32 : _welding_distance(0) {
34 mesh.m_numTriangles = 0;
35 mesh.m_numVertices = 0;
36 mesh.m_indexType = PHY_INTEGER;
37 mesh.m_triangleIndexBase =
nullptr;
38 mesh.m_triangleIndexStride = 3 *
sizeof(int);
39 mesh.m_vertexBase =
nullptr;
40 mesh.m_vertexStride =
sizeof(btVector3);
41 _mesh.addIndexedMesh(mesh);
47 size_t BulletTriangleMesh::
48 get_num_vertices()
const {
51 return _vertices.size();
61 nassertr(index < (
size_t)_vertices.size(), LPoint3::zero());
62 const btVector3 &vertex = _vertices[index];
63 return LPoint3(vertex[0], vertex[1], vertex[2]);
74 nassertr(index + 2 < (
size_t)_indices.size(), LVecBase3i::zero());
75 return LVecBase3i(_indices[index], _indices[index + 1], _indices[index + 2]);
85 return _indices.size() / 3;
91 size_t BulletTriangleMesh::
92 get_num_triangles()
const {
107 _vertices.reserve(num_verts);
108 _indices.reserve(num_indices);
110 btIndexedMesh &mesh = _mesh.getIndexedMeshArray()[0];
111 mesh.m_vertexBase = (
unsigned char*)&_vertices[0];
112 mesh.m_triangleIndexBase = (
unsigned char *)&_indices[0];
125 do_add_triangle(
const LPoint3 &p0,
const LPoint3 &p1,
const LPoint3 &p2,
bool remove_duplicate_vertices) {
127 nassertv(!p0.is_nan());
128 nassertv(!p1.is_nan());
129 nassertv(!p2.is_nan());
131 btIndexedMesh &mesh = _mesh.getIndexedMeshArray()[0];
132 mesh.m_numTriangles++;
134 if (!remove_duplicate_vertices) {
135 unsigned int index = _vertices.size();
136 _indices.push_back(index++);
137 _indices.push_back(index++);
138 _indices.push_back(index++);
140 _vertices.push_back(LVecBase3_to_btVector3(p0));
141 _vertices.push_back(LVecBase3_to_btVector3(p1));
142 _vertices.push_back(LVecBase3_to_btVector3(p2));
143 mesh.m_numVertices += 3;
144 mesh.m_vertexBase = (
unsigned char*)&_vertices[0];
146 _indices.push_back(find_or_add_vertex(p0));
147 _indices.push_back(find_or_add_vertex(p1));
148 _indices.push_back(find_or_add_vertex(p2));
151 mesh.m_triangleIndexBase = (
unsigned char *)&_indices[0];
163 add_triangle(
const LPoint3 &p0,
const LPoint3 &p1,
const LPoint3 &p2,
bool remove_duplicate_vertices) {
180 _welding_distance = distance;
187 PN_stdfloat BulletTriangleMesh::
188 get_welding_distance()
const {
191 return _welding_distance;
212 size_t num_vertices = vdata->get_num_rows();
215 btIndexedMesh &mesh = _mesh.getIndexedMeshArray()[0];
217 if (!remove_duplicate_vertices) {
219 mesh.m_numVertices += num_vertices;
220 unsigned int index_offset = _vertices.size();
221 _vertices.reserve(_vertices.size() + num_vertices);
225 _vertices.push_back(LVecBase3_to_btVector3(reader.
get_data3()));
230 _vertices.push_back(LVecBase3_to_btVector3(m.xform_point(reader.
get_data3())));
234 for (
size_t k = 0; k < geom->get_num_primitives(); ++k) {
236 prim = prim->decompose();
238 if (prim->is_of_type(GeomTriangles::get_class_type())) {
239 int num_vertices = prim->get_num_vertices();
240 _indices.reserve(_indices.size() + num_vertices);
241 mesh.m_numTriangles += num_vertices / 3;
244 if (vertices !=
nullptr) {
247 _indices.push_back(index_offset + index.
get_data1i());
250 int index = index_offset + prim->get_first_vertex();
251 int end_index = index + num_vertices;
252 while (index < end_index) {
253 _indices.push_back(index++);
258 nassertv(mesh.m_numTriangles * 3 == _indices.size());
263 points.reserve(_vertices.size() + num_vertices);
272 points.push_back(m.xform_point(reader.
get_data3()));
277 for (
size_t k = 0; k < geom->get_num_primitives(); ++k) {
279 prim = prim->decompose();
281 if (prim->is_of_type(GeomTriangles::get_class_type())) {
282 int num_vertices = prim->get_num_vertices();
283 _indices.reserve(_indices.size() + num_vertices);
284 mesh.m_numTriangles += num_vertices / 3;
287 if (vertices !=
nullptr) {
290 _indices.push_back(find_or_add_vertex(points[index.
get_data1i()]));
293 int index = prim->get_first_vertex();
294 int end_index = index + num_vertices;
295 while (index < end_index) {
296 _indices.push_back(find_or_add_vertex(points[index]));
301 nassertv(mesh.m_numTriangles * 3 == _indices.size());
305 mesh.m_vertexBase = (
unsigned char*)&_vertices[0];
306 mesh.m_triangleIndexBase = (
unsigned char *)&_indices[0];
319 add_array(
const PTA_LVecBase3 &points,
const PTA_int &indices,
bool remove_duplicate_vertices) {
322 btIndexedMesh &mesh = _mesh.getIndexedMeshArray()[0];
324 _indices.reserve(_indices.size() + indices.size());
326 if (!remove_duplicate_vertices) {
327 unsigned int index_offset = _vertices.size();
328 for (
size_t i = 0; i < indices.size(); ++i) {
329 _indices.push_back(index_offset + indices[i]);
332 _vertices.reserve(_vertices.size() + points.size());
333 for (
size_t i = 0; i < points.size(); ++i) {
334 _vertices.push_back(LVecBase3_to_btVector3(points[i]));
337 mesh.m_numVertices += points.size();
341 _indices.reserve(_indices.size() + indices.size());
342 for (
size_t i = 0; i < indices.size(); ++i) {
343 LVecBase3 p = points[indices[i]];
344 _indices.push_back(find_or_add_vertex(p));
348 mesh.m_numTriangles += indices.size() / 3;
351 mesh.m_vertexBase = (
unsigned char*)&_vertices[0];
352 mesh.m_triangleIndexBase = (
unsigned char *)&_indices[0];
358 void BulletTriangleMesh::
359 output(std::ostream &out)
const {
362 out << get_type() <<
", " << _indices.size() / 3 <<
" triangles";
368 void BulletTriangleMesh::
369 write(std::ostream &out,
int indent_level)
const {
370 indent(out, indent_level) << get_type() <<
":" << endl;
372 const IndexedMeshArray &array = _mesh.getIndexedMeshArray();
373 for (
int i = 0; i < array.size(); ++i) {
374 indent(out, indent_level + 2) <<
"IndexedMesh " << i <<
":" << endl;
375 const btIndexedMesh &mesh = array[0];
376 indent(out, indent_level + 4) <<
"num triangles:" << mesh.m_numTriangles << endl;
377 indent(out, indent_level + 4) <<
"num vertices:" << mesh.m_numVertices << endl;
385 unsigned int BulletTriangleMesh::
386 find_or_add_vertex(
const LVecBase3 &p) {
387 btVector3 vertex = LVecBase3_to_btVector3(p);
389 for (
int i = 0; i < _vertices.size(); ++i) {
390 if ((_vertices[i] - vertex).length2() <= _welding_distance) {
395 _vertices.push_back(vertex);
397 btIndexedMesh &mesh = _mesh.getIndexedMeshArray()[0];
398 mesh.m_numVertices++;
399 mesh.m_vertexBase = (
unsigned char*)&_vertices[0];
400 return _vertices.size() - 1;
422 btIndexedMesh &mesh = _mesh.getIndexedMeshArray()[0];
430 const unsigned char *vptr = mesh.m_vertexBase;
431 nassertv(vptr !=
nullptr || mesh.m_numVertices == 0);
433 for (
int i = 0; i < mesh.m_numVertices; ++i) {
434 const btVector3 &vertex = *((btVector3 *)vptr);
438 vptr += mesh.m_vertexStride;
442 const unsigned char *iptr = mesh.m_triangleIndexBase;
443 nassertv(iptr !=
nullptr || mesh.m_numTriangles == 0);
445 for (
int i = 0; i < mesh.m_numTriangles; ++i) {
446 int *triangle = (
int *)iptr;
450 iptr += mesh.m_triangleIndexStride;
466 param->fillin(scan, manager);
475 void BulletTriangleMesh::
484 btIndexedMesh &mesh = _mesh.getIndexedMeshArray()[0];
485 mesh.m_numVertices = num_vertices;
486 mesh.m_numTriangles = num_triangles;
490 _vertices.reserve(num_vertices);
491 for (
int i = 0; i < num_vertices; ++i) {
495 _vertices.push_back(btVector3(x, y, z));
499 size_t num_indices = (size_t)num_triangles * 3;
500 _indices.resize(num_indices);
501 scan.
extract_bytes((
unsigned char *)&_indices[0], num_indices *
sizeof(
int));
504 mesh.m_vertexBase = (
unsigned char*)&_vertices[0];
505 mesh.m_triangleIndexBase = (
unsigned char *)&_indices[0];
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
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...
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
static void register_with_read_factory()
Tells the BamReader how to create objects of type BulletTriangleMesh.
void do_add_triangle(const LPoint3 &p0, const LPoint3 &p1, const LPoint3 &p2, bool remove_duplicate_vertices=false)
Adds a triangle with the indicated coordinates.
Base class for objects that can be written to and read from Bam files.
This is an abstract base class for a family of classes that represent the fundamental geometry primit...
get_vertex
Returns the vertex at the given vertex index.
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
int32_t get_int32()
Extracts a signed 32-bit integer.
void add_stdfloat(PN_stdfloat value)
Adds either a 32-bit or a 64-bit floating-point number, according to set_stdfloat_double().
void add_geom(const Geom *geom, bool remove_duplicate_vertices=false, const TransformState *ts=TransformState::make_identity())
Adds the geometry from the indicated Geom from the triangle mesh.
vector_uchar extract_bytes(size_t size)
Extracts the indicated number of bytes in the datagram and returns them as a string.
void add_array(const PTA_LVecBase3 &points, const PTA_int &indices, bool remove_duplicate_vertices=false)
Adds triangle information from an array of points and indices referring to these points.
void parse_params(const FactoryParams ¶ms, DatagramIterator &scan, BamReader *&manager)
Takes in a FactoryParams, passed from a WritableFactory into any TypedWritable's make function,...
void add_bool(bool value)
Adds a boolean value to the datagram.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
get_triangle
Returns the vertex indices making up the given triangle index.
std::ostream & indent(std::ostream &out, int indent_level)
A handy function for doing text formatting.
Similar to MutexHolder, but for a light mutex.
This defines the actual numeric vertex data stored in a Geom, in the structure defined by a particula...
A container for geometry primitives.
An instance of this class is passed to the Factory when requesting it to do its business and construc...
const LVecBase3 & get_data3()
Returns the data associated with the read row, expressed as a 3-component value, and advances the rea...
void register_factory(TypeHandle handle, CreateFunc *func, void *user_data=nullptr)
Registers a new kind of thing the Factory will be able to create.
int get_data1i()
Returns the data associated with the read row, expressed as a 1-component value, and advances the rea...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void add_int32(int32_t value)
Adds a signed 32-bit integer to the datagram.
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.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void preallocate(int num_verts, int num_indices)
Used to reserve memory in anticipation of the given amount of vertices and indices being added to the...
This object provides a high-level interface for quickly reading a sequence of numeric values from a v...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
set_welding_distance
Sets the square of the distance at which vertices will be merged together when adding geometry with r...
bool is_at_end() const
Returns true if the reader is currently at the end of the list of vertices, false otherwise.
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.
TypeHandle is the identifier used to differentiate C++ class types.
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
get_welding_distance
Returns the value previously set with set_welding_distance(), or the value of 0 if none was set.
This is the data for one array of a GeomVertexData structure.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.