virtual bool CookConvex(FName Format, const TArray<FVector>& SrcBuffer, TArray<uint8>& OutBuffer, bool bDeformableMesh = false) const override
	{
#if WITH_PHYSX
		PxPlatform::Enum PhysXFormat = PxPlatform::ePC;
		bool bIsPhysXFormatValid = GetPhysXFormat(Format, PhysXFormat);
		check(bIsPhysXFormatValid);

		PxConvexMeshDesc PConvexMeshDesc;
		PConvexMeshDesc.points.data = SrcBuffer.GetData();
		PConvexMeshDesc.points.count = SrcBuffer.Num();
		PConvexMeshDesc.points.stride = sizeof(FVector);
		if (bDeformableMesh)
		{
			PConvexMeshDesc.flags = PxConvexFlag::eCOMPUTE_CONVEX | PxConvexFlag::eINFLATE_CONVEX;
		}
		else
		{
			PConvexMeshDesc.flags = PxConvexFlag::eCOMPUTE_CONVEX;
		}

		// Set up cooking
		const PxCookingParams Params = PhysXCooking->getParams();
		PxCookingParams NewParams = Params;
		NewParams.targetPlatform = PhysXFormat;
		if (bDeformableMesh)
		{
			// Meshes which can be deformed need different cooking parameters to inhibit vertex welding and add an extra skin around the collision mesh for safety.
			// We need to set the meshWeldTolerance to zero, even when disabling 'clean mesh' as PhysX will attempt to perform mesh cleaning anyway according to this meshWeldTolerance
			// if the convex hull is not well formed.
			// Set the skin thickness as a proportion of the overall size of the mesh as PhysX's internal tolerances also use the overall size to calculate the epsilon used.
			const FBox Bounds(SrcBuffer);
			const float MaxExtent = (Bounds.Max - Bounds.Min).Size();
			NewParams.skinWidth = MaxExtent / 512.0f;
			NewParams.meshPreprocessParams = PxMeshPreprocessingFlags(PxMeshPreprocessingFlag::eDISABLE_CLEAN_MESH);
			NewParams.areaTestEpsilon = 0.0f;
			NewParams.meshWeldTolerance = 0.0f;
			PhysXCooking->setParams(NewParams);
		}

		// Cook the convex mesh to a temp buffer
		TArray<uint8> CookedMeshBuffer;
		FPhysXOutputStream Buffer(&CookedMeshBuffer);
		bool Result = PhysXCooking->cookConvexMesh(PConvexMeshDesc, Buffer);
		
		// Return default cooking params to normal
		if (bDeformableMesh)
		{
			PhysXCooking->setParams(Params);
		}

		if( Result && CookedMeshBuffer.Num() > 0 )
		{
			// Append the cooked data into cooked buffer
			OutBuffer.Append( CookedMeshBuffer );
			return true;
		}
#endif		// WITH_PHYSX
		return false;
	}
Exemplo n.º 2
0
    virtual bool CookTriMesh(FName Format, int32 RuntimeCookFlags, const TArray<FVector>& SrcVertices, const TArray<FTriIndices>& SrcIndices, const TArray<uint16>& SrcMaterialIndices, const bool FlipNormals, TArray<uint8>& OutBuffer, bool bDeformableMesh = false) const override
    {
#if WITH_PHYSX
        PxPlatform::Enum PhysXFormat = PxPlatform::ePC;
        bool bIsPhysXFormatValid = GetPhysXFormat(Format, PhysXFormat);
        check(bIsPhysXFormatValid);

        PxTriangleMeshDesc PTriMeshDesc;
        PTriMeshDesc.points.data = SrcVertices.GetData();
        PTriMeshDesc.points.count = SrcVertices.Num();
        PTriMeshDesc.points.stride = sizeof(FVector);
        PTriMeshDesc.triangles.data = SrcIndices.GetData();
        PTriMeshDesc.triangles.count = SrcIndices.Num();
        PTriMeshDesc.triangles.stride = sizeof(FTriIndices);
        PTriMeshDesc.materialIndices.data = SrcMaterialIndices.GetData();
        PTriMeshDesc.materialIndices.stride = sizeof(PxMaterialTableIndex);
        PTriMeshDesc.flags = FlipNormals ? PxMeshFlag::eFLIPNORMALS : (PxMeshFlags)0;

        // Set up cooking
        const PxCookingParams& Params = PhysXCooking->getParams();
        PxCookingParams NewParams = Params;
        NewParams.targetPlatform = PhysXFormat;
        PxMeshPreprocessingFlags OldCookingFlags = NewParams.meshPreprocessParams;

        if (RuntimeCookFlags & ERuntimePhysxCookOptimizationFlags::SuppressFaceRemapTable)
        {
            NewParams.suppressTriangleMeshRemapTable = true;
        }

        if (bDeformableMesh)
        {
            // In the case of a deformable mesh, we have to change the cook params
            NewParams.meshPreprocessParams = PxMeshPreprocessingFlag::eDISABLE_CLEAN_MESH;
        }

        PhysXCooking->setParams(NewParams);


        // Cook TriMesh Data
        FPhysXOutputStream Buffer(&OutBuffer);
        bool Result = PhysXCooking->cookTriangleMesh(PTriMeshDesc, Buffer);

        if (bDeformableMesh)	//restore old params
        {
            NewParams.meshPreprocessParams = OldCookingFlags;
            PhysXCooking->setParams(NewParams);
        }
        return Result;
#else
        return false;
#endif		// WITH_PHYSX
    }
	virtual bool CookHeightField(FName Format, FIntPoint HFSize, float Thickness, const void* Samples, uint32 SamplesStride, TArray<uint8>& OutBuffer) const override
	{
#if WITH_PHYSX
		PxPlatform::Enum PhysXFormat = PxPlatform::ePC;
		bool bIsPhysXFormatValid = GetPhysXFormat(Format, PhysXFormat);
		check(bIsPhysXFormatValid);

		PxHeightFieldDesc HFDesc;
		HFDesc.format = PxHeightFieldFormat::eS16_TM;
		HFDesc.nbColumns = HFSize.X;
		HFDesc.nbRows = HFSize.Y;
		HFDesc.samples.data = Samples;
		HFDesc.samples.stride = SamplesStride;
		HFDesc.flags = PxHeightFieldFlag::eNO_BOUNDARY_EDGES;
		HFDesc.thickness = Thickness;

		// Set up cooking
		const PxCookingParams& Params = PhysXCooking->getParams();
		PxCookingParams NewParams = Params;
		NewParams.targetPlatform = PhysXFormat;
		PhysXCooking->setParams(NewParams);

		// Cook to a temp buffer
		TArray<uint8> CookedBuffer;
		FPhysXOutputStream Buffer(&CookedBuffer);

		if (PhysXCooking->cookHeightField(HFDesc, Buffer) && CookedBuffer.Num() > 0)
		{
			// Append the cooked data into cooked buffer
			OutBuffer.Append(CookedBuffer);
			return true;
		}
		return false;
#else
		return false;
#endif		// WITH_PHYSX
	}
