Beispiel #1
0
void Model::loaded(FS::IFile& file, bool success, FS::FileSystem& fs)
{
	PROFILE_FUNCTION();
	if (success)
	{
		FileHeader header;
		file.read(&header, sizeof(header));
		if (header.m_magic == FILE_MAGIC &&
			header.m_version <= (uint32_t)FileVersion::LATEST &&
			parseMeshes(file) && parseGeometry(file) && parseBones(file) &&
			parseLODs(file))
		{
			m_size = file.size();
			decrementDepCount();
		}
		else
		{
			g_log_warning.log("renderer") << "Error loading model "
										  << m_path.c_str();
			onFailure();
			return;
		}
	}
	else
	{
		g_log_warning.log("renderer") << "Error loading model "
									  << m_path.c_str();
		onFailure();
	}
}
JsonSerializer::JsonSerializer(FS::IFile& file,
	AccessMode access_mode,
	const Path& path,
	IAllocator& allocator)
	: m_file(file)
	, m_access_mode(access_mode)
	, m_allocator(allocator)
{
	m_is_error = false;
	copyString(m_path, path.c_str());
	m_is_first_in_block = true;
	m_data = nullptr;
	m_is_string_token = false;
	if (m_access_mode == READ)
	{
		m_data_size = (int)file.size();
		if (file.getBuffer() != nullptr)
		{
			m_data = (const char*)file.getBuffer();
			m_own_data = false;
		}
		else
		{
			int size = (int)m_file.size();
			char* data = (char*)m_allocator.allocate(size);
			m_own_data = true;
			file.read(data, m_data_size);
			m_data = data;
		}
		m_token = m_data;
		m_token_size = 0;
		deserializeToken();
	}
}
Beispiel #3
0
bool Texture::loadRaw(FS::IFile& file)
{
	PROFILE_FUNCTION();
	size_t size = file.size();
	m_BPP = 2;
	m_width = (int)sqrt(size / m_BPP);
	m_height = m_width;

	if (m_data_reference)
	{
		m_data.resize(size);
		file.read(&m_data[0], size);
	}

	const uint16_t* src_mem = (const uint16_t*)file.getBuffer();
	const bgfx::Memory* mem = bgfx::alloc(m_width * m_height * sizeof(float));
	float* dst_mem = (float*)mem->data;

	for (int i = 0; i < m_width * m_height; ++i)
	{
		dst_mem[i] = src_mem[i] / 65535.0f;
	}

	m_texture_handle = bgfx::createTexture2D(
		m_width, m_height, 1, bgfx::TextureFormat::R32F, 0, nullptr);
	bgfx::updateTexture2D(
		m_texture_handle,
		0,
		0,
		0,
		m_width,
		m_height,
		mem);
	return bgfx::isValid(m_texture_handle);
}
void Texture::save()
{
	char ext[5];
	ext[0] = 0;
	PathUtils::getExtension(ext, 5, getPath().c_str());
	if (strcmp(ext, "raw") == 0 && m_BPP == 2)
	{
		FS::FileSystem& fs = m_resource_manager.getFileSystem();
		FS::IFile* file = fs.open(fs.getDefaultDevice(),
								  getPath().c_str(),
								  FS::Mode::OPEN_OR_CREATE | FS::Mode::WRITE);

		file->write(&m_data[0], m_data.size() * sizeof(m_data[0]));
		fs.close(*file);
	}
	else if (strcmp(ext, "tga") == 0 && m_BPP == 4)
	{
		saveTGA();
	}
	else
	{
		g_log_error.log("renderer") << "Texture " << getPath()
									<< " can not be saved - unsupported format";
	}
}
Beispiel #5
0
bool Model::parseVertexDef(FS::IFile& file, bgfx::VertexDecl* vertex_definition)
{
	vertex_definition->begin();

	uint32 attribute_count;
	file.read(&attribute_count, sizeof(attribute_count));

	for (uint32 i = 0; i < attribute_count; ++i)
	{
		char tmp[50];
		uint32 len;
		file.read(&len, sizeof(len));
		if (len > sizeof(tmp) - 1)
		{
			return false;
		}
		file.read(tmp, len);
		tmp[len] = '\0';

		if (compareString(tmp, "in_position") == 0)
		{
			vertex_definition->add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float);
		}
		else if (compareString(tmp, "in_colors") == 0)
		{
			vertex_definition->add(bgfx::Attrib::Color0, 4, bgfx::AttribType::Uint8, true, false);
		}
		else if (compareString(tmp, "in_tex_coords") == 0)
		{
			vertex_definition->add(bgfx::Attrib::TexCoord0, 2, bgfx::AttribType::Float);
		}
		else if (compareString(tmp, "in_normal") == 0)
		{
			vertex_definition->add(bgfx::Attrib::Normal, 4, bgfx::AttribType::Uint8, true, true);
		}
		else if (compareString(tmp, "in_tangents") == 0)
		{
			vertex_definition->add(bgfx::Attrib::Tangent, 4, bgfx::AttribType::Uint8, true, true);
		}
		else if (compareString(tmp, "in_weights") == 0)
		{
			vertex_definition->add(bgfx::Attrib::Weight, 4, bgfx::AttribType::Float);
		}
		else if (compareString(tmp, "in_indices") == 0)
		{
			vertex_definition->add(bgfx::Attrib::Indices, 4, bgfx::AttribType::Int16, false, true);
		}
		else
		{
			ASSERT(false);
			return false;
		}

		uint32 type;
		file.read(&type, sizeof(type));
	}

	vertex_definition->end();
	return true;
}
Beispiel #6
0
bool Shader::load(FS::IFile& file)
{
	lua_State* L = luaL_newstate();
	luaL_openlibs(L);
	registerFunctions(this, &m_combintions, &getRenderer(), L);
	m_render_states = BGFX_STATE_DEPTH_TEST_LEQUAL;

	bool errors = luaL_loadbuffer(L, (const char*)file.getBuffer(), file.size(), "") != LUA_OK;
	errors = errors || lua_pcall(L, 0, 0, 0) != LUA_OK;
	if (errors)
	{
		g_log_error.log("Renderer") << getPath().c_str() << ": " << lua_tostring(L, -1);
		lua_pop(L, 1);
		return false;
	}
	
	if (!generateInstances())
	{
		g_log_error.log("Renderer") << "Could not load instances of shader " << getPath().c_str();
		return false;
	}

	m_size = file.size();
	lua_close(L);
	return true;
}
bool LuaScript::load(FS::IFile& file)
{
	m_properties.clear();
	m_source_code.set((const char*)file.getBuffer(), (int)file.size());
	parseProperties();
	m_size = file.size();
	return true;
}
Beispiel #8
0
bool ShaderBinary::load(FS::IFile& file)
{
	auto* mem = bgfx::alloc((uint32)file.size() + 1);
	file.read(mem->data, file.size());
	mem->data[file.size()] = '\0';
	m_handle = bgfx::createShader(mem);
	m_size = file.size();
	return bgfx::isValid(m_handle);
}
Beispiel #9
0
bool Texture::loadDDS(FS::IFile& file)
{
	bgfx::TextureInfo info;
	m_texture_handle = bgfx::createTexture(
		bgfx::copy(file.getBuffer(), file.size()), 0, 0, &info);
	m_BPP = -1;
	m_width = info.width;
	m_height = info.height;
	return bgfx::isValid(m_texture_handle);
}
bool Clip::load(FS::IFile& file)
{
	short* output = nullptr;
	auto res = stb_vorbis_decode_memory(
		(unsigned char*)file.getBuffer(), (int)file.size(), &m_channels, &m_sample_rate, &output);
	if (res <= 0) return false;

	m_data.resize(res * m_channels);
	copyMemory(&m_data[0], output, res * m_channels * sizeof(m_data[0]));
	free(output);

	return true;
}
Beispiel #11
0
bool Model::parseVertexDeclEx(FS::IFile& file, bgfx::VertexDecl* vertex_decl)
{
	vertex_decl->begin();

	u32 attribute_count;
	file.read(&attribute_count, sizeof(attribute_count));

	for (u32 i = 0; i < attribute_count; ++i)
	{
		i32 attr;
		file.read(&attr, sizeof(attr));

		if (attr == (i32)Attrs::Position)
		{
			vertex_decl->add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float);
		}
		else if (attr == (i32)Attrs::Color0)
		{
			vertex_decl->add(bgfx::Attrib::Color0, 4, bgfx::AttribType::Uint8, true, false);
		}
		else if (attr == (i32)Attrs::TexCoord0)
		{
			vertex_decl->add(bgfx::Attrib::TexCoord0, 2, bgfx::AttribType::Float);
		}
		else if (attr == (i32)Attrs::Normal)
		{
			vertex_decl->add(bgfx::Attrib::Normal, 4, bgfx::AttribType::Uint8, true, true);
		}
		else if (attr == (i32)Attrs::Tangent)
		{
			vertex_decl->add(bgfx::Attrib::Tangent, 4, bgfx::AttribType::Uint8, true, true);
		}
		else if (attr == (i32)Attrs::Weight)
		{
			vertex_decl->add(bgfx::Attrib::Weight, 4, bgfx::AttribType::Float);
		}
		else if (attr == (i32)Attrs::Indices)
		{
			vertex_decl->add(bgfx::Attrib::Indices, 4, bgfx::AttribType::Int16, false, true);
		}
		else
		{
			ASSERT(false);
			return false;
		}
	}

	vertex_decl->end();
	return true;
}
Beispiel #12
0
bool Texture::load(FS::IFile& file)
{
	PROFILE_FUNCTION();

	const char* path = getPath().c_str();
	size_t len = getPath().length();
	bool loaded = false;
	if (len > 3 && compareString(path + len - 4, ".dds") == 0)
	{
		loaded = loadDDS(file);
	}
	else if (len > 3 && compareString(path + len - 4, ".raw") == 0)
	{
		loaded = loadRaw(file);
	}
	else
	{
		loaded = loadTGA(file);
	}
	if (!loaded)
	{
		g_log_warning.log("Renderer") << "Error loading texture " << path;
		return false;
	}

	m_size = file.size();
	return true;
}
Beispiel #13
0
bool Model::parseLODs(FS::IFile& file)
{
	i32 lod_count;
	file.read(&lod_count, sizeof(lod_count));
	if (lod_count <= 0 || lod_count > lengthOf(m_lods))
	{
		return false;
	}
	for (int i = 0; i < lod_count; ++i)
	{
		file.read(&m_lods[i].to_mesh, sizeof(m_lods[i].to_mesh));
		file.read(&m_lods[i].distance, sizeof(m_lods[i].distance));
		m_lods[i].from_mesh = i > 0 ? m_lods[i - 1].to_mesh + 1 : 0;
	}
	return true;
}
void LuaScript::loaded(FS::IFile& file, bool success, FS::FileSystem& fs)
{
	if (success)
	{
		m_source_code.set((const char*)file.getBuffer(), file.size());
		parseProperties();
		m_size = file.size();
		decrementDepCount();
	}
	else
	{
		g_log_error.log("lua_script") << "Could not load script "
									  << m_path.c_str();
		onFailure();
	}
}
Beispiel #15
0
bool Model::parseLODs(FS::IFile& file)
{
	int32 lod_count;
	file.read(&lod_count, sizeof(lod_count));
	if (lod_count <= 0)
	{
		return false;
	}
	m_lods.resize(lod_count);
	for (int i = 0; i < lod_count; ++i)
	{
		file.read(&m_lods[i].m_to_mesh, sizeof(m_lods[i].m_to_mesh));
		file.read(&m_lods[i].m_distance, sizeof(m_lods[i].m_distance));
		m_lods[i].m_from_mesh = i > 0 ? m_lods[i - 1].m_to_mesh + 1 : 0;
	}
	return true;
}
Beispiel #16
0
bool Model::load(FS::IFile& file)
{
	PROFILE_FUNCTION();
	FileHeader header;
	file.read(&header, sizeof(header));
	if (header.m_magic == FILE_MAGIC 
		&& header.m_version <= (uint32)FileVersion::LATEST 
		&& parseMeshes(file) 
		&& parseGeometry(file) 
		&& parseBones(file) 
		&& parseLODs(file))
	{
		m_size = file.size();
		return true;
	}

	g_log_warning.log("renderer") << "Error loading model " << getPath().c_str();
	return false;
}
Beispiel #17
0
bool Model::load(FS::IFile& file)
{
	PROFILE_FUNCTION();
	FileHeader header;
	file.read(&header, sizeof(header));

	if (header.magic != FILE_MAGIC)
	{
		g_log_warning.log("Renderer") << "Corrupted model " << getPath().c_str();
		return false;
	}

	if(header.version > (u32)FileVersion::LATEST)
	{
		g_log_warning.log("Renderer") << "Unsupported version of model " << getPath().c_str();
		return false;
	}

	u32 global_flags = 0; // backward compatibility
	if(header.version > (u32)FileVersion::WITH_FLAGS)
	{
		file.read(&global_flags, sizeof(global_flags));
	}

	bgfx::VertexDecl global_vertex_decl;
	if (header.version > (u32)FileVersion::SINGLE_VERTEX_DECL && header.version <= (u32)FileVersion::MULTIPLE_VERTEX_DECLS)
	{
		parseVertexDeclEx(file, &global_vertex_decl);
	}

	if (parseMeshes(global_vertex_decl, file, (FileVersion)header.version, global_flags)
		&& parseBones(file)
		&& parseLODs(file))
	{
		m_size = file.size();
		return true;
	}

	g_log_error.log("Renderer") << "Error loading model " << getPath().c_str();
	return false;
}
Beispiel #18
0
bool Model::parseGeometry(FS::IFile& file)
{
	int32_t indices_count = 0;
	file.read(&indices_count, sizeof(indices_count));
	if (indices_count <= 0)
	{
		return false;
	}
	m_indices.resize(indices_count);
	file.read(&m_indices[0], sizeof(m_indices[0]) * indices_count);

	int32_t vertices_size = 0;
	file.read(&vertices_size, sizeof(vertices_size));
	if (vertices_size <= 0)
	{
		return false;
	}

	Array<uint8_t> vertices(m_allocator);
	vertices.resize(vertices_size);
	file.read(&vertices[0], sizeof(vertices[0]) * vertices.size());

	m_geometry_buffer_object.setAttributesData(
		&vertices[0], vertices.size(), m_meshes[0].getVertexDefinition());
	m_geometry_buffer_object.setIndicesData(
		&m_indices[0], m_indices.size() * sizeof(m_indices[0]));

	int vertex_count = 0;
	for (int i = 0; i < m_meshes.size(); ++i)
	{
		vertex_count += m_meshes[i].getAttributeArraySize() /
						m_meshes[i].getVertexDefinition().getStride();
	}
	m_vertices.resize(vertex_count);

	computeRuntimeData(&vertices[0]);

	return true;
}
Beispiel #19
0
bool Model::parseGeometry(FS::IFile& file)
{
	int32 indices_count = 0;
	file.read(&indices_count, sizeof(indices_count));
	if (indices_count <= 0) return false;

	m_indices.resize(indices_count);
	file.read(&m_indices[0], sizeof(m_indices[0]) * indices_count);

	int32 vertices_size = 0;
	file.read(&vertices_size, sizeof(vertices_size));
	if (vertices_size <= 0) return false;

	ASSERT(!bgfx::isValid(m_vertices_handle));
	const bgfx::Memory* vertices_mem = bgfx::alloc(vertices_size);
	file.read(vertices_mem->data, vertices_size);
	m_vertices_handle = bgfx::createVertexBuffer(vertices_mem, m_meshes[0].getVertexDefinition());
	m_vertices_size = vertices_size;

	ASSERT(!bgfx::isValid(m_indices_handle));
	m_indices_size = sizeof(m_indices[0]) * indices_count;
	const bgfx::Memory* mem = bgfx::copy(&m_indices[0], m_indices_size);
	m_indices_handle = bgfx::createIndexBuffer(mem, BGFX_BUFFER_INDEX32);

	int vertex_count = 0;
	for (int i = 0; i < m_meshes.size(); ++i)
	{
		vertex_count += m_meshes[i].getAttributeArraySize() /
						m_meshes[i].getVertexDefinition().getStride();
	}
	m_vertices.resize(vertex_count);

	computeRuntimeData(vertices_mem->data);

	return true;
}
void Texture::loaded(FS::IFile& file, bool success, FS::FileSystem& fs)
{
	PROFILE_FUNCTION();
	if (success)
	{
		const char* path = m_path.c_str();
		size_t len = m_path.length();
		bool loaded = false;
		if (len > 3 && strcmp(path + len - 4, ".dds") == 0)
		{
			loaded = loadDDS(file);
		}
		else if (len > 3 && strcmp(path + len - 4, ".raw") == 0)
		{
			loaded = loadRaw(file);
		}
		else
		{
			loaded = loadTGA(file);
		}
		if (!loaded)
		{
			g_log_warning.log("renderer") << "Error loading texture "
										  << m_path.c_str();
			onFailure();
		}
		else
		{
			m_size = file.size();
			decrementDepCount();
		}
	}
	else
	{
		g_log_warning.log("renderer") << "Error loading texture "
									  << m_path.c_str();
		onFailure();
	}
}
Beispiel #21
0
void Animation::loaded(FS::IFile& file, bool success, FS::FileSystem& fs)
{
	if (success)
	{
		IAllocator& allocator = getAllocator();
		allocator.deallocate(m_positions);
		allocator.deallocate(m_rotations);
		allocator.deallocate(m_bones);
		m_positions = nullptr;
		m_rotations = nullptr;
		m_bones = 0;
		m_frame_count = m_bone_count = 0;
		Header header;
		file.read(&header, sizeof(header));
		if (header.magic != HEADER_MAGIC)
		{
			onFailure();
			g_log_error.log("animation") << m_path.c_str() << " is not an animation file";
			return;
		}
		if (header.version > 1)
		{
			onFailure();
			g_log_error.log("animation") << "Unsupported animation version " << header.version << " (" << m_path.c_str() << ")";
			return;
		}
		m_fps = header.fps;
		file.read(&m_frame_count, sizeof(m_frame_count));
		file.read(&m_bone_count, sizeof(m_bone_count));

		m_positions = static_cast<Vec3*>(allocator.allocate(sizeof(Vec3) * m_frame_count * m_bone_count));
		m_rotations = static_cast<Quat*>(allocator.allocate(sizeof(Quat) * m_frame_count * m_bone_count));
		m_bones = static_cast<uint32_t*>(allocator.allocate(sizeof(uint32_t) * m_bone_count));
		file.read(&m_positions[0], sizeof(Vec3)* m_bone_count * m_frame_count);
		file.read(&m_rotations[0], sizeof(Quat)* m_bone_count * m_frame_count);
		file.read(m_bones, sizeof(m_bones[0]) * m_bone_count);
		
		m_size = file.size();
		decrementDepCount();
	}
	else
	{
		onFailure();
	}
}
Beispiel #22
0
bool Animation::load(FS::IFile& file)
{
	IAllocator& allocator = getAllocator();
	allocator.deallocate(m_positions);
	allocator.deallocate(m_rotations);
	allocator.deallocate(m_bones);
	m_positions = nullptr;
	m_rotations = nullptr;
	m_bones = nullptr;
	m_frame_count = m_bone_count = 0;
	Header header;
	file.read(&header, sizeof(header));
	if (header.magic != HEADER_MAGIC)
	{
		g_log_error.log("Animation") << getPath() << " is not an animation file";
		return false;
	}
	if (header.version > 1)
	{
		g_log_error.log("Animation") << "Unsupported animation version " << header.version << " ("
									 << getPath() << ")";
		return false;
	}
	m_fps = header.fps;
	file.read(&m_frame_count, sizeof(m_frame_count));
	file.read(&m_bone_count, sizeof(m_bone_count));

	m_positions = static_cast<Vec3*>(allocator.allocate(sizeof(Vec3) * m_frame_count * m_bone_count));
	m_rotations = static_cast<Quat*>(allocator.allocate(sizeof(Quat) * m_frame_count * m_bone_count));
	m_bones = static_cast<uint32*>(allocator.allocate(sizeof(uint32) * m_bone_count));
	file.read(&m_positions[0], sizeof(Vec3)* m_bone_count * m_frame_count);
	file.read(&m_rotations[0], sizeof(Quat)* m_bone_count * m_frame_count);
	file.read(m_bones, sizeof(m_bones[0]) * m_bone_count);
		
	m_size = file.size();
	return true;
}
Beispiel #23
0
bool Material::load(FS::IFile& file)
{
	PROFILE_FUNCTION();

	m_render_states = BGFX_STATE_DEPTH_TEST_LEQUAL | BGFX_STATE_CULL_CW;
	m_uniforms.clear();
	JsonSerializer serializer(file, JsonSerializer::READ, getPath().c_str(), m_allocator);
	serializer.deserializeObjectBegin();
	char path[MAX_PATH_LENGTH];
	char label[256];
	char material_dir[MAX_PATH_LENGTH];
	PathUtils::getDir(material_dir, MAX_PATH_LENGTH, getPath().c_str());
	bool b_value;
	while (!serializer.isObjectEnd())
	{
		serializer.deserializeLabel(label, 255);
		if (compareString(label, "uniforms") == 0)
		{
			deserializeUniforms(serializer);
		}
		else if (compareString(label, "texture") == 0)
		{
			if (!deserializeTexture(serializer, material_dir))
			{
				return false;
			}
		}
		else if (compareString(label, "alpha_cutout") == 0)
		{
			bool b;
			serializer.deserialize(b, false);
			enableAlphaCutout(b);
		}
		else if (compareString(label, "alpha_blending") == 0)
		{
			if (serializer.isNextBoolean())
			{
				bool is_alpha_blending;
				serializer.deserialize(is_alpha_blending, false);
				if (is_alpha_blending)
				{
					m_render_states |= BGFX_STATE_BLEND_ADD;
				}
				else
				{
					m_render_states &= ~BGFX_STATE_BLEND_MASK;
				}
			}
			else
			{
				serializer.deserialize(label, 255, "alpha");
				if (compareString(label, "alpha") == 0)
				{
					m_render_states |= BGFX_STATE_BLEND_ALPHA;
				}
				else if (compareString(label, "add") == 0)
				{
					m_render_states |= BGFX_STATE_BLEND_ADD;
				}
				else if (compareString(label, "disabled") == 0)
				{
					m_render_states &= ~BGFX_STATE_BLEND_MASK;
				}
			}
		}
		else if (compareString(label, "specular") == 0)
		{
			serializer.deserializeArrayBegin();
			serializer.deserializeArrayItem(m_specular.x, 1.0f);
			serializer.deserializeArrayItem(m_specular.y, 1.0f);
			serializer.deserializeArrayItem(m_specular.z, 1.0f);
			serializer.deserializeArrayEnd();
		}
		else if (compareString(label, "shininess") == 0)
		{
			serializer.deserialize(m_shininess, 4.0f);
		}
		else if (compareString(label, "shadow_receiver") == 0)
		{
			bool b;
			serializer.deserialize(b, true);
			enableShadowReceiving(b);
		}
		else if (compareString(label, "shader") == 0)
		{
			serializer.deserialize(path, MAX_PATH_LENGTH, "");
			setShader(static_cast<Shader*>(
				m_resource_manager.get(ResourceManager::SHADER)->load(Path(path))));
		}
		else if (compareString(label, "z_test") == 0)
		{
			serializer.deserialize(b_value, true);
			enableZTest(b_value);
		}
		else if (compareString(label, "backface_culling") == 0)
		{
			serializer.deserialize(b_value, true);
			enableBackfaceCulling(b_value);
		}
		else
		{
			g_log_warning.log("renderer") << "Unknown parameter " << label << " in material "
										  << getPath().c_str();
		}
	}
	serializer.deserializeObjectEnd();

	if (!m_shader)
	{
		g_log_error.log("renderer") << "Material " << getPath().c_str() << " without a shader";
		return false;
	}

	m_size = file.size();
	return true;
}
	bool PhysicsGeometry::load(FS::IFile& file)
	{
		Header header;
		file.read(&header, sizeof(header));
		if (header.m_magic != HEADER_MAGIC || header.m_version > (uint32)Versions::LAST)
		{
			return false;
		}

		auto* phy_manager = m_resource_manager.get(ResourceManager::PHYSICS);
		PhysicsSystem& system = static_cast<PhysicsGeometryManager*>(phy_manager)->getSystem();

		uint32 num_verts;
		Array<Vec3> verts(getAllocator());
		file.read(&num_verts, sizeof(num_verts));
		verts.resize(num_verts);
		file.read(&verts[0], sizeof(verts[0]) * verts.size());

		m_is_convex = header.m_convex != 0;
		if (!m_is_convex)
		{
			physx::PxTriangleMeshGeometry* geom =
				LUMIX_NEW(getAllocator(), physx::PxTriangleMeshGeometry)();
			m_geometry = geom;
			uint32 num_indices;
			Array<uint32> tris(getAllocator());
			file.read(&num_indices, sizeof(num_indices));
			tris.resize(num_indices);
			file.read(&tris[0], sizeof(tris[0]) * tris.size());

			physx::PxTriangleMeshDesc meshDesc;
			meshDesc.points.count = num_verts;
			meshDesc.points.stride = sizeof(physx::PxVec3);
			meshDesc.points.data = &verts[0];

			meshDesc.triangles.count = num_indices / 3;
			meshDesc.triangles.stride = 3 * sizeof(physx::PxU32);
			meshDesc.triangles.data = &tris[0];

			OutputStream writeBuffer(getAllocator());
			system.getCooking()->cookTriangleMesh(meshDesc, writeBuffer);

			InputStream readBuffer(writeBuffer.data, writeBuffer.size);
			geom->triangleMesh = system.getPhysics()->createTriangleMesh(readBuffer);
		}
		else
		{
			physx::PxConvexMeshGeometry* geom =
				LUMIX_NEW(getAllocator(), physx::PxConvexMeshGeometry)();
			m_geometry = geom;
			physx::PxConvexMeshDesc meshDesc;
			meshDesc.points.count = verts.size();
			meshDesc.points.stride = sizeof(Vec3);
			meshDesc.points.data = &verts[0];
			meshDesc.flags = physx::PxConvexFlag::eCOMPUTE_CONVEX;

			OutputStream writeBuffer(getAllocator());
			bool status = system.getCooking()->cookConvexMesh(meshDesc, writeBuffer);
			if (!status)
			{
				LUMIX_DELETE(getAllocator(), geom);
				m_geometry = nullptr;
				return false;
			}

			InputStream readBuffer(writeBuffer.data, writeBuffer.size);
			physx::PxConvexMesh* mesh = system.getPhysics()->createConvexMesh(readBuffer);
			geom->convexMesh = mesh;
		}

		m_size = file.size();
		return true;
	}
