PxTriangleMesh* PhysicsSystem::cookTriangleMesh(Mesh& mesh) {
	FDUint nbVerts = mesh.getVertexCount();
	FDUint triCount = mesh.getIndexCount() / 3;
	void* verts = mesh.getSourceData();
	void* indices = mesh.getSourceIndexData();

	PxTriangleMeshDesc meshDesc;
	meshDesc.flags |= PxMeshFlag::e16_BIT_INDICES;

	meshDesc.points.count = nbVerts;
	meshDesc.points.stride = mesh.getDescriptor()->getVertexSize();
	meshDesc.points.data = verts;

	meshDesc.triangles.count        = triCount;
	meshDesc.triangles.stride       = 3*sizeof(PxU16);
	meshDesc.triangles.data         = indices;

	PxDefaultMemoryOutputStream writeBuffer;
	FDbool status = cooking->cookTriangleMesh(meshDesc, writeBuffer);
	if (!status) {
		FD_THROW(GenericException("Cooking failed."));
	}

	PxDefaultMemoryInputData readBuffer(writeBuffer.getData(), 
			writeBuffer.getSize());
	PxTriangleMesh* physicalMesh = physics->createTriangleMesh(readBuffer);
	return physicalMesh;
}
PxTriangleMesh* Physx::createTriangleMesh( const vector<vec3>& positions, size_t numTriangles, vector<uint32_t> indices )
{
	if ( positions.empty() ) {
		return nullptr;
	}
	if ( indices.empty() ) {
		CI_ASSERT( positions.size() % 3 == 0 );
		uint32_t count = (uint32_t)positions.size();
		for ( uint32_t i = 0; i < count; ++i ) {
			indices.push_back( i );
		}
		numTriangles = indices.size() / 3;
	}
	
	PxTriangleMeshDesc desc;
	desc.points.count		= (PxU32)positions.size();
	desc.points.data		= (PxVec3*)&positions[ 0 ];
	desc.points.stride		= sizeof( PxVec3 );
	desc.triangles.count	= (PxU32)numTriangles;
	desc.triangles.data		= (PxU32*)&indices[ 0 ];
	desc.triangles.stride	= sizeof( PxU32 ) * 3;
	
	PxDefaultMemoryOutputStream writeBuffer;
	if ( !mCooking->cookTriangleMesh( desc, writeBuffer ) ) {
		return nullptr;
	}
	
	PxDefaultMemoryInputData readBuffer( writeBuffer.getData(), writeBuffer.getSize() );
	return mPhysics->createTriangleMesh( readBuffer );
}
Exemple #3
0
physx::PxInputStream*
PhysXRigidManager::getTriangleMeshGeo(PxScene *world, physx::PxCooking* mCooking, ExternalInfo externInfo, bool isStatic) {
	PxPhysics *gPhysics = &(world->getPhysics());
	PxDefaultMemoryOutputStream *writeBuffer = new PxDefaultMemoryOutputStream();

	bool status;
	if (isStatic) {
		PxTriangleMeshDesc meshDesc;
		meshDesc.points.count = externInfo.nbVertices;
		meshDesc.points.stride = 4 * sizeof(float);
		meshDesc.points.data = externInfo.vertices;

		meshDesc.triangles.count = static_cast<int> (externInfo.nbIndices / 3);
		meshDesc.triangles.stride = 3 * sizeof(unsigned int);
		meshDesc.triangles.data = externInfo.indices;
		
		status = mCooking->cookTriangleMesh(meshDesc, *writeBuffer);
	}
	else {
		PxConvexMeshDesc meshDesc2;

		meshDesc2.points.count = externInfo.nbVertices;
		meshDesc2.points.stride = 4 * sizeof(float);
		meshDesc2.points.data = externInfo.vertices;
		meshDesc2.flags |= PxConvexFlag::eCOMPUTE_CONVEX | PxConvexFlag::eINFLATE_CONVEX;
		meshDesc2.vertexLimit = 256;

		status = mCooking->cookConvexMesh(meshDesc2, *writeBuffer);

	}
	return new PxDefaultMemoryInputData(writeBuffer->getData(), writeBuffer->getSize());
}
	PxGeometry& Camera::getPixelFrustum(FDreal pixelXSize, FDreal pixelYSize) {
		
		if (pixelFrustum.isValid()) {
			return pixelFrustum;
		}

		Vector3 proj1(-pixelXSize / 2, -pixelYSize / 2, 1);
		Vector3 proj2(-pixelXSize / 2, pixelYSize / 2, 1);
		Vector3 proj3(pixelXSize / 2, -pixelYSize / 2, 1);
		Vector3 proj4(pixelXSize / 2, pixelYSize / 2, 1);

		fdmath::Matrix44 projInverse;
		fdmath::gluInvertMatrix44(projection, projInverse);

		FDreal len = -100.0f;
		Vector3 view1 = projInverse.transform(proj1).getNormalized() * len;
		Vector3 view2 = projInverse.transform(proj2).getNormalized() * len;
		Vector3 view3 = projInverse.transform(proj3).getNormalized() * len;
		Vector3 view4 = projInverse.transform(proj4).getNormalized() * len;

		static const PxVec3 convexVerts[] = {PxVec3(0,0,0), view1, 
				view2, view3, view4};

		PhysicsSystem* physics = FreeThread__getWorld().
				getSystem<PhysicsSystem>();

		PxConvexMeshDesc convexDesc;
		convexDesc.points.count     = 5;
		convexDesc.points.stride    = sizeof(PxVec3);
		convexDesc.points.data      = convexVerts;
		convexDesc.flags            = PxConvexFlag::eCOMPUTE_CONVEX;
		convexDesc.vertexLimit      = 256;

		PxDefaultMemoryOutputStream buf;
		if (!physics->cooking->cookConvexMesh(convexDesc, buf)) {
			FD_THROW(GenericException("Unable to cook convex pixel mesh!"));
		}
		PxDefaultMemoryInputData input(buf.getData(), buf.getSize());
		PxConvexMesh* convexMesh = physics->physics->createConvexMesh(input);

		pixelFrustum = PxConvexMeshGeometry(convexMesh);

		return pixelFrustum;
	}