Exemplo n.º 4
0
    virtual EPhysXCookingResult CookConvex(FName Format, int32 RuntimeCookFlags, const TArray<FVector>& SrcBuffer, TArray<uint8>& OutBuffer, bool bDeformableMesh = false) const override
    {
        EPhysXCookingResult CookResult = EPhysXCookingResult::Failed;

#if WITH_PHYSX
        PxPlatform::Enum PhysXFormat = PxPlatform::ePC;
        bool bIsPhysXFormatValid = GetPhysXFormat(Format, PhysXFormat);
        check(bIsPhysXFormatValid);

        PxConvexMeshDesc PConvexMeshDesc;
        PConvexMeshDesc.points.data = SrcBuffer.GetData();
        PConvexMeshDesc.points.count = SrcBuffer.Num();
        PConvexMeshDesc.points.stride = sizeof(FVector);
        PConvexMeshDesc.flags = PxConvexFlag::eCOMPUTE_CONVEX;

        // Set up cooking
        const PxCookingParams Params = PhysXCooking->getParams();
        PxCookingParams NewParams = Params;
        NewParams.targetPlatform = PhysXFormat;

        if(RuntimeCookFlags & ERuntimePhysxCookOptimizationFlags::SuppressFaceRemapTable)
        {
            NewParams.suppressTriangleMeshRemapTable = true;
        }

        if (bDeformableMesh)
        {
            // Meshes which can be deformed need different cooking parameters to inhibit vertex welding and add an extra skin around the collision mesh for safety.
            // We need to set the meshWeldTolerance to zero, even when disabling 'clean mesh' as PhysX will attempt to perform mesh cleaning anyway according to this meshWeldTolerance
            // if the convex hull is not well formed.
            // Set the skin thickness as a proportion of the overall size of the mesh as PhysX's internal tolerances also use the overall size to calculate the epsilon used.
            const FBox Bounds(SrcBuffer);
            const float MaxExtent = (Bounds.Max - Bounds.Min).Size();

            NewParams.meshPreprocessParams = PxMeshPreprocessingFlags(PxMeshPreprocessingFlag::eDISABLE_CLEAN_MESH);
            NewParams.meshWeldTolerance = 0.0f;
        }

        PhysXCooking->setParams(NewParams);

        // Cook the convex mesh to a temp buffer
        TArray<uint8> CookedMeshBuffer;
        FPhysXOutputStream Buffer(&CookedMeshBuffer);
        if (PhysXCooking->cookConvexMesh(PConvexMeshDesc, Buffer))
        {
            CookResult = EPhysXCookingResult::Succeeded;
        }
        else
        {
            if (!(PConvexMeshDesc.flags & PxConvexFlag::eINFLATE_CONVEX))
            {
                // We failed to cook without inflating convex. Let's try again with inflation
                //This is not ideal since it makes the collision less accurate. It's needed if given verts are extremely close.
                PConvexMeshDesc.flags |= PxConvexFlag::eINFLATE_CONVEX;
                if (PhysXCooking->cookConvexMesh(PConvexMeshDesc, Buffer))
                {
                    CookResult = EPhysXCookingResult::SucceededWithInflation;
                }
            }
        }

        // Return default cooking params to normal
        if (bDeformableMesh)
        {
            PhysXCooking->setParams(Params);
        }

        if (CookedMeshBuffer.Num() == 0)
        {
            CookResult = EPhysXCookingResult::Failed;
        }

        if (CookResult != EPhysXCookingResult::Failed)
        {
            // Append the cooked data into cooked buffer
            OutBuffer.Append( CookedMeshBuffer );
        }
#endif		// WITH_PHYSX

        return CookResult;
    }