Beispiel #25
0
bool Model::parseBones(FS::IFile& file)
{
	int bone_count;
	file.read(&bone_count, sizeof(bone_count));
	if (bone_count < 0) return false;
	if (bone_count > Bone::MAX_COUNT)
	{
		g_log_warning.log("Renderer") << "Model " << getPath().c_str() << " has too many bones.";
		return false;
	}

	m_bones.reserve(bone_count);
	for (int i = 0; i < bone_count; ++i)
	{
		Model::Bone& b = m_bones.emplace(m_allocator);
		int len;
		file.read(&len, sizeof(len));
		char tmp[MAX_PATH_LENGTH];
		if (len >= MAX_PATH_LENGTH)
		{
			return false;
		}
		file.read(tmp, len);
		tmp[len] = 0;
		b.name = tmp;
		m_bone_map.insert(crc32(b.name.c_str()), m_bones.size() - 1);
		file.read(&len, sizeof(len));
		if (len >= MAX_PATH_LENGTH)
		{
			return false;
		}
		if(len > 0)
		{
			file.read(tmp, len);
			tmp[len] = 0;
			b.parent = tmp;
		}
		else
		{
			b.parent = "";
		}
		file.read(&b.transform.pos.x, sizeof(float) * 3);
		file.read(&b.transform.rot.x, sizeof(float) * 4);
	}
	m_first_nonroot_bone_index = -1;
	for (int i = 0; i < bone_count; ++i)
	{
		Model::Bone& b = m_bones[i];
		if (b.parent.length() == 0)
		{
			if (m_first_nonroot_bone_index != -1)
			{
				g_log_error.log("Renderer") << "Invalid skeleton in " << getPath().c_str();
				return false;
			}
			b.parent_idx = -1;
		}
		else
		{
			b.parent_idx = getBoneIdx(b.parent.c_str());
			if (b.parent_idx > i || b.parent_idx < 0)
			{
				g_log_error.log("Renderer") << "Invalid skeleton in " << getPath().c_str();
				return false;
			}
			if (m_first_nonroot_bone_index == -1)
			{
				m_first_nonroot_bone_index = i;
			}
		}
	}

	for (int i = 0; i < m_bones.size(); ++i)
	{
		m_bones[i].inv_bind_transform = m_bones[i].transform.inverted();
	}

	for (int i = 0; i < m_bones.size(); ++i)
	{
		int p = m_bones[i].parent_idx;
		if (p >= 0)
		{
			m_bones[i].relative_transform = m_bones[p].inv_bind_transform * m_bones[i].transform;
		}
		else
		{
			m_bones[i].relative_transform = m_bones[i].transform;
		}
	}
	return true;
}
Beispiel #26
0
bool Model::parseMeshes(const bgfx::VertexDecl& global_vertex_decl, FS::IFile& file, FileVersion version, u32 global_flags)
{
	if (version <= FileVersion::MULTIPLE_VERTEX_DECLS) return parseMeshesOld(global_vertex_decl, file, version, global_flags);
	
	int object_count = 0;
	file.read(&object_count, sizeof(object_count));
	if (object_count <= 0) return false;

	char model_dir[MAX_PATH_LENGTH];
	PathUtils::getDir(model_dir, MAX_PATH_LENGTH, getPath().c_str());

	m_meshes.reserve(object_count);
	for (int i = 0; i < object_count; ++i)
	{
		bgfx::VertexDecl vertex_decl;
		if (!parseVertexDeclEx(file, &vertex_decl)) return false;

		i32 str_size;
		file.read(&str_size, sizeof(str_size));
		char material_name[MAX_PATH_LENGTH];
		file.read(material_name, str_size);
		if (str_size >= MAX_PATH_LENGTH) return false;

		material_name[str_size] = 0;

		char material_path[MAX_PATH_LENGTH];
		copyString(material_path, model_dir);
		catString(material_path, material_name);
		catString(material_path, ".mat");

		auto* material_manager = m_resource_manager.getOwner().get(Material::TYPE);
		Material* material = static_cast<Material*>(material_manager->load(Path(material_path)));
		
		file.read(&str_size, sizeof(str_size));
		char mesh_name[MAX_PATH_LENGTH];
		mesh_name[str_size] = 0;
		file.read(mesh_name, str_size);

		m_meshes.emplace(material, vertex_decl, mesh_name, m_allocator);
		addDependency(*material);
	}

	for (int i = 0; i < object_count; ++i)
	{
		Mesh& mesh = m_meshes[i];
		int index_size;
		int indices_count;
		file.read(&index_size, sizeof(index_size));
		if (index_size != 2 && index_size != 4) return false;
		file.read(&indices_count, sizeof(indices_count));
		if (indices_count <= 0) return false;
		mesh.indices.resize(index_size * indices_count);
		file.read(&mesh.indices[0], mesh.indices.size());

		if (index_size == 2) mesh.flags.set(Mesh::Flags::INDICES_16_BIT);
		mesh.indices_count = indices_count;
		const bgfx::Memory* indices_mem = bgfx::copy(&mesh.indices[0], mesh.indices.size());
		mesh.index_buffer_handle = bgfx::createIndexBuffer(indices_mem);
	}

	for (int i = 0; i < object_count; ++i)
	{
		Mesh& mesh = m_meshes[i];
		int data_size;
		file.read(&data_size, sizeof(data_size));
		const bgfx::Memory* vertices_mem = bgfx::alloc(data_size);
		file.read(vertices_mem->data, vertices_mem->size);

		const bgfx::VertexDecl& vertex_decl = mesh.vertex_decl;
		int position_attribute_offset = vertex_decl.getOffset(bgfx::Attrib::Position);
		int uv_attribute_offset = vertex_decl.getOffset(bgfx::Attrib::TexCoord0);
		int weights_attribute_offset = vertex_decl.getOffset(bgfx::Attrib::Weight);
		int bone_indices_attribute_offset = vertex_decl.getOffset(bgfx::Attrib::Indices);
		bool keep_skin = vertex_decl.has(bgfx::Attrib::Weight) && vertex_decl.has(bgfx::Attrib::Indices);

		int vertex_size = mesh.vertex_decl.getStride();
		int mesh_vertex_count = vertices_mem->size / mesh.vertex_decl.getStride();
		mesh.vertices.resize(mesh_vertex_count);
		mesh.uvs.resize(mesh_vertex_count);
		if (keep_skin) mesh.skin.resize(mesh_vertex_count);
		const u8* vertices = vertices_mem->data;
		for (int j = 0; j < mesh_vertex_count; ++j)
		{
			int offset = j * vertex_size;
			if (keep_skin)
			{
				mesh.skin[j].weights = *(const Vec4*)&vertices[offset + weights_attribute_offset];
				copyMemory(mesh.skin[j].indices,
					&vertices[offset + bone_indices_attribute_offset],
					sizeof(mesh.skin[j].indices));
			}
			mesh.vertices[j] = *(const Vec3*)&vertices[offset + position_attribute_offset];
			mesh.uvs[j] = *(const Vec2*)&vertices[offset + uv_attribute_offset];
		}
		mesh.vertex_buffer_handle = bgfx::createVertexBuffer(vertices_mem, mesh.vertex_decl);
	}
	file.read(&m_bounding_radius, sizeof(m_bounding_radius));
	file.read(&m_aabb, sizeof(m_aabb));

	return true;
}
Beispiel #27
0
bool Model::parseMeshes(FS::IFile& file)
{
	int object_count = 0;
	file.read(&object_count, sizeof(object_count));
	if (object_count <= 0) return false;

	m_meshes.reserve(object_count);
	char model_dir[MAX_PATH_LENGTH];
	PathUtils::getDir(model_dir, MAX_PATH_LENGTH, getPath().c_str());
	for (int i = 0; i < object_count; ++i)
	{
		int32 str_size;
		file.read(&str_size, sizeof(str_size));
		char material_name[MAX_PATH_LENGTH];
		file.read(material_name, str_size);
		if (str_size >= MAX_PATH_LENGTH) return false;

		material_name[str_size] = 0;

		char material_path[MAX_PATH_LENGTH];
		copyString(material_path, model_dir);
		catString(material_path, material_name);
		catString(material_path, ".mat");

		auto* material_manager = m_resource_manager.get(ResourceManager::MATERIAL);
		Material* material = static_cast<Material*>(material_manager->load(Path(material_path)));

		int32 attribute_array_offset = 0;
		file.read(&attribute_array_offset, sizeof(attribute_array_offset));
		int32 attribute_array_size = 0;
		file.read(&attribute_array_size, sizeof(attribute_array_size));
		int32 indices_offset = 0;
		file.read(&indices_offset, sizeof(indices_offset));
		int32 mesh_tri_count = 0;
		file.read(&mesh_tri_count, sizeof(mesh_tri_count));

		file.read(&str_size, sizeof(str_size));
		if (str_size >= MAX_PATH_LENGTH)
		{
			material_manager->unload(*material);
			return false;
		}
		
		char mesh_name[MAX_PATH_LENGTH];
		mesh_name[str_size] = 0;
		file.read(mesh_name, str_size);

		bgfx::VertexDecl def;
		parseVertexDef(file, &def);
		m_meshes.emplace(def,
						 material,
						 attribute_array_offset,
						 attribute_array_size,
						 indices_offset,
						 mesh_tri_count * 3,
						 mesh_name,
						 m_allocator);
		addDependency(*material);
	}
	return true;
}
Beispiel #28
0
bool Model::parseBones(FS::IFile& file)
{
	int bone_count;
	file.read(&bone_count, sizeof(bone_count));
	if (bone_count < 0)
	{
		return false;
	}
	m_bones.reserve(bone_count);
	for (int i = 0; i < bone_count; ++i)
	{
		Model::Bone& b = m_bones.emplace(m_allocator);
		int len;
		file.read(&len, sizeof(len));
		char tmp[MAX_PATH_LENGTH];
		if (len >= MAX_PATH_LENGTH)
		{
			return false;
		}
		file.read(tmp, len + 1);
		tmp[len] = 0;
		b.name = tmp;
		m_bone_map.insert(crc32(b.name.c_str()), m_bones.size() - 1);
		file.read(&len, sizeof(len));
		if (len >= MAX_PATH_LENGTH)
		{
			return false;
		}
		if(len > 0)
		{
			file.read(tmp, len);
			tmp[len] = 0;
			b.parent = tmp;
		}
		else
		{
			b.parent = "";
		}
		file.read(&b.position.x, sizeof(float) * 3);
		file.read(&b.rotation.x, sizeof(float) * 4);
	}
	m_first_nonroot_bone_index = -1;
	for (int i = 0; i < bone_count; ++i)
	{
		Model::Bone& b = m_bones[i];
		if (b.parent.length() == 0)
		{
			b.parent_idx = -1;
		}
		else
		{
			b.parent_idx = getBoneIdx(b.parent.c_str());
			if (b.parent_idx > i || b.parent_idx < 0)
			{
				g_log_error.log("renderer") << "Invalid skeleton in "
											<< getPath().c_str();
				return false;
			}
			if (m_first_nonroot_bone_index == -1)
			{
				m_first_nonroot_bone_index = i;
			}
		}
	}
	for (int i = 0; i < m_bones.size(); ++i)
	{
		m_bones[i].rotation.toMatrix(m_bones[i].inv_bind_matrix);
		m_bones[i].inv_bind_matrix.translate(m_bones[i].position);
	}
	for (int i = 0; i < m_bones.size(); ++i)
	{
		m_bones[i].inv_bind_matrix.fastInverse();
	}
	return true;
}
Beispiel #29
0
bool Model::parseMeshesOld(bgfx::VertexDecl global_vertex_decl, FS::IFile& file, FileVersion version, u32 global_flags)
{
	int object_count = 0;
	file.read(&object_count, sizeof(object_count));
	if (object_count <= 0) return false;

	m_meshes.reserve(object_count);
	char model_dir[MAX_PATH_LENGTH];
	PathUtils::getDir(model_dir, MAX_PATH_LENGTH, getPath().c_str());
	struct Offsets
	{
		i32 attribute_array_offset;
		i32 attribute_array_size;
		i32 indices_offset;
		i32 mesh_tri_count;
	};
	Array<Offsets> mesh_offsets(m_allocator);
	for (int i = 0; i < object_count; ++i)
	{
		i32 str_size;
		file.read(&str_size, sizeof(str_size));
		char material_name[MAX_PATH_LENGTH];
		file.read(material_name, str_size);
		if (str_size >= MAX_PATH_LENGTH) return false;

		material_name[str_size] = 0;

		char material_path[MAX_PATH_LENGTH];
		copyString(material_path, model_dir);
		catString(material_path, material_name);
		catString(material_path, ".mat");

		auto* material_manager = m_resource_manager.getOwner().get(Material::TYPE);
		Material* material = static_cast<Material*>(material_manager->load(Path(material_path)));

		Offsets& offsets = mesh_offsets.emplace();
		file.read(&offsets.attribute_array_offset, sizeof(offsets.attribute_array_offset));
		file.read(&offsets.attribute_array_size, sizeof(offsets.attribute_array_size));
		file.read(&offsets.indices_offset, sizeof(offsets.indices_offset));
		file.read(&offsets.mesh_tri_count, sizeof(offsets.mesh_tri_count));

		file.read(&str_size, sizeof(str_size));
		if (str_size >= MAX_PATH_LENGTH)
		{
			material_manager->unload(*material);
			return false;
		}

		char mesh_name[MAX_PATH_LENGTH];
		mesh_name[str_size] = 0;
		file.read(mesh_name, str_size);

		bgfx::VertexDecl vertex_decl = global_vertex_decl;
		if (version <= FileVersion::SINGLE_VERTEX_DECL)
		{
			parseVertexDecl(file, &vertex_decl);
			if (i != 0 && global_vertex_decl.m_hash != vertex_decl.m_hash)
			{
				g_log_error.log("Renderer") << "Model " << getPath().c_str()
					<< " contains meshes with different vertex declarations.";
			}
			if(i == 0) global_vertex_decl = vertex_decl;
		}


		m_meshes.emplace(material,
			vertex_decl,
			mesh_name,
			m_allocator);
		addDependency(*material);
	}

	i32 indices_count = 0;
	file.read(&indices_count, sizeof(indices_count));
	if (indices_count <= 0) return false;

	u32 INDICES_16BIT_FLAG = 1;
	int index_size = global_flags & INDICES_16BIT_FLAG ? 2 : 4;
	Array<u8> indices(m_allocator);
	indices.resize(indices_count * index_size);
	file.read(&indices[0], indices.size());

	i32 vertices_size = 0;
	file.read(&vertices_size, sizeof(vertices_size));
	if (vertices_size <= 0) return false;

	Array<u8> vertices(m_allocator);
	vertices.resize(vertices_size);
	file.read(&vertices[0], vertices.size());

	int vertex_count = 0;
	for (const Offsets& offsets : mesh_offsets)
	{
		vertex_count += offsets.attribute_array_size / global_vertex_decl.getStride();
	}

	if (version > FileVersion::BOUNDING_SHAPES_PRECOMPUTED)
	{
		file.read(&m_bounding_radius, sizeof(m_bounding_radius));
		file.read(&m_aabb, sizeof(m_aabb));
	}

	float bounding_radius_squared = 0;
	Vec3 min_vertex(0, 0, 0);
	Vec3 max_vertex(0, 0, 0);

	int vertex_size = global_vertex_decl.getStride();
	int position_attribute_offset = global_vertex_decl.getOffset(bgfx::Attrib::Position);
	int uv_attribute_offset = global_vertex_decl.getOffset(bgfx::Attrib::TexCoord0);
	int weights_attribute_offset = global_vertex_decl.getOffset(bgfx::Attrib::Weight);
	int bone_indices_attribute_offset = global_vertex_decl.getOffset(bgfx::Attrib::Indices);
	bool keep_skin = global_vertex_decl.has(bgfx::Attrib::Weight) && global_vertex_decl.has(bgfx::Attrib::Indices);
	for (int i = 0; i < m_meshes.size(); ++i)
	{
		Offsets& offsets = mesh_offsets[i];
		Mesh& mesh = m_meshes[i];
		mesh.indices_count = offsets.mesh_tri_count * 3;
		mesh.indices.resize(mesh.indices_count * index_size);
		copyMemory(&mesh.indices[0], &indices[offsets.indices_offset * index_size], mesh.indices_count * index_size);

		int mesh_vertex_count = offsets.attribute_array_size / global_vertex_decl.getStride();
		int mesh_attributes_array_offset = offsets.attribute_array_offset;
		mesh.vertices.resize(mesh_vertex_count);
		mesh.uvs.resize(mesh_vertex_count);
		if (keep_skin) mesh.skin.resize(mesh_vertex_count);
		for (int j = 0; j < mesh_vertex_count; ++j)
		{
			int offset = mesh_attributes_array_offset + j * vertex_size;
			if (keep_skin)
			{
				mesh.skin[j].weights = *(const Vec4*)&vertices[offset + weights_attribute_offset];
				copyMemory(mesh.skin[j].indices,
					&vertices[offset + bone_indices_attribute_offset],
					sizeof(mesh.skin[j].indices));
			}
			mesh.vertices[j] = *(const Vec3*)&vertices[offset + position_attribute_offset];
			mesh.uvs[j] = *(const Vec2*)&vertices[offset + uv_attribute_offset];
			float sq_len = mesh.vertices[j].squaredLength();
			bounding_radius_squared = Math::maximum(bounding_radius_squared, sq_len > 0 ? sq_len : 0);
			min_vertex.x = Math::minimum(min_vertex.x, mesh.vertices[j].x);
			min_vertex.y = Math::minimum(min_vertex.y, mesh.vertices[j].y);
			min_vertex.z = Math::minimum(min_vertex.z, mesh.vertices[j].z);
			max_vertex.x = Math::maximum(max_vertex.x, mesh.vertices[j].x);
			max_vertex.y = Math::maximum(max_vertex.y, mesh.vertices[j].y);
			max_vertex.z = Math::maximum(max_vertex.z, mesh.vertices[j].z);
		}
	}

	if (version <= FileVersion::BOUNDING_SHAPES_PRECOMPUTED)
	{
		m_bounding_radius = sqrt(bounding_radius_squared);
		m_aabb = AABB(min_vertex, max_vertex);
	}

	for (int i = 0; i < m_meshes.size(); ++i)
	{
		Mesh& mesh = m_meshes[i];
		Offsets offsets = mesh_offsets[i];
		
		ASSERT(!bgfx::isValid(mesh.index_buffer_handle));
		if (global_flags & INDICES_16BIT_FLAG)
		{
			mesh.flags.set(Mesh::Flags::INDICES_16_BIT);
		}
		int indices_size = index_size * mesh.indices_count;
		const bgfx::Memory* mem = bgfx::copy(&indices[offsets.indices_offset * index_size], indices_size);
		mesh.index_buffer_handle = bgfx::createIndexBuffer(mem, index_size == 4 ? BGFX_BUFFER_INDEX32 : 0);
		if (!bgfx::isValid(mesh.index_buffer_handle)) return false;

		ASSERT(!bgfx::isValid(mesh.vertex_buffer_handle));
		const bgfx::Memory* vertices_mem = bgfx::copy(&vertices[offsets.attribute_array_offset], offsets.attribute_array_size);
		mesh.vertex_buffer_handle = bgfx::createVertexBuffer(vertices_mem, mesh.vertex_decl);
		if (!bgfx::isValid(mesh.vertex_buffer_handle)) return false;
	}

	return true;
}
bool Texture::loadTGA(FS::IFile& file)
{
	PROFILE_FUNCTION();
	TGAHeader header;
	file.read(&header, sizeof(header));

	int color_mode = header.bitsPerPixel / 8;
	int image_size = header.width * header.height * 4;
	if (header.dataType != 2)
	{
		g_log_error.log("renderer") << "Unsupported texture format "
									<< m_path.c_str();
		return false;
	}

	if (color_mode < 3)
	{
		g_log_error.log("renderer") << "Unsupported color mode "
									<< m_path.c_str();
		return false;
	}

	m_width = header.width;
	m_height = header.height;
	TextureManager* manager = static_cast<TextureManager*>(
		getResourceManager().get(ResourceManager::TEXTURE));
	if (m_data_reference)
	{
		m_data.resize(image_size);
	}
	uint8_t* image_dest = m_data_reference
							  ? &m_data[0]
							  : (uint8_t*)manager->getBuffer(image_size);

	// Targa is BGR, swap to RGB, add alpha and flip Y axis
	for (long y = 0; y < header.height; y++)
	{
		long read_index = y * header.width * color_mode;
		long write_index = ((header.imageDescriptor & 32) != 0)
							   ? read_index
							   : y * header.width * 4;
		for (long x = 0; x < header.width; x++)
		{
			file.read(&image_dest[write_index + 2], sizeof(uint8_t));
			file.read(&image_dest[write_index + 1], sizeof(uint8_t));
			file.read(&image_dest[write_index + 0], sizeof(uint8_t));
			if (color_mode == 4)
				file.read(&image_dest[write_index + 3], sizeof(uint8_t));
			else
				image_dest[write_index + 3] = 255;
			write_index += 4;
		}
	}
	m_BPP = 4;

	m_texture_handle = bgfx::createTexture2D(
		header.width,
		header.height,
		1,
		bgfx::TextureFormat::RGBA8,
		m_flags,
		0);
	bgfx::updateTexture2D(
		m_texture_handle,
		0,
		0,
		0,
		header.width,
		header.height,
		bgfx::copy(image_dest, header.width * header.height * 4));
	m_depth = 1;
	return bgfx::isValid(m_texture_handle);
}