Panda3D
physxMeshPool.cxx
1 // Filename: physxMeshPool.cxx
2 // Created by: enn0x (14Oct09)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #include "physxMeshPool.h"
16 #include "physxConvexMesh.h"
17 #include "physxTriangleMesh.h"
18 #include "physxClothMesh.h"
19 #include "physxSoftBodyMesh.h"
20 
21 #include "physxFileStream.h"
22 #include "virtualFileSystem.h"
23 
24 PhysxMeshPool::ConvexMeshes PhysxMeshPool::_convex_meshes;
25 PhysxMeshPool::TriangleMeshes PhysxMeshPool::_triangle_meshes;
26 PhysxMeshPool::ClothMeshes PhysxMeshPool::_cloth_meshes;
27 PhysxMeshPool::SoftbodyMeshes PhysxMeshPool::_softbody_meshes;
28 
29 ////////////////////////////////////////////////////////////////////
30 // Function: PhysxMeshPool::check_file
31 // Access: Private
32 // Description:
33 ////////////////////////////////////////////////////////////////////
34 bool PhysxMeshPool::
35 check_filename(const Filename &fn) {
36 
37  if (!(VirtualFileSystem::get_global_ptr()->exists(fn))) {
38  physx_cat.error() << "File does not exists: " << fn << endl;
39  return false;
40  }
41 
42  if (!(VirtualFileSystem::get_global_ptr()->is_regular_file(fn))) {
43  physx_cat.error() << "Not a regular file: " << fn << endl;
44  return false;
45  }
46 
47  return true;
48 }
49 
50 ////////////////////////////////////////////////////////////////////
51 // Function: PhysxMeshPool::load_convex_mesh
52 // Access: Published
53 // Description:
54 ////////////////////////////////////////////////////////////////////
55 PhysxConvexMesh *PhysxMeshPool::
56 load_convex_mesh(const Filename &fn) {
57 
58  if (!check_filename(fn)) return NULL;
59 
60  PhysxConvexMesh *mesh;
61 
62  ConvexMeshes::iterator it = _convex_meshes.find(fn);
63  if (it == _convex_meshes.end()) {
64  // Not found; load mesh.
65  NxConvexMesh *meshPtr;
66  PhysxFileStream stream = PhysxFileStream(fn, true);
67 
68  mesh = new PhysxConvexMesh();
69  nassertr_always(mesh, NULL);
70 
71  NxPhysicsSDK *sdk = NxGetPhysicsSDK();
72  nassertr_always(sdk, NULL);
73 
74  meshPtr = sdk->createConvexMesh(stream);
75  nassertr_always(meshPtr, NULL);
76 
77  mesh->link(meshPtr);
78 
79  _convex_meshes.insert(ConvexMeshes::value_type(fn, mesh));
80  }
81  else {
82  // Found; return previously loaded mesh.
83  mesh = (*it).second;
84  }
85 
86  return mesh;
87 }
88 
89 ////////////////////////////////////////////////////////////////////
90 // Function: PhysxMeshPool::load_triangle_mesh
91 // Access: Published
92 // Description:
93 ////////////////////////////////////////////////////////////////////
94 PhysxTriangleMesh *PhysxMeshPool::
95 load_triangle_mesh(const Filename &fn) {
96 
97  if (!check_filename(fn)) return NULL;
98 
99  PhysxTriangleMesh *mesh;
100 
101  TriangleMeshes::iterator it = _triangle_meshes.find(fn);
102  if (it == _triangle_meshes.end()) {
103  // Not found; load mesh.
104  NxTriangleMesh *meshPtr;
105  PhysxFileStream stream = PhysxFileStream(fn, true);
106 
107  mesh = new PhysxTriangleMesh();
108  nassertr_always(mesh, NULL);
109 
110  NxPhysicsSDK *sdk = NxGetPhysicsSDK();
111  nassertr_always(sdk, NULL);
112 
113  meshPtr = sdk->createTriangleMesh(stream);
114  nassertr_always(meshPtr, NULL);
115 
116  mesh->link(meshPtr);
117 
118  _triangle_meshes.insert(TriangleMeshes::value_type(fn, mesh));
119  }
120  else {
121  // Found; return previously loaded mesh.
122  mesh = (*it).second;
123  }
124 
125  return mesh;
126 }
127 
128 ////////////////////////////////////////////////////////////////////
129 // Function: PhysxMeshPool::load_cloth_mesh
130 // Access: Published
131 // Description:
132 ////////////////////////////////////////////////////////////////////
133 PhysxClothMesh *PhysxMeshPool::
134 load_cloth_mesh(const Filename &fn) {
135 
136  if (!check_filename(fn)) return NULL;
137 
138  PhysxClothMesh *mesh;
139 
140  ClothMeshes::iterator it = _cloth_meshes.find(fn);
141  if (it == _cloth_meshes.end()) {
142  // Not found; load mesh.
143  NxClothMesh *meshPtr;
144  PhysxFileStream stream = PhysxFileStream(fn, true);
145 
146  mesh = new PhysxClothMesh();
147  nassertr_always(mesh, NULL);
148 
149  NxPhysicsSDK *sdk = NxGetPhysicsSDK();
150  nassertr_always(sdk, NULL);
151 
152  meshPtr = sdk->createClothMesh(stream);
153  nassertr_always(meshPtr, NULL);
154 
155  mesh->link(meshPtr);
156 
157  _cloth_meshes.insert(ClothMeshes::value_type(fn, mesh));
158  }
159  else {
160  // Found; return previously loaded mesh.
161  mesh = (*it).second;
162  }
163 
164  return mesh;
165 }
166 
167 ////////////////////////////////////////////////////////////////////
168 // Function: PhysxMeshPool::load_soft_body_mesh
169 // Access: Published
170 // Description:
171 ////////////////////////////////////////////////////////////////////
172 PhysxSoftBodyMesh *PhysxMeshPool::
173 load_soft_body_mesh(const Filename &fn) {
174 
175  if (!check_filename(fn)) return NULL;
176 
177  PhysxSoftBodyMesh *mesh;
178 
179  SoftbodyMeshes::iterator it = _softbody_meshes.find(fn);
180  if (it == _softbody_meshes.end()) {
181  // Not found; load mesh.
182  NxSoftBodyMesh *meshPtr;
183  PhysxFileStream stream = PhysxFileStream(fn, true);
184 
185  mesh = new PhysxSoftBodyMesh();
186  nassertr_always(mesh, NULL);
187 
188  NxPhysicsSDK *sdk = NxGetPhysicsSDK();
189  nassertr_always(sdk, NULL);
190 
191  meshPtr = sdk->createSoftBodyMesh(stream);
192  nassertr_always(meshPtr, NULL);
193 
194  mesh->link(meshPtr);
195 
196  _softbody_meshes.insert(SoftbodyMeshes::value_type(fn, mesh));
197  }
198  else {
199  // Found; return previously loaded mesh.
200  mesh = (*it).second;
201  }
202 
203  return mesh;
204 }
205 
206 ////////////////////////////////////////////////////////////////////
207 // Function: PhysxMeshPool::release_convex_mesh
208 // Access: Published
209 // Description:
210 ////////////////////////////////////////////////////////////////////
211 bool PhysxMeshPool::
212 release_convex_mesh(PhysxConvexMesh *mesh) {
213 
214  ConvexMeshes::iterator it;
215  for (it=_convex_meshes.begin(); it != _convex_meshes.end(); ++it) {
216  if (mesh == (*it).second) {
217  _convex_meshes.erase(it);
218  return true;
219  }
220  }
221 
222  return false;
223 }
224 
225 ////////////////////////////////////////////////////////////////////
226 // Function: PhysxMeshPool::release_triangle_mesh
227 // Access: Published
228 // Description:
229 ////////////////////////////////////////////////////////////////////
230 bool PhysxMeshPool::
231 release_triangle_mesh(PhysxTriangleMesh *mesh) {
232 
233  TriangleMeshes::iterator it;
234  for (it=_triangle_meshes.begin(); it != _triangle_meshes.end(); ++it) {
235  if (mesh == (*it).second) {
236  _triangle_meshes.erase(it);
237  return true;
238  }
239  }
240 
241  return false;
242 }
243 
244 ////////////////////////////////////////////////////////////////////
245 // Function: PhysxMeshPool::release_cloth_mesh
246 // Access: Published
247 // Description:
248 ////////////////////////////////////////////////////////////////////
249 bool PhysxMeshPool::
250 release_cloth_mesh(PhysxClothMesh *mesh) {
251 
252  ClothMeshes::iterator it;
253  for (it=_cloth_meshes.begin(); it != _cloth_meshes.end(); ++it) {
254  if (mesh == (*it).second) {
255  _cloth_meshes.erase(it);
256  return true;
257  }
258  }
259 
260  return false;
261 }
262 
263 ////////////////////////////////////////////////////////////////////
264 // Function: PhysxMeshPool::release_soft_body_mesh
265 // Access: Published
266 // Description:
267 ////////////////////////////////////////////////////////////////////
268 bool PhysxMeshPool::
269 release_soft_body_mesh(PhysxSoftBodyMesh *mesh) {
270 
271  SoftbodyMeshes::iterator it;
272  for (it=_softbody_meshes.begin(); it != _softbody_meshes.end(); ++it) {
273  if (mesh == (*it).second) {
274  _softbody_meshes.erase(it);
275  return true;
276  }
277  }
278 
279  return false;
280 }
281 
282 ////////////////////////////////////////////////////////////////////
283 // Function: PhysxMeshPool::list_content
284 // Access: Published
285 // Description:
286 ////////////////////////////////////////////////////////////////////
287 void PhysxMeshPool::
288 list_contents() {
289  list_contents(nout);
290 }
291 
292 ////////////////////////////////////////////////////////////////////
293 // Function: PhysxMeshPool::list_content
294 // Access: Published
295 // Description:
296 ////////////////////////////////////////////////////////////////////
297 void PhysxMeshPool::
298 list_contents(ostream &out) {
299 
300  out << "PhysX mesh pool contents:\n";
301 
302  // Convex meshes
303  {
304  ConvexMeshes::const_iterator it;
305  for (it=_convex_meshes.begin(); it != _convex_meshes.end(); ++it) {
306  Filename fn = (*it).first;
307  PhysxConvexMesh *mesh = (*it).second;
308 
309  out << " " << fn.get_fullpath()
310  << " (convex mesh, " << mesh->ptr()->getReferenceCount()
311  << " references)" << endl;
312  }
313  }
314 
315  // Triangle meshes
316  {
317  TriangleMeshes::const_iterator it;
318  for (it=_triangle_meshes.begin(); it != _triangle_meshes.end(); ++it) {
319  Filename fn = (*it).first;
320  PhysxTriangleMesh *mesh = (*it).second;
321 
322  out << " " << fn.get_fullpath()
323  << " (triangle mesh, " << mesh->ptr()->getReferenceCount()
324  << " references)\n";
325  }
326  }
327 
328  // Cloth meshes
329  {
330  ClothMeshes::const_iterator it;
331  for (it=_cloth_meshes.begin(); it != _cloth_meshes.end(); ++it) {
332  Filename fn = (*it).first;
333  PhysxClothMesh *mesh = (*it).second;
334 
335  out << " " << fn.get_fullpath()
336  << " (cloth mesh, " << mesh->ptr()->getReferenceCount()
337  << " references)\n";
338  }
339  }
340 
341  // Soft body meshes
342  {
343  SoftbodyMeshes::const_iterator it;
344  for (it=_softbody_meshes.begin(); it != _softbody_meshes.end(); ++it) {
345  Filename fn = (*it).first;
346  PhysxSoftBodyMesh *mesh = (*it).second;
347 
348  out << " " << fn.get_fullpath()
349  << " (soft body mesh, " << mesh->ptr()->getReferenceCount()
350  << " references)\n";
351  }
352  }
353 
354  // Summary
355  NxPhysicsSDK *sdk = NxGetPhysicsSDK();
356 
357  out << " Total number of convex meshes: " << sdk->getNbConvexMeshes()
358  << " created, " << _convex_meshes.size() << " registred\n";
359 
360  out << " Total number of triangle meshes: " << sdk->getNbTriangleMeshes()
361  << " created, " << _triangle_meshes.size() << " registred\n";
362 
363  out << " Total number of cloth meshes: " << sdk->getNbClothMeshes()
364  << " created, " << _cloth_meshes.size() << " registred\n";
365 
366  out << " Total number of soft body meshes: " << sdk->getNbSoftBodyMeshes()
367  << " created, " << _softbody_meshes.size() << " registred\n";
368 }
369 
This is our own Panda specialization on the default STL map.
Definition: pmap.h:52
string get_fullpath() const
Returns the entire filename: directory, basename, extension.
Definition: filename.I:398
The name of a file, such as a texture file or an Egg file.
Definition: filename.h:44
static VirtualFileSystem * get_global_ptr()
Returns the default global VirtualFileSystem.
A Convex Mesh.