You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
256 lines
6.7 KiB
C++
256 lines
6.7 KiB
C++
// Copyright 1998-2014 Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "Core.h"
|
|
#include "ModuleInterface.h"
|
|
#include "ModuleManager.h"
|
|
#include "Engine.h"
|
|
#include "PhysicsPublic.h"
|
|
#include "TargetPlatform.h"
|
|
#include "PhysXFormats.h"
|
|
|
|
static_assert(WITH_PHYSX, "No point in compiling PhysX cooker, if we don't have PhysX.");
|
|
|
|
static FName NAME_PhysXPC(TEXT("PhysXPC"));
|
|
static FName NAME_PhysXXboxOne(TEXT("PhysXXboxOne"));
|
|
static FName NAME_PhysXPS4(TEXT("PhysXPS4"));
|
|
|
|
/**
|
|
* FPhysXFormats. Cooks physics data.
|
|
**/
|
|
class FPhysXFormats : public IPhysXFormat
|
|
{
|
|
enum
|
|
{
|
|
/** Version for PhysX format, this becomes part of the DDC key. */
|
|
UE_PHYSX_PC_VER = 0,
|
|
};
|
|
|
|
PxCooking* PhysXCooking;
|
|
|
|
/**
|
|
* Validates format name and returns its PhysX enum value.
|
|
*
|
|
* @param InFormatName PhysX format name.
|
|
* @param OutFormat PhysX enum
|
|
* @return true if InFormatName is a valid and supported PhysX format
|
|
*/
|
|
bool GetPhysXFormat(FName InFormatName, PxPlatform::Enum& OutFormat) const
|
|
{
|
|
if ((InFormatName == NAME_PhysXPC) || (InFormatName == NAME_PhysXXboxOne) || (InFormatName == NAME_PhysXPS4))
|
|
{
|
|
OutFormat = PxPlatform::ePC;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Valudates PhysX format name.
|
|
*/
|
|
bool CheckPhysXFormat(FName InFormatName) const
|
|
{
|
|
PxPlatform::Enum PhysXFormat = PxPlatform::ePC;
|
|
return GetPhysXFormat(InFormatName, PhysXFormat);
|
|
}
|
|
|
|
public:
|
|
|
|
FPhysXFormats( PxCooking* InCooking )
|
|
: PhysXCooking( InCooking )
|
|
{}
|
|
|
|
virtual bool AllowParallelBuild() const
|
|
{
|
|
return false;
|
|
}
|
|
|
|
virtual uint16 GetVersion(FName Format) const override
|
|
{
|
|
check(CheckPhysXFormat(Format));
|
|
return UE_PHYSX_PC_VER;
|
|
}
|
|
|
|
|
|
virtual void GetSupportedFormats(TArray<FName>& OutFormats) const
|
|
{
|
|
OutFormats.Add(NAME_PhysXPC);
|
|
OutFormats.Add(NAME_PhysXXboxOne);
|
|
OutFormats.Add(NAME_PhysXPS4);
|
|
}
|
|
|
|
virtual bool CookConvex(FName Format, const TArray<FVector>& SrcBuffer, TArray<uint8>& OutBuffer) 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);
|
|
PConvexMeshDesc.flags = PxConvexFlag::eCOMPUTE_CONVEX;
|
|
|
|
// Set up cooking
|
|
const PxCookingParams& Params = PhysXCooking->getParams();
|
|
PxCookingParams NewParams = Params;
|
|
NewParams.targetPlatform = PhysXFormat;
|
|
PhysXCooking->setParams(NewParams);
|
|
|
|
// Cook the convex mesh to a temp buffer
|
|
TArray<uint8> CookedMeshBuffer;
|
|
FPhysXOutputStream Buffer(&CookedMeshBuffer);
|
|
bool Result = PhysXCooking->cookConvexMesh(PConvexMeshDesc, Buffer);
|
|
|
|
if( Result && CookedMeshBuffer.Num() > 0 )
|
|
{
|
|
// Append the cooked data into cooked buffer
|
|
OutBuffer.Append( CookedMeshBuffer );
|
|
return true;
|
|
}
|
|
#endif // WITH_PHYSX
|
|
return false;
|
|
}
|
|
|
|
virtual bool CookTriMesh(FName Format, const TArray<FVector>& SrcVertices, const TArray<FTriIndices>& SrcIndices, const TArray<uint16>& SrcMaterialIndices, const bool FlipNormals, TArray<uint8>& OutBuffer, bool bPerPolySkeletalMesh = 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 (bPerPolySkeletalMesh)
|
|
{
|
|
//per poly skeletal mesh requires deforming mesh. This is a very special case so 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 (bPerPolySkeletalMesh) //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
|
|
}
|
|
|
|
};
|
|
|
|
|
|
/**
|
|
* Module for PhysX cooking
|
|
*/
|
|
static IPhysXFormat* Singleton = NULL;
|
|
|
|
class FPhysXPlatformModule : public IPhysXFormatModule
|
|
{
|
|
public:
|
|
FPhysXPlatformModule()
|
|
{
|
|
|
|
}
|
|
|
|
virtual ~FPhysXPlatformModule()
|
|
{
|
|
ShutdownPhysXCooking();
|
|
|
|
delete Singleton;
|
|
Singleton = NULL;
|
|
}
|
|
virtual IPhysXFormat* GetPhysXFormat()
|
|
{
|
|
if (!Singleton)
|
|
{
|
|
InitPhysXCooking();
|
|
Singleton = new FPhysXFormats(GPhysXCooking);
|
|
}
|
|
return Singleton;
|
|
}
|
|
|
|
private:
|
|
|
|
/**
|
|
* Load the required modules for PhysX
|
|
*/
|
|
void InitPhysXCooking()
|
|
{
|
|
// Make sure PhysX libs are loaded
|
|
LoadPhysXModules();
|
|
}
|
|
|
|
void ShutdownPhysXCooking()
|
|
{
|
|
// Ideally PhysX cooking should be initialized in InitPhysXCooking and released here
|
|
// but Apex is still being setup in the engine and it also requires PhysX cooking singleton.
|
|
}
|
|
};
|
|
|
|
IMPLEMENT_MODULE( FPhysXPlatformModule, PhysXFormats );
|