1+ // ////////////////////////////////////////////////////////////////////////////////
2+ // Copyright (C) Inspiration Byte
3+ // 2009-2020
4+ // ////////////////////////////////////////////////////////////////////////////////
5+ // Description: Physics model cache for bullet physics
6+ // Generates real shapes for Bullet Collision
7+ // /////////////////////////////////////////////////////////////////////////////////
8+
9+ #include " core/core_common.h"
10+ #include " core/ConVar.h"
11+
12+ #include " DkJoltPCH.h"
13+ #include < Jolt/Physics/Collision/Shape/ConvexHullShape.h>
14+ #include < Jolt/Physics/Collision/Shape/MeshShape.h>
15+
16+ #include " DkJoltShapeCache.h"
17+ #include " egf/physmodel.h"
18+
19+ static Threading::CEqMutex s_shapeCacheMutex;
20+
21+ DECLARE_CVAR (ph_studioShapeMargin, " 0.05" , " Studio model shape marginal" , CV_CHEAT); // same as JPH::cDefaultConvexRadius
22+
23+ // makes and caches shape. IsConvex defines that it was convex or not (also for internal use)
24+ static JPH::Ref<JPH::Shape> jphGenerateCollisionShape (ArrayCRef<Vector3D> vertices, ArrayCRef<int > indices, EPhysShapeType type)
25+ {
26+ const float margin = ph_studioShapeMargin.GetFloat ();
27+
28+ switch (type)
29+ {
30+ case PHYSSHAPE_TYPE_CONCAVE:
31+ case PHYSSHAPE_TYPE_MOVABLECONCAVE:
32+ {
33+ JPH::VertexList jphVertList;
34+ JPH::IndexedTriangleList jphTriList;
35+ jphVertList.reserve (vertices.numElem ());
36+
37+ for (int i = 0 ; i < vertices.numElem (); ++i)
38+ jphVertList.push_back (Convert::ToFloat3 (vertices[i]));
39+
40+ jphTriList.reserve (indices.numElem () / 3 );
41+ for (int i = 0 ; i < indices.numElem (); i += 3 )
42+ {
43+ JPH::IndexedTriangle jphTri (indices[i], indices[i + 1 ], indices[i + 2 ]);
44+ jphTriList.push_back (jphTri);
45+ }
46+
47+ JPH::MeshShapeSettings jphMeshSettings (jphVertList, jphTriList);
48+ auto jphResult = jphMeshSettings.Create ();
49+ return jphResult.Get ();
50+ }
51+ case PHYSSHAPE_TYPE_CONVEX:
52+ {
53+ JPH::Array<JPH::Vec3> jphVertList;
54+ jphVertList.reserve (vertices.numElem ());
55+ for (int i = 0 ; i < vertices.numElem (); ++i)
56+ jphVertList.push_back (Convert::ToVec3 (vertices[i]));
57+
58+ JPH::ConvexHullShapeSettings jphHullSettings (jphVertList, ph_studioShapeMargin.GetFloat ());
59+ auto jphResult = jphHullSettings.Create ();
60+ return jphResult.Get ();
61+ }
62+ }
63+
64+ MsgError (" InternalGenerateShape: Shape type %d is invalid!\n " , type);
65+
66+ return nullptr ;
67+ }
68+
69+ bool CDkJoltStudioShapeCache::IsInitialized () const
70+ {
71+ return true ;
72+ }
73+
74+ // checks the shape is initialized for the cache
75+ bool CDkJoltStudioShapeCache::IsShapeCachePresent ( StudioPhyShapeData& shapeInfo )
76+ {
77+ using namespace Threading ;
78+ CScopedMutex m (s_shapeCacheMutex);
79+ if (arrayFindIndex (m_collisionShapes, reinterpret_cast <JPH::Shape*>(shapeInfo.cacheRef )) != -1 )
80+ return true ;
81+
82+ return false ;
83+ }
84+
85+ // initializes whole studio shape model with all objects
86+ void CDkJoltStudioShapeCache::InitStudioCache (StudioPhysData& studioData)
87+ {
88+ using namespace Threading ;
89+
90+ for (StudioPhyShapeData& shapeData : studioData.shapes )
91+ {
92+ const physgeominfo_t & shapeInfo = shapeData.desc ;
93+
94+ JPH::Ref<JPH::Shape> shape = jphGenerateCollisionShape (
95+ studioData.vertices ,
96+ ArrayCRef (studioData.indices .ptr () + shapeInfo.startIndices , shapeInfo.numIndices ),
97+ static_cast <EPhysShapeType>(shapeInfo.type ));
98+
99+ {
100+ CScopedMutex m (s_shapeCacheMutex);
101+ m_collisionShapes.append (shape);
102+ shapeData.cacheRef = shape;
103+ }
104+ }
105+
106+ for (StudioPhyObjData& obj : studioData.objects )
107+ {
108+ for (int i = 0 ; i < obj.desc .numShapes ; ++i)
109+ obj.shapeCacheRefs [i] = studioData.shapes [obj.desc .shapeIndex [i]].cacheRef ;
110+ }
111+ }
112+
113+ void CDkJoltStudioShapeCache::DestroyStudioCache (StudioPhysData& studioData)
114+ {
115+ using namespace Threading ;
116+
117+ for (StudioPhyShapeData& shapeData : studioData.shapes )
118+ {
119+ CScopedMutex m (s_shapeCacheMutex);
120+ const int shapeIdx = arrayFindIndex (m_collisionShapes, reinterpret_cast <JPH::Shape*>(shapeData.cacheRef ));
121+ if (shapeIdx == -1 )
122+ continue ;
123+
124+ m_collisionShapes.fastRemoveIndex (shapeIdx);
125+ }
126+ }
127+
128+ // does all shape cleanup
129+ void CDkJoltStudioShapeCache::Cleanup_Invalidate ()
130+ {
131+ using namespace Threading ;
132+
133+ CScopedMutex m (s_shapeCacheMutex);
134+ m_collisionShapes.clear (true );
135+ }
0 commit comments