コード例 #1
0
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);
		}
	}
}
コード例 #2
0
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);
}
コード例 #3
0
ファイル: ext-script.c プロジェクト: bsmr-games/lipsofsuna
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);
}