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];