Esempio n. 1
0
/**
 * \brief we need to go through the hierarchy and set the combined matrices
 * calls itself recursively as it tareverses the hierarchy
 * \param device - the Direct3D device object
 * \param pFrame - current frame
 * \param pParentMatrix - the parent frame matrix
 * \author Keith Ditchburn \date 18 July 2005
*/
void CXFileEntity::SetupBoneMatrices(D3DXFRAME_EXTENDED *pFrame, LPD3DXMATRIX pParentMatrix)
{
	// Cast to our extended structure first
	D3DXMESHCONTAINER_EXTENDED* pMesh = (D3DXMESHCONTAINER_EXTENDED*)pFrame->pMeshContainer;

	// If this frame has a mesh
	if(pMesh)
	{
		// We need to remember which is the first mesh in the hierarchy for later when we 
		// update (FrameMove)
		if(!m_firstMesh)
			m_firstMesh = pMesh;
		
		// if there is skin info, then setup the bone matrices
		if(pMesh->pSkinInfo && pMesh->MeshData.pMesh)
		{
			// Create a copy of the mesh to skin into later
			D3DVERTEXELEMENT9 Declaration[MAX_FVF_DECL_SIZE];
			if (FAILED(pMesh->MeshData.pMesh->GetDeclaration(Declaration)))
				return;

			pMesh->MeshData.pMesh->CloneMesh(D3DXMESH_MANAGED, 
				Declaration, m_d3dDevice, 
				&pMesh->exSkinMesh);

			// Max bones is calculated for later use (to know how big to make the bone matrices array)
			m_maxBones=max(m_maxBones,(int)pMesh->pSkinInfo->GetNumBones());

			// For each bone work out its matrix
			for (unsigned int i = 0; i < pMesh->pSkinInfo->GetNumBones(); i++)
			{   
				// Find the frame containing the bone
				D3DXFRAME_EXTENDED* pTempFrame = (D3DXFRAME_EXTENDED*)D3DXFrameFind(m_frameRoot, 
						pMesh->pSkinInfo->GetBoneName(i));

				// set the bone part - point it at the transformation matrix
				pMesh->exFrameCombinedMatrixPointer[i] = &pTempFrame->exCombinedTransformationMatrix;
			}

		}
	}

	// Pass on to sibblings
	if(pFrame->pFrameSibling)
		SetupBoneMatrices((D3DXFRAME_EXTENDED*)pFrame->pFrameSibling, pParentMatrix);

	// Pass on to children
	if(pFrame->pFrameFirstChild)
		SetupBoneMatrices((D3DXFRAME_EXTENDED*)pFrame->pFrameFirstChild, &pFrame->exCombinedTransformationMatrix);
}
Esempio n. 2
0
bool XEnitity::Load(const std::string FileName)
{
	m_FileName = FileName;

	MeshAllocation* pMeshAlloc = new MeshAllocation;

	HRESULT hr = D3DXLoadMeshHierarchyFromX(m_FileName.c_str(),
		D3DXMESH_MANAGED,
		m_d3ddev, 
		pMeshAlloc,
		NULL,
		&m_pTopFrame,
		&m_pAnimCtrl);

	SAFE_DELETE(pMeshAlloc);

	if(FAILED(hr))	return false;

	m_NumAnimationSets = m_pAnimCtrl->GetNumAnimationSets();

	if(m_pTopFrame)
	{
		SetupBoneMatrices((CUSTOM_FRAME*) m_pTopFrame);

		m_pBoneMatrices = new D3DXMATRIX[m_MaxBones];
		memset(m_pBoneMatrices, 0, sizeof(D3DXMATRIX)*m_MaxBones);
	}

	return true;
}
Esempio n. 3
0
bool CXFileEntity::Load(const std::string &filename)
{
	// Create our mesh hierarchy class to control the allocation of memory - only used temporarily
	CMeshHierarchy *memoryAllocator=new CMeshHierarchy;

	// To make it easier to find the textures change the current directory to the one containing the .x file
	// First though remember the current one to put it back afterwards
	std::string currentDirectory=CUtility::GetTheCurrentDirectory();

	std::string xfilePath;
	CUtility::SplitPath(filename,&xfilePath,&m_filename);

	SetCurrentDirectory(xfilePath.c_str());

	// This is the function that does all the .x file loading. We provide a pointer to an instance of our 
	// memory allocator class to handle memory allocationm during the frame and mesh loading
	HRESULT hr = D3DXLoadMeshHierarchyFromX(filename.c_str(), D3DXMESH_MANAGED, m_d3dDevice, 
		memoryAllocator, NULL, &m_frameRoot, &m_animController);

	delete memoryAllocator;
	memoryAllocator=0;

	SetCurrentDirectory(currentDirectory.c_str());
	
	if (FAILED(hr))
		return false; 

	// if the x file contains any animation remember how many sets there are
	if(m_animController)
		m_numAnimationSets = m_animController->GetMaxNumAnimationSets();

	// Bones for skining
	if(m_frameRoot)
	{
		// Set the bones up
		SetupBoneMatrices((D3DXFRAME_EXTENDED*)m_frameRoot, NULL);

		// Create the bone matrices array for use during FrameMove to hold the final transform
		m_boneMatrices  = new D3DXMATRIX[m_maxBones];
		ZeroMemory(m_boneMatrices, sizeof(D3DXMATRIX)*m_maxBones);

		// Calculate the Bounding Sphere for this model (used in CalculateInitialViewMatrix to position camera correctly)
		D3DXFrameCalculateBoundingSphere(m_frameRoot, &m_sphereCentre, &m_sphereRadius);
	}

	m_firstMesh->MeshData.pMesh->GetVertexBuffer(&vb.vb);
	m_firstMesh->MeshData.pMesh->GetIndexBuffer(&ib.ib);

	D3DVERTEXELEMENT9 pDecl[MAX_FVF_DECL_SIZE];
	m_firstMesh->MeshData.pMesh->GetDeclaration(pDecl);
	renderSystem->CreateVertexDeclaration(&pDecl[0],&vb.declaration);
	// Получение данных о количестве вершин, индексов и полигонов
	dwNumVerticies	= m_firstMesh->MeshData.pMesh->GetNumVertices();
	dwNumIndecies	= m_firstMesh->MeshData.pMesh->GetNumFaces()*3;
	dwNumFaces		= m_firstMesh->MeshData.pMesh->GetNumFaces();
	vb.vertexSize = (short)m_firstMesh->MeshData.pMesh->GetNumBytesPerVertex();
	return true;
}
Esempio n. 4
0
void XEnitity::SetupBoneMatrices(CUSTOM_FRAME *pFrame)
{
	CUSTOM_MESHCONTAINER* pMeshContainer = (CUSTOM_MESHCONTAINER*) pFrame->pMeshContainer; 

	while(pMeshContainer && pMeshContainer->pSkinInfo){

		D3DVERTEXELEMENT9 Declaration[MAX_FVF_DECL_SIZE];
		if( FAILED( pMeshContainer->MeshData.pMesh->GetDeclaration(Declaration) ) )
			return;
		//clone the mesh
		pMeshContainer->MeshData.pMesh->CloneMesh(D3DXMESH_MANAGED, Declaration, m_d3ddev, &pMeshContainer->pExSkinMesh);

		//calc the max bones
		DWORD NumBones = pMeshContainer->pSkinInfo->GetNumBones();
		m_MaxBones = max(m_MaxBones, (unsigned int)NumBones);

		for(unsigned int i = 0; i < NumBones; ++i){
			CUSTOM_FRAME* pTmpFrame = (CUSTOM_FRAME*) D3DXFrameFind(m_pTopFrame, pMeshContainer->pSkinInfo->GetBoneName(i));

			pMeshContainer->pExFrameCombinedMatrixPointer[i] = &pTmpFrame->exCombTransformationMatrix;
		}
		
		//loop for all meshes
		pMeshContainer = (CUSTOM_MESHCONTAINER*)pMeshContainer->pNextMeshContainer;
	}//end while

	//pass to siblings
	if(pFrame->pFrameSibling)
		SetupBoneMatrices((CUSTOM_FRAME*)pFrame->pFrameSibling);

	//pass to children
	if(pFrame->pFrameFirstChild)
		SetupBoneMatrices((CUSTOM_FRAME*)pFrame->pFrameFirstChild);

	return;
}
Esempio n. 5
0
File: Mesh.cpp Progetto: 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);
	}
}