Panda3D
bulletTriangleMeshShape.cxx
Go to the documentation of this file.
1 /**
2  * PANDA 3D SOFTWARE
3  * Copyright (c) Carnegie Mellon University. All rights reserved.
4  *
5  * All use of this software is subject to the terms of the revised BSD
6  * license. You should have received a copy of this license along
7  * with this source code in a file named "LICENSE."
8  *
9  * @file bulletTriangleMeshShape.cxx
10  * @author enn0x
11  * @date 2010-02-09
12  */
13 
15 
16 #include "config_bullet.h"
17 
18 #include "bulletTriangleMesh.h"
19 #include "bulletWorld.h"
20 
21 #include "nodePathCollection.h"
22 #include "geomNode.h"
23 #include "geomVertexReader.h"
24 
25 TypeHandle BulletTriangleMeshShape::_type_handle;
26 
27 /**
28  * Only used by make_from_bam.
29  */
30 BulletTriangleMeshShape::
31 BulletTriangleMeshShape() :
32  _mesh(nullptr),
33  _gimpact_shape(nullptr),
34  _bvh_shape(nullptr),
35  _dynamic(false),
36  _compress(false),
37  _bvh(false) {
38 }
39 
40 /**
41  * The parameters 'compress' and 'bvh' are only used if 'dynamic' is set to
42  * FALSE.
43  * Assumes the lock(bullet global lock) is held by the caller
44  */
45 BulletTriangleMeshShape::
46 BulletTriangleMeshShape(BulletTriangleMesh *mesh, bool dynamic, bool compress, bool bvh) :
47  _dynamic(dynamic),
48  _compress(compress),
49  _bvh(bvh) {
50 
51  // Assert that mesh is not NULL
52  if (!mesh) {
53  bullet_cat.warning() << "mesh is NULL! creating new mesh." << std::endl;
54  mesh = new BulletTriangleMesh();
55  }
56 
57  // Assert that mesh has at least one triangle
58  if (mesh->do_get_num_triangles() == 0) {
59  bullet_cat.warning() << "mesh has zero triangles! adding degenerated triangle." << std::endl;
60  mesh->add_triangle(LPoint3::zero(), LPoint3::zero(), LPoint3::zero());
61  }
62 
63  // Retain a pointer to the mesh, to prevent it from being deleted
64  _mesh = mesh;
65 
66  // Dynamic will create a GImpact mesh shape
67  if (dynamic) {
68 
69  _gimpact_shape = new btGImpactMeshShape(mesh->ptr());
70  _gimpact_shape->updateBound();
71  _gimpact_shape->setUserPointer(this);
72 
73  _bvh_shape = nullptr;
74  }
75 
76  // Static will create a Bvh mesh shape
77  else {
78 
79  _bvh_shape = new btBvhTriangleMeshShape(mesh->ptr(), compress, bvh);
80  _bvh_shape->setUserPointer(this);
81 
82  _gimpact_shape = nullptr;
83  }
84 }
85 
86 /**
87  *
88  */
89 BulletTriangleMeshShape::
90 BulletTriangleMeshShape(const BulletTriangleMeshShape &copy) {
91  LightMutexHolder holder(BulletWorld::get_global_lock());
92 
93  _dynamic = copy._dynamic;
94  _compress = copy._compress;
95  _bvh = copy._bvh;
96  _mesh = copy._mesh;
97 
98  if (_dynamic) {
99  _gimpact_shape = new btGImpactMeshShape(_mesh->ptr());
100  _gimpact_shape->updateBound();
101  _gimpact_shape->setUserPointer(this);
102  _bvh_shape = nullptr;
103  } else {
104  _bvh_shape = new btBvhTriangleMeshShape(_mesh->ptr(), _compress, _bvh);
105  _bvh_shape->setUserPointer(this);
106  _gimpact_shape = nullptr;
107  }
108 }
109 
110 /**
111  *
112  */
113 btCollisionShape *BulletTriangleMeshShape::
114 ptr() const {
115 
116  if (_bvh_shape) {
117  return _bvh_shape;
118  }
119 
120  if (_gimpact_shape) {
121  return _gimpact_shape;
122  }
123 
124  return nullptr;
125 }
126 
127 /**
128  *
129  */
130 void BulletTriangleMeshShape::
131 refit_tree(const LPoint3 &aabb_min, const LPoint3 &aabb_max) {
132  LightMutexHolder holder(BulletWorld::get_global_lock());
133 
134  nassertv(!aabb_max.is_nan());
135  nassertv(!aabb_max.is_nan());
136 
137  nassertv(this->is_static());
138 
139  _bvh_shape->refitTree(LVecBase3_to_btVector3(aabb_min),
140  LVecBase3_to_btVector3(aabb_max));
141 }
142 
143 /**
144  * Tells the BamReader how to create objects of type BulletTriangleMeshShape.
145  */
148  BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
149 }
150 
151 /**
152  * Writes the contents of this object to the datagram for shipping out to a
153  * Bam file.
154  */
157  BulletShape::write_datagram(manager, dg);
158 
159  dg.add_stdfloat(get_margin());
160 
161  manager->write_pointer(dg, _mesh);
162 
163  dg.add_bool(_dynamic);
164  if (!_dynamic) {
165  dg.add_bool(_compress);
166  dg.add_bool(_bvh);
167  }
168 }
169 
170 /**
171  * Receives an array of pointers, one for each time manager->read_pointer()
172  * was called in fillin(). Returns the number of pointers processed.
173  */
176  int pi = BulletShape::complete_pointers(p_list, manager);
177 
178  _mesh = DCAST(BulletTriangleMesh, p_list[pi++]);
179 
180  btStridingMeshInterface *mesh_ptr = _mesh->ptr();
181  nassertr(mesh_ptr != nullptr, pi);
182 
183  if (_dynamic) {
184  _gimpact_shape = new btGImpactMeshShape(mesh_ptr);
185  _gimpact_shape->updateBound();
186  _gimpact_shape->setUserPointer(this);
187  _gimpact_shape->setMargin(_margin);
188  } else {
189  _bvh_shape = new btBvhTriangleMeshShape(mesh_ptr, _compress, _bvh);
190  _bvh_shape->setUserPointer(this);
191  _bvh_shape->setMargin(_margin);
192  }
193 
194  return pi;
195 }
196 
197 /**
198  * This function is called by the BamReader's factory when a new object of
199  * type BulletShape is encountered in the Bam file. It should create the
200  * BulletShape and extract its information from the file.
201  */
202 TypedWritable *BulletTriangleMeshShape::
203 make_from_bam(const FactoryParams &params) {
205  DatagramIterator scan;
206  BamReader *manager;
207 
208  parse_params(params, scan, manager);
209  param->fillin(scan, manager);
210 
211  return param;
212 }
213 
214 /**
215  * This internal function is called by make_from_bam to read in all of the
216  * relevant data from the BamFile for the new BulletTriangleMeshShape.
217  */
218 void BulletTriangleMeshShape::
219 fillin(DatagramIterator &scan, BamReader *manager) {
220  BulletShape::fillin(scan, manager);
221 
222  _margin = scan.get_stdfloat();
223 
224  manager->read_pointer(scan);
225 
226  _dynamic = scan.get_bool();
227  if (!_dynamic) {
228  _compress = scan.get_bool();
229  _bvh = scan.get_bool();
230  }
231 }
bool get_bool()
Extracts a boolean value.
PN_stdfloat get_stdfloat()
Extracts either a 32-bit or a 64-bit floating-point number, according to Datagram::set_stdfloat_doubl...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
Definition: bamReader.h:110
Base class for objects that can be written to and read from Bam files.
Definition: typedWritable.h:35
virtual int complete_pointers(TypedWritable **plist, BamReader *manager)
Receives an array of pointers, one for each time manager->read_pointer() was called in fillin().
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
Definition: bamWriter.h:63
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual void fillin(DatagramIterator &scan, BamReader *manager)
This internal function is intended to be called by each class's make_from_bam() method to read in all...
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
void add_stdfloat(PN_stdfloat value)
Adds either a 32-bit or a 64-bit floating-point number, according to set_stdfloat_double().
Definition: datagram.I:133
void parse_params(const FactoryParams &params, DatagramIterator &scan, BamReader *&manager)
Takes in a FactoryParams, passed from a WritableFactory into any TypedWritable's make function,...
Definition: bamReader.I:275
void add_bool(bool value)
Adds a boolean value to the datagram.
Definition: datagram.I:34
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual int complete_pointers(TypedWritable **p_list, BamReader *manager)
Receives an array of pointers, one for each time manager->read_pointer() was called in fillin().
Similar to MutexHolder, but for a light mutex.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
An instance of this class is passed to the Factory when requesting it to do its business and construc...
Definition: factoryParams.h:36
void register_factory(TypeHandle handle, CreateFunc *func, void *user_data=nullptr)
Registers a new kind of thing the Factory will be able to create.
Definition: factory.I:73
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
size_t do_get_num_triangles() const
Returns the number of triangles in this triangle mesh.
static WritableFactory * get_factory()
Returns the global WritableFactory for generating TypedWritable objects.
Definition: bamReader.I:177
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
static void register_with_read_factory()
Tells the BamReader how to create objects of type BulletTriangleMeshShape.
bool read_pointer(DatagramIterator &scan)
The interface for reading a pointer to another object from a Bam file.
Definition: bamReader.cxx:610
void add_triangle(const LPoint3 &p0, const LPoint3 &p1, const LPoint3 &p2, bool remove_duplicate_vertices=false)
Adds a triangle with the indicated coordinates.
A class to retrieve the individual data elements previously stored in a Datagram.
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
Definition: datagram.h:38
void write_pointer(Datagram &packet, const TypedWritable *dest)
The interface for writing a pointer to another object to a Bam file.
Definition: bamWriter.cxx:317
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.