static void Model_edit_material (LIScrArgs* args) { int i; int j; int n; float color[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; const char* str; const char* shader = NULL; const char* texture = NULL; LIEngModel* model; LIMdlMaterial* material; /* Get the engine model. */ model = args->self; liscr_args_gets_string (args, "match_shader", &shader); liscr_args_gets_string (args, "match_texture", &texture); /* Edit each matching material. */ for (i = 0 ; i < model->model->materials.count ; i++) { material = model->model->materials.array + i; if (!limdl_material_compare_shader_and_texture (material, shader, texture)) continue; if (liscr_args_gets_floatv (args, "diffuse", 4, color)) limdl_material_set_diffuse (material, color); if (liscr_args_gets_floatv (args, "specular", 4, color)) limdl_material_set_specular (material, color); if (liscr_args_gets_string (args, "shader", &str)) limdl_material_set_shader (material, str); if (liscr_args_gets_table (args, "textures")) { /* Count textures. */ for (n = 0 ; n < 4 ; n++) { lua_pushnumber (args->lua, n + 1); lua_gettable (args->lua, -2); j = lua_type (args->lua, -1); lua_pop (args->lua, 1); if (j != LUA_TSTRING) break; } /* Allocate textures. */ if (material->textures.count != n) { if (!limdl_material_realloc_textures (material, n)) { lua_pop (args->lua, 1); continue; } } /* Set textures. */ for (j = 0 ; j < n ; j++) { lua_pushnumber (args->lua, j + 1); lua_gettable (args->lua, -2); limdl_material_set_texture (material, j, LIMDL_TEXTURE_TYPE_IMAGE, LIMDL_TEXTURE_FLAG_BILINEAR | LIMDL_TEXTURE_FLAG_MIPMAP | LIMDL_TEXTURE_FLAG_REPEAT, lua_tostring (args->lua, -1)); lua_pop (args->lua, 1); } lua_pop (args->lua, 1); } } }
static void Model_add_triangles (LIScrArgs* args) { int i; int group = 1; int vertices_cap = 0; int vertices_num = 0; float* attrs[8]; LIMdlIndex* indices = NULL; LIMatVector zero = { 0.0f, 0.0f, 0.0f }; LIMdlBuilder* builder; LIMdlVertex* tmp; LIMdlVertex* vertex; LIMdlVertex* vertices = NULL; LIEngModel* model; /* Get the edited material group. */ model = args->self; liscr_args_gets_int (args, "material", &group); if (group < 1 || group > model->model->materials.count) return; /* Read vertex data. */ /* Vertices are stored to a sequential table. Each vertex is presented as a sequential child table whose fields are presented in the order of {x,y,z,nx,ny,nz,u,v}. */ if (liscr_args_gets_table (args, "vertices")) { for (vertices_num = 0 ; ; vertices_num++) { /* Get the vertex table. */ lua_pushnumber (args->lua, vertices_num + 1); lua_gettable (args->lua, -2); if (lua_type (args->lua, -1) != LUA_TTABLE) { lua_pop (args->lua, 1); break; } /* Allocate space for the vertex. */ if (vertices_cap < vertices_num + 1) { if (!vertices_cap) vertices_cap = 32; else vertices_cap <<= 1; tmp = realloc (vertices, vertices_cap * sizeof (LIMdlVertex)); if (tmp == NULL) { lisys_free (vertices); return; } vertices = tmp; } vertex = vertices + vertices_num; limdl_vertex_init (vertex, &zero, &zero, 0.0f, 0.0f); /* Read vertex attributes. */ attrs[0] = &vertex->coord.x; attrs[1] = &vertex->coord.y; attrs[2] = &vertex->coord.z; attrs[3] = &vertex->normal.x; attrs[4] = &vertex->normal.y; attrs[5] = &vertex->normal.z; attrs[6] = vertex->texcoord + 0; attrs[7] = vertex->texcoord + 1; for (i = 0 ; i < 8 ; i++) { lua_pushnumber (args->lua, i + 1); lua_gettable (args->lua, -2); if (lua_type (args->lua, -1) == LUA_TNUMBER) *(attrs[i]) = lua_tonumber (args->lua, -1); else *(attrs[i]) = 0.0f; lua_pop (args->lua, 1); } lua_pop (args->lua, 1); } lua_pop (args->lua, 1); } /* Validate the vertex count. */ if (!vertices_num) return; vertices_num -= vertices_num % 3; if (!vertices_num) { lisys_free (vertices); return; } /* Create the index buffer. */ indices = calloc (vertices_num, sizeof (LIMdlIndex)); if (indices == NULL) { lisys_free (vertices); return; } for (i = 0 ; i < vertices_num ; i++) indices[i] = model->model->vertices.count + i; /* Create a model builder. */ builder = limdl_builder_new (model->model); if (builder == NULL) { lisys_free (vertices); lisys_free (indices); return; } /* Insert the vertices and indices. */ limdl_builder_insert_vertices (builder, vertices, vertices_num, NULL); limdl_builder_insert_indices (builder, 0, group - 1, indices, vertices_num, 0); limdl_builder_finish (builder); /* Cleanup. */ limdl_builder_free (builder); lisys_free (vertices); lisys_free (indices); }
static void Database_query (LIScrArgs* args) { int i; int col; int row; int ret; int size; const char* query; const char* str; sqlite3* self; LIArcPacket* packet; LIScrData* data; sqlite3_stmt* statement; self = args->self; if (!liscr_args_geti_string (args, 0, &query) && !liscr_args_gets_string (args, "query", &query)) return; /* Create a statement. */ if (sqlite3_prepare_v2 (self, query, -1, &statement, NULL) != SQLITE_OK) { lisys_error_set (EINVAL, "SQL prepare: %s", sqlite3_errmsg (self)); lisys_error_report (); return; } /* Bind variables. */ if (liscr_args_geti_table (args, 1) || liscr_args_gets_table (args, "bind")) { for (i = 1 ; i < sqlite3_bind_parameter_count (statement) + 1 ; i++) { /* We got a table that has the bound variables in fields matching the indices of the bound variables. We can simply loop through the table and use the binding index as the key. */ lua_pushnumber (args->lua, i); lua_gettable (args->lua, -2); switch (lua_type (args->lua, -1)) { /* Bind numbers as doubles. */ case LUA_TNUMBER: if (sqlite3_bind_double (statement, i, lua_tonumber (args->lua, -1)) != SQLITE_OK) { lisys_error_set (EINVAL, "SQL bind: %s", sqlite3_errmsg (self)); lisys_error_report (); sqlite3_finalize (statement); return; } break; /* Bind strings as text. */ case LUA_TSTRING: if (sqlite3_bind_text (statement, i, lua_tostring (args->lua, -1), -1, SQLITE_TRANSIENT) != SQLITE_OK) { lisys_error_set (EINVAL, "SQL bind: %s", sqlite3_errmsg (self)); lisys_error_report (); sqlite3_finalize (statement); return; } break; /* Bind packets as blobs. */ case LUA_TUSERDATA: data = liscr_isdata (args->lua, -1, LISCR_SCRIPT_PACKET); if (data == NULL) break; packet = liscr_data_get_data (data); if (packet->writer != NULL) { if (sqlite3_bind_blob (statement, i, packet->writer->memory.buffer, packet->writer->memory.length, SQLITE_TRANSIENT) != SQLITE_OK) { lisys_error_set (EINVAL, "SQL bind: %s", sqlite3_errmsg (self)); lisys_error_report (); sqlite3_finalize (statement); return; } } else { if (sqlite3_bind_blob (statement, i, packet->reader->buffer, packet->reader->length, SQLITE_TRANSIENT) != SQLITE_OK) { lisys_error_set (EINVAL, "SQL bind: %s", sqlite3_errmsg (self)); lisys_error_report (); sqlite3_finalize (statement); return; } } break; /* Bind any other values as NULL. */ default: if (sqlite3_bind_null (statement, i) != SQLITE_OK) { lisys_error_set (EINVAL, "SQL bind: %s", sqlite3_errmsg (self)); lisys_error_report (); sqlite3_finalize (statement); return; } break; } lua_pop (args->lua, 1); } lua_pop (args->lua, 1); } /* Execute the statement and process results. */ for (row = 0, ret = sqlite3_step (statement) ; ret != SQLITE_DONE ; ret = sqlite3_step (statement), row++) { /* Check for errors. */ if (ret != SQLITE_ROW) { lisys_error_set (EINVAL, "SQL step: %s", sqlite3_errmsg (self)); lisys_error_report (); sqlite3_finalize (statement); return; } if (!row) liscr_args_set_output (args, LISCR_ARGS_OUTPUT_TABLE_FORCE); /* Create a row table. */ lua_newtable (args->lua); /* Push the columns to the table. */ for (col = 0 ; col < sqlite3_column_count (statement) ; col++) { switch (sqlite3_column_type (statement, col)) { case SQLITE_INTEGER: lua_pushnumber (args->lua, col + 1); lua_pushnumber (args->lua, sqlite3_column_int (statement, col)); lua_settable (args->lua, -3); break; case SQLITE_FLOAT: lua_pushnumber (args->lua, col + 1); lua_pushnumber (args->lua, sqlite3_column_double (statement, col)); lua_settable (args->lua, -3); break; case SQLITE_TEXT: str = (const char*) sqlite3_column_text (statement, col); size = sqlite3_column_bytes (statement, col); lua_pushnumber (args->lua, col + 1); if (size > 0 && str != NULL) lua_pushstring (args->lua, str); else lua_pushstring (args->lua, str); lua_settable (args->lua, -3); break; case SQLITE_BLOB: str = sqlite3_column_blob (statement, col); size = sqlite3_column_bytes (statement, col); packet = liarc_packet_new_readable (str, size); if (packet != NULL) { lua_pushnumber (args->lua, col + 1); data = liscr_data_new (args->script, args->lua, packet, LISCR_SCRIPT_PACKET, liarc_packet_free); if (data != NULL) lua_settable (args->lua, -3); else { lua_pop (args->lua, 1); liarc_packet_free (packet); } } break; case SQLITE_NULL: break; default: lisys_assert (0 && "invalid column type"); break; } } /* Add the row to the return values. */ liscr_args_seti_stack (args); } if (!row) liscr_args_set_output (args, LISCR_ARGS_OUTPUT_TABLE_FORCE); sqlite3_finalize (statement); }