예제 #1
0
/**
*  @brief
*    Returns position, rotation and scale from a matrix
*/
void PLTools::GetPosRotScale(const GMatrix &mTransform, Point3 &vPos, Quat &qRot, Point3 &vScale, bool bFlip)
{
	// Get the position
	vPos = mTransform.Translation();

	// Get the rotation of the node as quaternion
	qRot = mTransform.Rotation();

	// Flip 180 degree around the y-axis? (true for camera and spot lights)
	if (bFlip) {
		Quat qRotationOffset;

		// We have to add a rotation about the x-axis of -90 degree... is this a IGame transform bug or something other odd??
		float fAngles[] = {static_cast<float>(HALFPI), 0.0f, 0.0f};
		EulerToQuat(fAngles, qRotationOffset);
		qRot = qRotationOffset*qRot;

		// We have to 'invert the z-axis', this is no PixelLight bug or so, we decided to do so to make things more universal
		fAngles[0] = 0.0f;
		fAngles[2] = static_cast<float>(PI);
		EulerToQuat(fAngles, qRotationOffset);
		qRot = qRotationOffset*qRot;
	}

	// Look out! We REALLY need to take the parity of the transform matrix into account!
	vScale = mTransform.Scaling()*static_cast<float>(mTransform.Parity());
}
예제 #2
0
void MeshExporter::_dumpJoint(IGameNode * node)
{
	IGameObject * obj = node->GetIGameObject();
	IGameObject::MaxType T = obj->GetMaxType();
	IGameObject::ObjectTypes type = obj->GetIGameType();
	const char * name = node->GetName();
		
	switch(type)
	{
	case IGameObject::IGAME_BONE:
	case IGameObject::IGAME_HELPER:
		{
			joint * bone = mMeshSource->NewJoint(node->GetName());
			int parent = -1;

			if (node->GetNodeParent())
			{
				parent = _getJointId(node->GetNodeParent()->GetName());

				mMeshSource->SetJointLink(parent, mMeshSource->GetJointCount() - 1);
			}
			else
			{
				INode* pNode = node->GetMaxNode()->GetParentNode();
				if (pNode)
					parent = _getJointId(pNode->GetName());
			}
				
			IGameControl * pGameControl = node->GetIGameControl();
			// base matrix
			{
				GMatrix matWorld = node->GetLocalTM();
				bone->position = Utility::ToFloat3(matWorld.Translation());
				bone->rotation = Utility::ToQuat(matWorld.Rotation());
				bone->scale = Utility::ToFloat3(matWorld.Scaling());

				/*
				if (node->GetNodeParent())
				{
					int parentId = _getBoneId(node->GetNodeParent()->GetName());

					if (parentId != -1)
					{
						xBone * parentBn = GetBone(parentId);

						bone->position = bone->position - parentBn->position;
						bone->orientation = parentBn->orientation.Inverse() * bone->orientation;
						bone->scale = bone->scale / parentBn->scale;
					}
				}
				*/
			}

			_dumpAnimation(pGameControl, mMeshSource->GetJointCount() - 1);
		}

		break;
	}
}
예제 #3
0
bool Optimizer::
dumpPhysXCookMesh(IGameNode* gameNode, const std::string& nodeName, int flag)
{
	// 受缩放影响
	GMatrix worldTM = gameNode->GetWorldTM();
	Point3 scale = worldTM.Scaling();
	// 世界矩阵的逆矩阵
	GMatrix nodeInvWorldTM = gameNode->GetWorldTM().Inverse();
	IGameObject* gameObject = gameNode->GetIGameObject();
	IGameMesh* gameMesh = static_cast<IGameMesh*>(gameObject);
	gameMesh->InitializeData();
	int numFaces = gameMesh->GetNumberOfFaces();
	int numVertex = numFaces * 3;
	std::vector<physx::PxVec3> pxVertices;
	pxVertices.reserve(numVertex);
	oiram::IndexBuffer indexBuffer;
	indexBuffer.use32BitIndices = numVertex > 65535;
	indexBuffer.use32BitIndices ? indexBuffer.uiIndexBuffer.reserve(numVertex) : indexBuffer.usIndexBuffer.reserve(numVertex);
	for (int i = 0; i < numFaces; ++i)
	{
		FaceEx* face = gameMesh->GetFace(i);
		for (int v = 0; v < 3; ++v)
		{
			Point3 position = gameMesh->GetVertex(face->vert[v], false);
			position = position * nodeInvWorldTM;
			pxVertices.push_back(physx::PxVec3(position.x * scale.x, position.y * scale.y, position.z * scale.z));
			if (indexBuffer.use32BitIndices)
				indexBuffer.uiIndexBuffer.push_back(static_cast<unsigned int>(indexBuffer.uiIndexBuffer.size()));
			else
				indexBuffer.usIndexBuffer.push_back(static_cast<unsigned short>(indexBuffer.usIndexBuffer.size()));
		}
	}
	gameNode->ReleaseIGameObject();

	// 初始化physx对象
	physx::PxDefaultAllocator s_defAlloc;
	PxOiramErrorCallback s_defErrCb;
	physx::PxFoundation* pFound = PxCreateFoundation(PX_PHYSICS_VERSION, s_defAlloc, s_defErrCb);
	physx::PxCooking* pCooking = PxCreateCooking(PX_PHYSICS_VERSION, *pFound, physx::PxCookingParams());

	// 优化物理模型顶点
	optimizePhysXMesh(flag, mD3DDevice, mEpsilon, pxVertices, indexBuffer);

	bool success = false;
	PxCookMesh cookMesh;
	switch (flag)
	{
	// cookConvexMesh
	case 1:
	default:
		{
			physx::PxConvexMeshDesc meshDesc;
			meshDesc.points.data = pxVertices.data();
			meshDesc.points.count = static_cast<physx::PxU32>(pxVertices.size());
			meshDesc.points.stride = sizeof(physx::PxVec3);
			meshDesc.flags = physx::PxConvexFlag::eCOMPUTE_CONVEX;

			// 先尝试导出
			success = meshDesc.isValid() && pCooking->cookConvexMesh(meshDesc, cookMesh);
			if (!success)
			{
				// polygon数量大于255的时候需要加上eINFLATE_CONVEX
				meshDesc.flags |= physx::PxConvexFlag::eINFLATE_CONVEX;
				success = meshDesc.isValid() && pCooking->cookConvexMesh(meshDesc, cookMesh);
			}
		}
		break;

	// cookTriangleMesh
	case 2:
		{
			physx::PxTriangleMeshDesc meshDesc;
			meshDesc.points.data = pxVertices.data();
			meshDesc.points.count = static_cast<physx::PxU32>(pxVertices.size());
			meshDesc.points.stride = sizeof(physx::PxVec3);

			if (indexBuffer.use32BitIndices)
			{
				meshDesc.triangles.data = indexBuffer.uiIndexBuffer.data();
				meshDesc.triangles.count = static_cast<physx::PxU32>(indexBuffer.uiIndexBuffer.size()) / 3;
				meshDesc.triangles.stride = sizeof(physx::PxU32) * 3;
			}
			else
			{
				meshDesc.triangles.data = indexBuffer.usIndexBuffer.data();
				meshDesc.triangles.count = static_cast<physx::PxU16>(indexBuffer.usIndexBuffer.size()) / 3;
				meshDesc.triangles.stride = sizeof(physx::PxU16) * 3;
				meshDesc.flags = physx::PxMeshFlag::e16_BIT_INDICES;
			}

			success = meshDesc.isValid();
			success = success && pCooking->cookTriangleMesh(meshDesc, cookMesh);
		}
		break;
	}

	if (success)
	{
		std::string pxName = nodeName + ".px";
		LogManager::getSingleton().logMessage(false, "Exporting: %s", pxName.c_str());

		pxName = config.exportPath + pxName;
		FILE* fp = fopen(pxName.c_str(), "wb");
		if (fp)
		{
			fwrite(cookMesh.getData(), cookMesh.getSize(), 1, fp);
			fclose(fp);
		}
	}

	pCooking->release();
	pFound->release();
	
	return success;
}