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);
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;
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;
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];
void parse_params(const FactoryParams ¶ms, DatagramIterator &scan, BamReader *&manager)
Takes in a FactoryParams, passed from a WritableFactory into any TypedWritable's make function,...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
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...
static WritableFactory * get_factory()
Returns the global WritableFactory for generating TypedWritable objects.
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
void add_triangle(const LPoint3 &p0, const LPoint3 &p1, const LPoint3 &p2, bool remove_duplicate_vertices=false)
Adds a triangle with the indicated coordinates.
size_t do_get_num_triangles() const
Returns the number of triangles in this triangle mesh.
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.
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 do_add_triangle(const LPoint3 &p0, const LPoint3 &p1, const LPoint3 &p2, bool remove_duplicate_vertices=false)
Adds a triangle with the indicated coordinates.
static void register_with_read_factory()
Tells the BamReader how to create objects of type BulletTriangleMesh.
get_vertex
Returns the vertex at the given vertex index.
get_num_triangles
Returns the number of triangles in this triangle mesh.
get_welding_distance
Returns the value previously set with set_welding_distance(), or the value of 0 if none was set.
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...
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.
set_welding_distance
Sets the square of the distance at which vertices will be merged together when adding geometry with r...
get_triangle
Returns the vertex indices making up the given triangle index.
get_num_vertices
Returns the number of vertices in this triangle mesh.
A class to retrieve the individual data elements previously stored in a Datagram.
PN_stdfloat get_stdfloat()
Extracts either a 32-bit or a 64-bit floating-point number, according to Datagram::set_stdfloat_doubl...
vector_uchar extract_bytes(size_t size)
Extracts the indicated number of bytes in the datagram and returns them as a string.
bool get_bool()
Extracts a boolean value.
int32_t get_int32()
Extracts a signed 32-bit integer.
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
void add_int32(int32_t value)
Adds a signed 32-bit integer to the datagram.
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_bool(bool value)
Adds a boolean value to the datagram.
An instance of this class is passed to the Factory when requesting it to do its business and construc...
void register_factory(TypeHandle handle, CreateFunc *func, void *user_data=nullptr)
Registers a new kind of thing the Factory will be able to create.
This is an abstract base class for a family of classes that represent the fundamental geometry primit...
This is the data for one array of a GeomVertexData structure.
This defines the actual numeric vertex data stored in a Geom, in the structure defined by a particula...
This object provides a high-level interface for quickly reading a sequence of numeric values from a v...
bool is_at_end() const
Returns true if the reader is currently at the end of the list of vertices, false otherwise.
int get_data1i()
Returns the data associated with the read row, expressed as a 1-component value, and advances the rea...
const LVecBase3 & get_data3()
Returns the data associated with the read row, expressed as a 3-component value, and advances the rea...
A container for geometry primitives.
Similar to MutexHolder, but for a light mutex.
TypeHandle is the identifier used to differentiate C++ class types.
Base class for objects that can be written to and read from Bam files.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
std::ostream & indent(std::ostream &out, int indent_level)
A handy function for doing text formatting.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.