static PxConvexMesh* createConvexMesh(const PxVec3* verts, const PxU32 numVerts, PxPhysics& physics, PxCooking& cooking)
{
	// Create descriptor for convex mesh
	PxConvexMeshDesc convexDesc;
	convexDesc.points.count			= numVerts;
	convexDesc.points.stride		= sizeof(PxVec3);
	convexDesc.points.data			= verts;
	convexDesc.flags				= PxConvexFlag::eCOMPUTE_CONVEX | PxConvexFlag::eINFLATE_CONVEX;

	PxConvexMesh* convexMesh = NULL;
	PxDefaultMemoryOutputStream buf;
	if(cooking.cookConvexMesh(convexDesc, buf))
	{
		PxDefaultMemoryInputData id(buf.getData(), buf.getSize());
		convexMesh = physics.createConvexMesh(id);
	}

	return convexMesh;
}
PxConvexMesh* ConvexHull::compute(fdcore::Array<fdmath::Vector3> points,
		PhysicsSystem& physicsSystem) {

	PxConvexMeshDesc convexDesc;
	convexDesc.points.count     = points.length;
	convexDesc.points.stride    = sizeof(PxVec3);
	convexDesc.points.data      = points.elements;
	convexDesc.flags            = PxConvexFlag::eCOMPUTE_CONVEX;
	convexDesc.vertexLimit      = 256;

	PxDefaultMemoryOutputStream buf;
	if (!physicsSystem.cooking->cookConvexMesh(convexDesc, buf)) {
		FD_THROW(GenericException("Unable to cook convex pixel mesh!"));
	}
	PxDefaultMemoryInputData input(buf.getData(), buf.getSize());
	PxConvexMesh* convexMesh = physicsSystem.physics->createConvexMesh(input);

	return convexMesh;
}
PxConvexMesh* Physx::createConvexMesh( const vector<vec3>& positions, PxConvexFlags flags )
{
	if ( positions.empty() ) {
		return nullptr;
	}
	PxConvexMeshDesc desc;
	desc.points.count	= (PxU32)positions.size();
	desc.points.data	= (PxVec3*)&positions[ 0 ];
	desc.points.stride	= sizeof( PxVec3 );
	desc.flags			= flags;
	
	PxDefaultMemoryOutputStream buffer;
	if ( !mCooking->cookConvexMesh( desc, buffer ) ) {
		return nullptr;
	}
	
	PxDefaultMemoryInputData input( buffer.getData(), buffer.getSize() );
	return mPhysics->createConvexMesh( input );
}
Exemple #8
0
//PxTriangleMesh*
PxDefaultMemoryInputData
getTriangleMeshGeo(PxScene *m_pDynamicsWorld, std::shared_ptr<nau::scene::IScene> &aScene, bool isStatic=true) {
    PxPhysics *gPhysics = &(m_pDynamicsWorld->getPhysics());

    std::shared_ptr<nau::scene::SceneObject> &aObject = aScene->getSceneObject(0);
    std::shared_ptr<VertexData> &vd = aObject->getRenderable()->getVertexData();
    std::vector<std::shared_ptr<MaterialGroup>> &matGroups = aObject->getRenderable()->getMaterialGroups();
    std::vector<std::shared_ptr<MaterialGroup>>::iterator matGroupsIter;

    PxDefaultMemoryOutputStream writeBuffer;

    PxTriangleMeshDesc meshDesc;
    matGroupsIter = matGroups.begin();
    for (; matGroupsIter != matGroups.end(); matGroupsIter++) {
        if ((*matGroupsIter)->getIndexData()->getIndexSize()) {
            std::shared_ptr<std::vector<unsigned int>> &indexes = (*matGroupsIter)->getIndexData()->getIndexData();

            meshDesc.points.count = static_cast<int> (vd->getDataOf(VertexData::GetAttribIndex(std::string("position")))->size());
            meshDesc.points.stride = 4 * sizeof(float);
            meshDesc.points.data = reinterpret_cast<const unsigned char *>(&(vd->getDataOf(VertexData::GetAttribIndex(std::string("position")))->at(0)));

            meshDesc.triangles.count = static_cast<int> (indexes->size() / 3);
            meshDesc.triangles.stride = 3 * sizeof(unsigned int);
            meshDesc.triangles.data = reinterpret_cast<const unsigned char *>(&((*indexes)[0]));

        }
    }
    bool status;
    if (isStatic) {
        //PxToolkit::MemoryOutputStream writeBuffer;
        status = mCooking->cookTriangleMesh(meshDesc, writeBuffer);
        //if (!status)
        //	return NULL;
    }
    else {
        PxConvexMeshDesc meshDesc2;

        /*PxU32 nbVerts = 0;
        PxVec3 * vertices;
        PxU32 nbIndices = 0 ;
        PxU32 *	indices;
        PxU32 nbPolygons = 0;
        PxHullPolygon * hullPolygons;

        if (mCooking->computeHullPolygons(meshDesc, gAllocator, nbVerts, vertices, nbIndices, indices, nbPolygons, hullPolygons)) {
        	meshDesc2.points.count = nbVerts;
        	meshDesc2.points.data = vertices;
        	meshDesc2.points.stride = sizeof(PxVec3);
        	meshDesc2.indices.count = nbIndices;
        	meshDesc2.indices.data = indices;
        	meshDesc2.indices.stride = sizeof(PxU32);
        	meshDesc2.polygons.count = nbPolygons;
        	meshDesc2.polygons.data = hullPolygons;
        	meshDesc2.polygons.stride = sizeof(PxHullPolygon);
        	meshDesc2.flags = PxConvexFlag::eINFLATE_CONVEX;
        }
        else {*/
        meshDesc2.points.count = meshDesc.points.count;
        meshDesc2.points.stride = meshDesc.points.stride;
        meshDesc2.points.data = meshDesc.points.data;
        meshDesc2.flags |= PxConvexFlag::eCOMPUTE_CONVEX | PxConvexFlag::eINFLATE_CONVEX;
        meshDesc2.vertexLimit = 256;
        //}
        /*PxConvexMeshDesc meshDesc;
        matGroupsIter = matGroups.begin();
        for (; matGroupsIter != matGroups.end(); matGroupsIter++) {
        	if ((*matGroupsIter)->getIndexData()->getIndexSize()) {
        		std::shared_ptr<std::vector<unsigned int>> &indexes = (*matGroupsIter)->getIndexData()->getIndexData();

        		meshDesc.points.count = static_cast<int> (vd->getDataOf(VertexData::GetAttribIndex(std::string("position")))->size());
        		meshDesc.points.stride = 4 * sizeof(float);
        		meshDesc.points.data = reinterpret_cast<const unsigned char *>(&(vd->getDataOf(VertexData::GetAttribIndex(std::string("position")))->at(0)));
        		meshDesc.flags = PxConvexFlag::eCOMPUTE_CONVEX | PxConvexFlag::eINFLATE_CONVEX;
        		meshDesc.vertexLimit = 256;
        	}
        }*/
        status = mCooking->cookConvexMesh(meshDesc2, writeBuffer);

    }

    //PxToolkit::PxInputStream readBuffer(writeBuffer.getData(), writeBuffer.getSize());
    PxDefaultMemoryInputData readBuffer(writeBuffer.getData(), writeBuffer.getSize());
    return readBuffer;
    //return gPhysics->createTriangleMesh(readBuffer);
}
	/**
	 * Attempts to cook a triangle or convex mesh from the provided mesh data. Will log a warning and return false if it is
	 * unable to cook the mesh. If the method returns true the resulting convex mesh will be output in the @p data buffer,
	 * and its size in @p size. The data buffer will be allocated used the generic allocator and is up to the caller to 
	 * free it.
	 */
	bool cookMesh(const SPtr<MeshData>& meshData, PhysicsMeshType type, UINT8** data, UINT32& size)
	{
		if (meshData == nullptr)
			return false;

		PxCooking* cooking = gPhysX().getCooking();
		if (cooking == nullptr)
		{
			LOGWRN("Attempting to cook a physics mesh but cooking is not enabled globally.");
			return false;
		}

		SPtr<VertexDataDesc> vertexDesc = meshData->getVertexDesc();
		if (!vertexDesc->hasElement(VES_POSITION))
		{
			LOGWRN("Provided PhysicsMesh mesh data has no vertex positions.");
			return false;
		}

		if (type == PhysicsMeshType::Convex)
		{
			if(!cookConvex(cooking, meshData, data, size))
			{
				LOGWRN("Failed cooking a convex mesh. Perpahs it is too complex? Maximum number of convex vertices is 256.");
				return false;
			}
		}
		else
		{
			PxTriangleMeshDesc meshDesc;
			meshDesc.points.count = meshData->getNumVertices();
			meshDesc.points.stride = vertexDesc->getVertexStride();
			meshDesc.points.data = meshData->getElementData(VES_POSITION);

			meshDesc.triangles.count = meshData->getNumIndices() / 3;
			meshDesc.flags |= PxMeshFlag::eFLIPNORMALS;

			IndexType indexType = meshData->getIndexType();
			if (indexType == IT_32BIT)
			{
				meshDesc.triangles.stride = 3 * sizeof(PxU32);
				meshDesc.triangles.data = meshData->getIndices32();
			}
			else
			{
				meshDesc.triangles.stride = 3 * sizeof(PxU16);
				meshDesc.triangles.data = meshData->getIndices16();
				meshDesc.flags |= PxMeshFlag::e16_BIT_INDICES;
			}

			PxDefaultMemoryOutputStream output;
			if (!cooking->cookTriangleMesh(meshDesc, output))
				return false;

			size = output.getSize();
			*data = (UINT8*)bs_alloc(size);

			memcpy(*data, output.getData(), size);
		}

		return true;
	}
	/**
	 * Attempts to cook a convex mesh from the provided mesh data. Assumes the mesh data is not null and contains vertex
	 * positions as well as face indices. If the method returns true the resulting convex mesh will be output in the @p
	 * data buffer, and its size in @p size. The data buffer will be allocated used the generic allocator and is up to the
	 * caller to free it.
	 */
	bool cookConvex(PxCooking* cooking, const SPtr<MeshData>& meshData, UINT8** data, UINT32& size)
	{
		SPtr<VertexDataDesc> vertexDesc = meshData->getVertexDesc();
		
		// Try to create hull from points
		PxConvexMeshDesc convexDesc;
		convexDesc.points.count = meshData->getNumVertices();
		convexDesc.points.stride = vertexDesc->getVertexStride();
		convexDesc.points.data = meshData->getElementData(VES_POSITION);
		convexDesc.flags |= PxConvexFlag::eCOMPUTE_CONVEX;

		PxDefaultMemoryOutputStream output;
		if (cooking->cookConvexMesh(convexDesc, output))
		{
			size = output.getSize();
			*data = (UINT8*)bs_alloc(size);

			memcpy(*data, output.getData(), size);
			return true;
		}

		// Try inflating the convex mesh
		convexDesc.flags |= PxConvexFlag::eINFLATE_CONVEX;
		if (cooking->cookConvexMesh(convexDesc, output))
		{
			size = output.getSize();
			*data = (UINT8*)bs_alloc(size);

			memcpy(*data, output.getData(), size);
			return true;
		}

		// Nothing works, just compute an AABB
		AABox box;

		auto vertIter = meshData->getVec3DataIter(VES_POSITION);
		do
		{
			box.merge(vertIter.getValue());
		}
		while (vertIter.moveNext());

		Vector3 aabbVerts[8];
		aabbVerts[0] = box.getCorner(AABox::FAR_LEFT_BOTTOM);
		aabbVerts[1] = box.getCorner(AABox::FAR_RIGHT_BOTTOM);
		aabbVerts[2] = box.getCorner(AABox::FAR_RIGHT_TOP);
		aabbVerts[3] = box.getCorner(AABox::FAR_LEFT_TOP);

		aabbVerts[4] = box.getCorner(AABox::NEAR_LEFT_BOTTOM);
		aabbVerts[5] = box.getCorner(AABox::NEAR_RIGHT_BOTTOM);
		aabbVerts[6] = box.getCorner(AABox::NEAR_RIGHT_TOP);
		aabbVerts[7] = box.getCorner(AABox::NEAR_LEFT_TOP);

		convexDesc.points.count = 8;
		convexDesc.points.stride = sizeof(Vector3);
		convexDesc.points.data = &aabbVerts[0];
		convexDesc.flags &= ~PxConvexFlag::eINFLATE_CONVEX;

		if (cooking->cookConvexMesh(convexDesc, output))
		{
			size = output.getSize();
			*data = (UINT8*)bs_alloc(size);

			memcpy(*data, output.getData(), size);
			return true;
		}

		return false;
	}