예제 #1
0
파일: Mesh.cpp 프로젝트: lcs2/carpg
//=================================================================================================
// Wczytuje dane wierzcho³ków z modelu (na razie dzia³a tylko dla Vec3)
//=================================================================================================
void Mesh::LoadVertexData(VertexData* vd, StreamReader& stream)
{
	// read and check header
	Header head;
	if(!stream.Read(head))
		throw "Failed to read file header.";
	if(memcmp(head.format, "QMSH", 4) != 0)
		throw Format("Invalid file signature '%.4s'.", head.format);
	if(head.version != 20)
		throw Format("Invalid file version '%d'.", head.version);
	if(head.flags != F_PHYSICS)
		throw Format("Invalid mesh flags '%d'.", head.flags);
	vd->radius = head.radius;

	// read vertices
	uint size = sizeof(Vec3) * head.n_verts;
	if(!stream.Ensure(size))
		throw "Failed to read vertex data.";
	vd->verts.resize(head.n_verts);
	stream.Read(vd->verts.data(), size);

	// read faces
	size = sizeof(Face) * head.n_tris;
	if(!stream.Ensure(size))
		throw "Failed to read triangle data.";
	vd->faces.resize(head.n_tris);
	stream.Read(vd->faces.data(), size);
}
예제 #2
0
파일: Image.cpp 프로젝트: mshandle/spank
static void PngReaderCallback(png_structp pPngStruct, png_bytep pData, png_size_t nSize)
{
	StreamReader* pStream = (StreamReader*)png_get_io_ptr(pPngStruct);

	if (!pStream->Read(pData, nSize))
	{
		png_error(pPngStruct,"pngReaderCallback failed");
	}
}
예제 #3
0
파일: Mesh.cpp 프로젝트: lcs2/carpg
void Mesh::LoadPoints(StreamReader& stream)
{
	uint size = Point::MIN_SIZE * head.n_points;
	if(!stream.Ensure(size))
		throw "Failed to read points.";
	attach_points.clear();
	attach_points.resize(head.n_points);
	for(word i = 0; i < head.n_points; ++i)
	{
		Point& p = attach_points[i];

		stream.Read(p.name);
		stream.Read(p.mat);
		stream.Read(p.bone);
		stream.Read(p.type);
		stream.Read(p.size);
		stream.Read(p.rot);
		p.rot.y = Clip(-p.rot.y);
	}
}
예제 #4
0
파일: Mesh.cpp 프로젝트: lcs2/carpg
//=================================================================================================
void Mesh::LoadHeader(StreamReader& stream)
{
	// head
	if(!stream.Read(head))
		throw "Failed to read file header.";
	if(memcmp(head.format, "QMSH", 4) != 0)
		throw Format("Invalid file signature '%.4s'.", head.format);
	if(head.version < 12 || head.version > 20)
		throw Format("Invalid file version '%u'.", head.version);
	if(head.version < 20)
		throw Format("Unsupported file version '%u'.", head.version);
	if(head.n_bones >= 32)
		throw Format("Too many bones (%u).", head.n_bones);
	if(head.n_subs == 0)
		throw "Missing model mesh!";
	if(IS_SET(head.flags, F_ANIMATED) && !IS_SET(head.flags, F_STATIC))
	{
		if(head.n_bones == 0)
			throw "No bones.";
		if(head.n_groups == 0)
			throw "No bone groups.";
	}
}
예제 #5
0
파일: Mesh.cpp 프로젝트: lcs2/carpg
//=================================================================================================
// Wczytywanie modelu z pliku
//=================================================================================================
void Mesh::Load(StreamReader& stream, IDirect3DDevice9* device)
{
	assert(device);

	LoadHeader(stream);
	SetVertexSizeDecl();

	// ------ vertices
	// ensure size
	uint size = vertex_size * head.n_verts;
	if(!stream.Ensure(size))
		throw "Failed to read vertex buffer.";

	// create vertex buffer
	HRESULT hr = device->CreateVertexBuffer(size, 0, 0, D3DPOOL_MANAGED, &vb, nullptr);
	if(FAILED(hr))
		throw Format("Failed to create vertex buffer (%d).", hr);

	// read
	void* ptr;
	V(vb->Lock(0, size, &ptr, 0));
	stream.Read(ptr, size);
	V(vb->Unlock());

	// ----- triangles
	// ensure size
	size = sizeof(word) * head.n_tris * 3;
	if(!stream.Ensure(size))
		throw "Failed to read index buffer.";

	// create index buffer
	hr = device->CreateIndexBuffer(size, 0, D3DFMT_INDEX16, D3DPOOL_MANAGED, &ib, nullptr);
	if(FAILED(hr))
		throw Format("Failed to create index buffer (%d).", hr);

	// read
	V(ib->Lock(0, size, &ptr, 0));
	stream.Read(ptr, size);
	V(ib->Unlock());

	// ----- submeshes
	size = Submesh::MIN_SIZE * head.n_subs;
	if(!stream.Ensure(size))
		throw "Failed to read submesh data.";
	subs.resize(head.n_subs);

	for(word i = 0; i < head.n_subs; ++i)
	{
		Submesh& sub = subs[i];

		stream.Read(sub.first);
		stream.Read(sub.tris);
		stream.Read(sub.min_ind);
		stream.Read(sub.n_ind);
		stream.Read(sub.name);
		stream.ReadString1();

		if(BUF[0])
			sub.tex = ResourceManager::Get<Texture>().GetLoaded(BUF);
		else
			sub.tex = nullptr;

		// specular value
		stream.Read(sub.specular_color);
		stream.Read(sub.specular_intensity);
		stream.Read(sub.specular_hardness);

		// normalmap
		if(IS_SET(head.flags, F_TANGENTS))
		{
			stream.ReadString1();
			if(BUF[0])
			{
				sub.tex_normal = ResourceManager::Get<Texture>().GetLoaded(BUF);
				stream.Read(sub.normal_factor);
			}
			else
				sub.tex_normal = nullptr;
		}
		else
			sub.tex_normal = nullptr;

		// specular map
		stream.ReadString1();
		if(BUF[0])
		{
			sub.tex_specular = ResourceManager::Get<Texture>().GetLoaded(BUF);
			stream.Read(sub.specular_factor);
			stream.Read(sub.specular_color_factor);
		}
		else
			sub.tex_specular = nullptr;

		if(!stream)
			throw Format("Failed to read submesh %u.", i);
	}

	// animation data
	if(IS_SET(head.flags, F_ANIMATED) && !IS_SET(head.flags, F_STATIC))
	{
		// bones
		size = Bone::MIN_SIZE * head.n_bones;
		if(!stream.Ensure(size))
			throw "Failed to read bones.";
		bones.resize(head.n_bones + 1);

		// zero bone
		Bone& zero_bone = bones[0];
		zero_bone.parent = 0;
		zero_bone.name = "zero";
		zero_bone.id = 0;
		zero_bone.mat = Matrix::IdentityMatrix;

		for(byte i = 1; i <= head.n_bones; ++i)
		{
			Bone& bone = bones[i];

			bone.id = i;
			stream.Read(bone.parent);

			stream.Read(bone.mat._11);
			stream.Read(bone.mat._12);
			stream.Read(bone.mat._13);
			bone.mat._14 = 0;
			stream.Read(bone.mat._21);
			stream.Read(bone.mat._22);
			stream.Read(bone.mat._23);
			bone.mat._24 = 0;
			stream.Read(bone.mat._31);
			stream.Read(bone.mat._32);
			stream.Read(bone.mat._33);
			bone.mat._34 = 0;
			stream.Read(bone.mat._41);
			stream.Read(bone.mat._42);
			stream.Read(bone.mat._43);
			bone.mat._44 = 1;

			stream.Read(bone.name);

			bones[bone.parent].childs.push_back(i);
		}

		if(!stream)
			throw "Failed to read bones data.";

		// animations
		size = Animation::MIN_SIZE * head.n_anims;
		if(!stream.Ensure(size))
			throw "Failed to read animations.";
		anims.resize(head.n_anims);

		for(byte i = 0; i < head.n_anims; ++i)
		{
			Animation& anim = anims[i];

			stream.Read(anim.name);
			stream.Read(anim.length);
			stream.Read(anim.n_frames);

			size = anim.n_frames * (4 + sizeof(KeyframeBone) * head.n_bones);
			if(!stream.Ensure(size))
				throw Format("Failed to read animation %u data.", i);

			anim.frames.resize(anim.n_frames);

			for(word j = 0; j < anim.n_frames; ++j)
			{
				stream.Read(anim.frames[j].time);
				anim.frames[j].bones.resize(head.n_bones);
				stream.Read(anim.frames[j].bones.data(), sizeof(KeyframeBone) * head.n_bones);
			}
		}

		// add zero bone to count
		++head.n_bones;
	}

	LoadPoints(stream);

	// bone groups
	if(IS_SET(head.flags, F_ANIMATED) && !IS_SET(head.flags, F_STATIC))
	{
		if(!stream.Ensure(BoneGroup::MIN_SIZE * head.n_groups))
			throw "Failed to read bone groups.";
		groups.resize(head.n_groups);
		for(word i = 0; i < head.n_groups; ++i)
		{
			BoneGroup& gr = groups[i];

			stream.Read(gr.name);

			// parent group
			stream.Read(gr.parent);
			assert(gr.parent < head.n_groups);
			assert(gr.parent != i || i == 0);

			// bone indexes
			byte count;
			stream.Read(count);
			gr.bones.resize(count);
			stream.Read(gr.bones.data(), gr.bones.size());
		}

		if(!stream)
			throw "Failed to read bone groups data.";

		SetupBoneMatrices();
	}

	// splits
	if(IS_SET(head.flags, F_SPLIT))
	{
		size = sizeof(Split) * head.n_subs;
		if(!stream.Ensure(size))
			throw "Failed to read mesh splits.";
		splits.resize(head.n_subs);
		stream.Read(splits.data(), size);
	}
}