Files
Michael Lentine f9b3324b32 Copying //UE4/Dev-Physics to Dev-Main (//UE4/Dev-Main) @ 6903150
#rb none
#rnx

[CL 6903163 by Michael Lentine in Main branch]
2019-06-08 17:15:34 -04:00

187 lines
14 KiB
C++

// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved.
#pragma once
#include "Misc/Build.h"
#if INCLUDE_CHAOS && !(UE_BUILD_SHIPPING || UE_BUILD_TEST)
#include "Containers/StaticBitArray.h"
#include "Chaos/ArrayCollectionArray.h"
#include "Chaos/ImplicitObject.h"
#include "Chaos/Matrix.h"
#include "Chaos/UniformGrid.h"
#include "Chaos/PBDRigidClustering.h"
#include "Chaos/Framework/BufferedData.h"
class FChaosSolversModule;
namespace Chaos { class FPBDRigidsSolver; }
template<class InElementType> class TManagedArray;
/** Enumeration of the synchronizable data. */
enum class EGeometryCollectionParticlesData : uint8
{
X,
R,
Geometry,
GeometryType,
GeometryIsConvex,
GeometryHasBoundingBox,
GeometryBoxMin,
GeometryBoxMax,
GeometrySphereCenter,
GeometrySphereRadius,
GeometryLevelSetGrid,
V,
W,
F,
Torque,
I,
InvI,
M,
InvM,
CollisionParticlesSize,
Disabled,
Sleeping,
Island,
P,
Q,
PreV,
PreW,
ConnectivityEdges,
ChildToParentMap,
Count
};
/**
Object holding selected particles data for a specific range of rigid body ids.
Use SetDataSyncFlag, SetAllDataSyncFlag, or RequestSyncedData to have the required data made available at the next tick.
Each time Sync is called, the particles' data is copied and the sync flags cleared.
Use HasSyncedData or RequestSyncedData to check which data is available at any one time.
*/
template<class T, int d>
class TGeometryCollectionParticlesData
{
public:
/** Constructor. */
TGeometryCollectionParticlesData();
/** Set this data type to copy at the next sync. */
void SetDataSyncFlag(EGeometryCollectionParticlesData Data) const { BufferedData.GetGameDataForRead().SetDataSyncFlag(Data); }
/** Set all data type to copy at the next sync. */
void SetAllDataSyncFlag() const { BufferedData.GetGameDataForRead().SetAllDataSyncFlag(); }
/** Return whether the specified type of data has been copied during the last sync. */
bool HasSyncedData(EGeometryCollectionParticlesData Data) const { return BufferedData.GetGameDataForRead().HasSyncedData(Data); }
/** Shorthand for both setting the flag and checking the data has already been synced. */
bool RequestSyncedData(EGeometryCollectionParticlesData Data) const { SetDataSyncFlag(Data); return HasSyncedData(Data); }
/** Copy the data of the specified set of particles/rigid body ids to this object. */
void Sync(const Chaos::FPBDRigidsSolver* Solver, const TManagedArray<int32>& RigidBodyIds);
const Chaos::TVector<T, d> & GetX (int32 Index) const { check(HasSyncedData(EGeometryCollectionParticlesData::X )); return BufferedData.GetGameDataForRead().X [Index]; }
const Chaos::TRotation<T, d> & GetR (int32 Index) const { check(HasSyncedData(EGeometryCollectionParticlesData::R )); return BufferedData.GetGameDataForRead().R [Index]; }
const Chaos::TImplicitObject<T, d>* const& GetGeometry (int32 Index) const { check(HasSyncedData(EGeometryCollectionParticlesData::Geometry )); return BufferedData.GetGameDataForRead().Geometry [Index]; }
const Chaos::ImplicitObjectType & GetGeometryType (int32 Index) const { check(HasSyncedData(EGeometryCollectionParticlesData::GeometryType )); return BufferedData.GetGameDataForRead().GeometryType [Index]; }
const bool & IsGeometryConvex (int32 Index) const { check(HasSyncedData(EGeometryCollectionParticlesData::GeometryIsConvex )); return BufferedData.GetGameDataForRead().GeometryIsConvex [Index]; }
const bool & HasGeometryBoundingBoxm (int32 Index) const { check(HasSyncedData(EGeometryCollectionParticlesData::GeometryHasBoundingBox)); return BufferedData.GetGameDataForRead().GeometryHasBoundingBox[Index]; }
const Chaos::TVector<T, d> & GetGeometryBoxMin (int32 Index) const { check(HasSyncedData(EGeometryCollectionParticlesData::GeometryBoxMin )); return BufferedData.GetGameDataForRead().GeometryBoxMin [Index]; }
const Chaos::TVector<T, d> & GetGeometryBoxMax (int32 Index) const { check(HasSyncedData(EGeometryCollectionParticlesData::GeometryBoxMax )); return BufferedData.GetGameDataForRead().GeometryBoxMax [Index]; }
const Chaos::TVector<T, d> & GetGeometrySphereCenter (int32 Index) const { check(HasSyncedData(EGeometryCollectionParticlesData::GeometrySphereCenter )); return BufferedData.GetGameDataForRead().GeometrySphereCenter [Index]; }
const T & GetGeometrySphereRadius (int32 Index) const { check(HasSyncedData(EGeometryCollectionParticlesData::GeometrySphereRadius )); return BufferedData.GetGameDataForRead().GeometrySphereRadius [Index]; }
const Chaos::TUniformGrid<T, d> & GetGeometryLevelSetGrid (int32 Index) const { check(HasSyncedData(EGeometryCollectionParticlesData::GeometryLevelSetGrid )); return BufferedData.GetGameDataForRead().GeometryLevelSetGrid [Index]; }
const Chaos::TVector<T, d> & GetV (int32 Index) const { check(HasSyncedData(EGeometryCollectionParticlesData::V )); return BufferedData.GetGameDataForRead().V [Index]; }
const Chaos::TVector<T, d> & GetW (int32 Index) const { check(HasSyncedData(EGeometryCollectionParticlesData::W )); return BufferedData.GetGameDataForRead().W [Index]; }
const Chaos::TVector<T, d> & GetF (int32 Index) const { check(HasSyncedData(EGeometryCollectionParticlesData::F )); return BufferedData.GetGameDataForRead().F [Index]; }
const Chaos::TVector<T, d> & GetTorque (int32 Index) const { check(HasSyncedData(EGeometryCollectionParticlesData::Torque )); return BufferedData.GetGameDataForRead().Torque [Index]; }
const Chaos::PMatrix<T, d, d> & GetI (int32 Index) const { check(HasSyncedData(EGeometryCollectionParticlesData::I )); return BufferedData.GetGameDataForRead().I [Index]; }
const Chaos::PMatrix<T, d, d> & GetInvI (int32 Index) const { check(HasSyncedData(EGeometryCollectionParticlesData::InvI )); return BufferedData.GetGameDataForRead().InvI [Index]; }
const T & GetM (int32 Index) const { check(HasSyncedData(EGeometryCollectionParticlesData::M )); return BufferedData.GetGameDataForRead().M [Index]; }
const T & GetInvM (int32 Index) const { check(HasSyncedData(EGeometryCollectionParticlesData::InvM )); return BufferedData.GetGameDataForRead().InvM [Index]; }
const int32 & GetCollisionParticlesSize(int32 Index) const { check(HasSyncedData(EGeometryCollectionParticlesData::CollisionParticlesSize)); return BufferedData.GetGameDataForRead().CollisionParticlesSize[Index]; }
const bool & IsDisabled (int32 Index) const { check(HasSyncedData(EGeometryCollectionParticlesData::Disabled )); return BufferedData.GetGameDataForRead().Disabled [Index]; }
const bool & IsSleeping (int32 Index) const { check(HasSyncedData(EGeometryCollectionParticlesData::Sleeping )); return BufferedData.GetGameDataForRead().Sleeping [Index]; }
const int32 & GetIsland (int32 Index) const { check(HasSyncedData(EGeometryCollectionParticlesData::Island )); return BufferedData.GetGameDataForRead().Island [Index]; }
const Chaos::TVector<T, d> & GetP (int32 Index) const { check(HasSyncedData(EGeometryCollectionParticlesData::P )); return BufferedData.GetGameDataForRead().P [Index]; }
const Chaos::TRotation<T, d> & GetQ (int32 Index) const { check(HasSyncedData(EGeometryCollectionParticlesData::Q )); return BufferedData.GetGameDataForRead().Q [Index]; }
const Chaos::TVector<T, d> & GetPreV (int32 Index) const { check(HasSyncedData(EGeometryCollectionParticlesData::PreV )); return BufferedData.GetGameDataForRead().PreV [Index]; }
const Chaos::TVector<T, d> & GetPreW (int32 Index) const { check(HasSyncedData(EGeometryCollectionParticlesData::PreW )); return BufferedData.GetGameDataForRead().PreW [Index]; }
const TArray<Chaos::TConnectivityEdge<T>>& GetConnectivityEdges (int32 Index) const { check(HasSyncedData(EGeometryCollectionParticlesData::ConnectivityEdges )); return BufferedData.GetGameDataForRead().ConnectivityEdges [Index]; }
const Chaos::TRigidTransform<T, d> & GetChildToParentMap (int32 Index) const { check(HasSyncedData(EGeometryCollectionParticlesData::ChildToParentMap )); return BufferedData.GetGameDataForRead().ChildToParentMap [Index]; }
/** Return a string with the entire set of value for the synced data of the specified particle. */
FString ToString(int32 Index, const TCHAR* Separator = TEXT(", ")) const { return BufferedData.GetGameDataForRead().ToString(Index, Separator); }
private:
/** Data bit selection type. */
typedef TStaticBitArray<uint32(EGeometryCollectionParticlesData::Count)> FDataFlags;
/** Structure used to exchange data between game and physics thread. */
struct FData
{
mutable FDataFlags RequiredDataFlags; // Mutable in order to allow const versions of all of this object's methods outside of the Sync process.
FDataFlags SyncedDataFlags;
Chaos::TArrayCollectionArray<Chaos::TVector<T, d> > X;
Chaos::TArrayCollectionArray<Chaos::TRotation<T, d> > R;
Chaos::TArrayCollectionArray<const Chaos::TImplicitObject<T, d>*> Geometry;
Chaos::TArrayCollectionArray<Chaos::ImplicitObjectType > GeometryType;
Chaos::TArrayCollectionArray<bool > GeometryIsConvex;
Chaos::TArrayCollectionArray<bool > GeometryHasBoundingBox;
Chaos::TArrayCollectionArray<Chaos::TVector<T, d> > GeometryBoxMin;
Chaos::TArrayCollectionArray<Chaos::TVector<T, d> > GeometryBoxMax;
Chaos::TArrayCollectionArray<Chaos::TVector<T, d> > GeometrySphereCenter;
Chaos::TArrayCollectionArray<T > GeometrySphereRadius;
Chaos::TArrayCollectionArray<Chaos::TUniformGrid<T, d> > GeometryLevelSetGrid;
Chaos::TArrayCollectionArray<Chaos::TVector<T, d> > V;
Chaos::TArrayCollectionArray<Chaos::TVector<T, d> > W;
Chaos::TArrayCollectionArray<Chaos::TVector<T, d> > F;
Chaos::TArrayCollectionArray<Chaos::TVector<T, d> > Torque;
Chaos::TArrayCollectionArray<Chaos::PMatrix<T, d, d> > I;
Chaos::TArrayCollectionArray<Chaos::PMatrix<T, d, d> > InvI;
Chaos::TArrayCollectionArray<T > M;
Chaos::TArrayCollectionArray<T > InvM;
Chaos::TArrayCollectionArray<int32 > CollisionParticlesSize;
Chaos::TArrayCollectionArray<bool > Disabled;
Chaos::TArrayCollectionArray<bool > Sleeping;
Chaos::TArrayCollectionArray<int32 > Island;
Chaos::TArrayCollectionArray<Chaos::TVector<T, d> > P;
Chaos::TArrayCollectionArray<Chaos::TRotation<T, d> > Q;
Chaos::TArrayCollectionArray<Chaos::TVector<T, d> > PreV;
Chaos::TArrayCollectionArray<Chaos::TVector<T, d> > PreW;
Chaos::TArrayCollectionArray<TArray<Chaos::TConnectivityEdge<T>>> ConnectivityEdges;
Chaos::TArrayCollectionArray<Chaos::TRigidTransform<T, d> > ChildToParentMap;
/** Set this data type to copy at the next sync. */
void SetDataSyncFlag(EGeometryCollectionParticlesData Data) const { RequiredDataFlags[uint32(Data)] = true; }
/** Set all data type to copy at the next sync. */
void SetAllDataSyncFlag() const;
/** Return whether the specified type of data has been copied during the last sync. */
bool HasSyncedData(EGeometryCollectionParticlesData Data) const { return SyncedDataFlags[uint32(Data)]; }
/** Deallocate the array containing the specified particle information. */
void Reset(EGeometryCollectionParticlesData Data);
/** Copy the specified particle information for the specified range of rigid body id. */
void Copy(EGeometryCollectionParticlesData Data, const Chaos::FPBDRigidsSolver* Solver, const TManagedArray<int32>& RigidBodyIds);
/** Return a string with the entire set of value for the synced data of the specified particle. */
FString ToString(int32 Index, const TCHAR* Separator) const;
};
const FChaosSolversModule* ChaosModule;
Chaos::TBufferedData<FData> BufferedData;
FThreadSafeCounter PhysicsSyncCount;
int32 GameSyncCount;
uint64 SyncFrame;
};
/** Current Chaos particles syncer type. */
typedef TGeometryCollectionParticlesData<float, 3> FGeometryCollectionParticlesData;
#endif // #if INCLUDE_CHAOS && !(UE_BUILD_SHIPPING || UE_BUILD_TEST)