40PStatCollector CollisionFloorMesh::_volume_pcollector(
"Collision Volumes:CollisionFloorMesh");
41PStatCollector CollisionFloorMesh::_test_pcollector(
"Collision Tests:CollisionFloorMesh");
56xform(
const LMatrix4 &mat) {
57 Vertices::iterator vi;
58 for (vi=_vertices.begin();vi!=_vertices.end();++vi) {
59 LPoint3 pt = (*vi) * mat;
60 (*vi).set(pt[0],pt[1],pt[2]);
62 Triangles::iterator ti;
63 for (ti=_triangles.begin();ti!=_triangles.end();++ti) {
64 CollisionFloorMesh::TriangleIndices tri = *ti;
65 LPoint3 v1 = _vertices[tri.p1];
66 LPoint3 v2 = _vertices[tri.p2];
67 LPoint3 v3 = _vertices[tri.p3];
69 tri.min_x=min(min(v1[0],v2[0]),v3[0]);
70 tri.max_x=max(max(v1[0],v2[0]),v3[0]);
71 tri.min_y=min(min(v1[1],v2[1]),v3[1]);
72 tri.max_y=max(max(v1[1],v2[1]),v3[1]);
86 return LPoint3::origin();
92void CollisionFloorMesh::
93output(std::ostream &out)
const {
101compute_internal_bounds()
const {
102 if (_vertices.empty()) {
103 return new BoundingBox;
106 Vertices::const_iterator pi = _vertices.begin();
112 for (++pi; pi != _vertices.end(); ++pi) {
115 n.set(min(n[0], p[0]),
118 x.set(max(x[0], p[0]),
123 return new BoundingBox(n, x);
131 const CollisionRay *ray;
132 DCAST_INTO_R(ray, entry.
get_from(),
nullptr);
135 LPoint3 from_origin = ray->get_origin() * wrt_space->get_mat();
137 double fx = from_origin[0];
138 double fy = from_origin[1];
140 CollisionFloorMesh::Triangles::const_iterator ti;
141 for (ti = _triangles.begin(); ti < _triangles.end(); ++ti) {
142 TriangleIndices tri = *ti;
144 if (fx < tri.min_x || fx >= tri.max_x || fy < tri.min_y || fy >= tri.max_y) {
149 LPoint3 p0 = _vertices[tri.p1];
150 LPoint3 p1 = _vertices[tri.p2];
151 LPoint3 p2 = _vertices[tri.p3];
152 PN_stdfloat p0x = p0[0];
153 PN_stdfloat p0y = p0[1];
154 PN_stdfloat e0x, e0y, e1x, e1y, e2x, e2y;
157 e0x = fx - p0x; e0y = fy - p0y;
158 e1x = p1[0] - p0x; e1y = p1[1] - p0y;
159 e2x = p2[0] - p0x; e2y = p2[1] - p0y;
161 if (e2x == 0.0)
continue;
163 if (u < 0.0 || u > 1.0)
continue;
164 if (e1y == 0)
continue;
165 v = (e0y - (e2y * u)) / e1y;
166 if (v < 0.0)
continue;
168 PN_stdfloat d = (e2y * e1x) - (e2x * e1y);
169 if (d == 0.0)
continue;
170 u = ((e0y * e1x) - (e0x * e1y)) / d;
171 if (u < 0.0 || u > 1.0)
continue;
172 v = (e0x - (e2x * u)) / e1x;
173 if (v < 0.0)
continue;
175 if (u + v <= 0.0 || u + v > 1.0)
continue;
177 PN_stdfloat mag = u + v;
178 PN_stdfloat p0z = p0[2];
180 PN_stdfloat uz = (p2[2] - p0z) * mag;
181 PN_stdfloat vz = (p1[2] - p0z) * mag;
182 PN_stdfloat finalz = p0z + vz + (((uz - vz) * u) / (u + v));
183 PT(CollisionEntry) new_entry =
new CollisionEntry(entry);
185 new_entry->set_surface_normal(LPoint3(0, 0, 1));
186 new_entry->set_surface_point(LPoint3(fx, fy, finalz));
198 const CollisionSphere *sphere;
199 DCAST_INTO_R(sphere, entry.
get_from(),
nullptr);
202 LPoint3 from_origin = sphere->get_center() * wrt_space->get_mat();
204 double fx = from_origin[0];
205 double fy = from_origin[1];
207 PN_stdfloat fz = PN_stdfloat(from_origin[2]);
208 PN_stdfloat rad = sphere->get_radius();
209 CollisionFloorMesh::Triangles::const_iterator ti;
210 for (ti = _triangles.begin(); ti < _triangles.end(); ++ti) {
211 TriangleIndices tri = *ti;
213 if (fx < tri.min_x || fx >= tri.max_x || fy < tri.min_y || fy >= tri.max_y) {
218 LPoint3 p0 = _vertices[tri.p1];
219 LPoint3 p1 = _vertices[tri.p2];
220 LPoint3 p2 = _vertices[tri.p3];
221 PN_stdfloat p0x = p0[0];
222 PN_stdfloat p0y = p0[1];
223 PN_stdfloat e0x, e0y, e1x, e1y, e2x, e2y;
226 e0x = fx - p0x; e0y = fy - p0y;
227 e1x = p1[0] - p0x; e1y = p1[1] - p0y;
228 e2x = p2[0] - p0x; e2y = p2[1] - p0y;
230 if (e2x == 0.0)
continue;
232 if (u < 0.0 || u > 1.0)
continue;
233 if (e1y == 0)
continue;
234 v = (e0y - (e2y * u)) / e1y;
235 if (v < 0.0)
continue;
237 PN_stdfloat d = (e2y * e1x) - (e2x * e1y);
238 if (d == 0.0)
continue;
239 u = ((e0y * e1x) - (e0x * e1y)) / d;
240 if (u < 0.0 || u > 1.0)
continue;
241 v = (e0x - (e2x * u)) / e1x;
242 if (v < 0.0)
continue;
244 if (u + v <= 0.0 || u + v > 1.0)
continue;
246 PN_stdfloat mag = u + v;
247 PN_stdfloat p0z = p0[2];
249 PN_stdfloat uz = (p2[2] - p0z) * mag;
250 PN_stdfloat vz = (p1[2] - p0z) * mag;
251 PN_stdfloat finalz = p0z+vz+(((uz - vz) *u)/(u+v));
252 PN_stdfloat dz = fz - finalz;
255 PT(CollisionEntry) new_entry =
new CollisionEntry(entry);
257 new_entry->set_surface_normal(LPoint3(0, 0, 1));
258 new_entry->set_surface_point(LPoint3(fx, fy, finalz));
270void CollisionFloorMesh::
272 if (collide_cat.is_debug()) {
274 <<
"Recomputing viz for " << *
this <<
"\n";
277 PT(GeomVertexData) vdata =
new GeomVertexData
280 GeomVertexWriter vertex(vdata, InternalName::get_vertex());
283 PT(GeomTriangles) mesh =
new GeomTriangles(Geom::UH_static);
284 PT(GeomLinestrips) wire =
new GeomLinestrips(Geom::UH_static);
285 Triangles::iterator ti;
286 Vertices::iterator vi;
287 for (vi = _vertices.begin(); vi != _vertices.end(); vi++) {
289 vertex.add_data3(vert);
291 for (ti = _triangles.begin(); ti != _triangles.end(); ++ti) {
292 CollisionFloorMesh::TriangleIndices tri = *ti;
293 mesh->add_vertex(tri.p1);
294 mesh->add_vertex(tri.p2);
295 mesh->add_vertex(tri.p3);
296 wire->add_vertex(tri.p1);
297 wire->add_vertex(tri.p2);
298 wire->add_vertex(tri.p3);
299 wire->add_vertex(tri.p1);
300 wire->close_primitive();
301 mesh->close_primitive();
304 PT(Geom) geom =
new Geom(vdata);
305 PT(Geom) geom2 =
new Geom(vdata);
306 geom->add_primitive(mesh);
307 geom2->add_primitive(wire);
311 _bounds_viz_geom->add_geom(geom, get_solid_bounds_viz_state());
312 _bounds_viz_geom->add_geom(geom2, get_wireframe_bounds_viz_state());
321 return _volume_pcollector;
330 return _test_pcollector;
342 for (
size_t i = 0; i < _vertices.size(); i++) {
343 _vertices[i].write_datagram(me);
346 for (
size_t i = 0; i < _triangles.size(); i++) {
363void CollisionFloorMesh::
366 CollisionSolid::fillin(scan, manager);
368 for (
size_t i = 0; i < num_verts; i++) {
370 vert.read_datagram(scan);
372 _vertices.push_back(vert);
375 for (
size_t i = 0; i < num_tris; i++) {
376 CollisionFloorMesh::TriangleIndices tri;
386 _triangles.push_back(tri);
400 me->fillin(scan, manager);
416void CollisionFloorMesh::
417write(std::ostream &out,
int indent_level)
const {
418 indent(out, indent_level) << (*this) <<
"\n";
425add_triangle(
unsigned int pointA,
unsigned int pointB,
unsigned int pointC) {
426 CollisionFloorMesh::TriangleIndices tri;
430 LPoint3 v1 = _vertices[pointA];
431 LPoint3 v2 = _vertices[pointB];
432 LPoint3 v3 = _vertices[pointC];
434 tri.min_x=min(min(v1[0],v2[0]),v3[0]);
435 tri.max_x=max(max(v1[0],v2[0]),v3[0]);
436 tri.min_y=min(min(v1[1],v2[1]),v3[1]);
437 tri.max_y=max(max(v1[1],v2[1]),v3[1]);
439 _triangles.push_back(tri);
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
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.
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 ...
This is an abstract class for any volume in any sense which can be said to define the locality of ref...
Defines a single collision event.
get_from
Returns the CollisionSolid pointer for the particular solid that triggered this collision.
static TypedWritable * make_CollisionFloorMesh(const FactoryParams ¶ms)
Factory method to generate a CollisionPolygon object.
void add_triangle(unsigned int pointA, unsigned int pointB, unsigned int pointC)
store a triangle for processing
virtual PStatCollector & get_volume_pcollector()
Returns a PStatCollector that is used to count the number of bounding volume tests made against a sol...
virtual void write_datagram(BamWriter *manager, Datagram &me)
Function to write the important information in the particular object to a Datagram.
virtual LPoint3 get_collision_origin() const
Returns the point in space deemed to be the "origin" of the solid for collision purposes.
virtual void xform(const LMatrix4 &mat)
Transforms the solid by the indicated matrix.
virtual PStatCollector & get_test_pcollector()
Returns a PStatCollector that is used to count the number of intersection tests made against a solid ...
static void register_with_read_factory()
Factory method to generate a CollisionPolygon object.
CollisionFloorMesh()
This is only for the convenience of CollisionPolygon.
The abstract base class for all things that can collide with other things in the world,...
virtual void write_datagram(BamWriter *manager, Datagram &me)
Function to write the important information in the particular object to a Datagram.
virtual void xform(const LMatrix4 &mat)
Transforms the solid by the indicated matrix.
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...
uint16_t get_uint16()
Extracts an unsigned 16-bit integer.
uint32_t get_uint32()
Extracts an unsigned 32-bit integer.
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
void add_uint32(uint32_t value)
Adds an unsigned 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_uint16(uint16_t value)
Adds an unsigned 16-bit integer 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.
A lightweight class that represents a single element that may be timed and/or counted via stats.
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.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
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.