Files
UnrealEngineUWP/Engine/Source/Runtime/Experimental/GeometryCollectionEngine/Public/GeometryCollection/GeometryCollectionParticlesData.h
Max Chen e4d4965491 Merging //UE4/Dev-Main to Dev-Editor (//UE4/Dev-Editor)
#rb none

[CL 7774443 by Max Chen in Dev-Editor branch]
2019-08-05 15:48:51 -04:00

189 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"
#include "Chaos/Declares.h"
class FChaosSolversModule;
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::FPhysicsSolver* 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::FPhysicsSolver* 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;
};
extern template class TGeometryCollectionParticlesData<float, 3>;
/** Current Chaos particles syncer type. */
typedef TGeometryCollectionParticlesData<float, 3> FGeometryCollectionParticlesData;
#endif // #if INCLUDE_CHAOS && !(UE_BUILD_SHIPPING || UE_BUILD_TEST)