15 #include "collisionInvSphere.h" 16 #include "collisionSphere.h" 17 #include "collisionLine.h" 18 #include "collisionRay.h" 19 #include "collisionSegment.h" 20 #include "collisionHandler.h" 21 #include "collisionEntry.h" 22 #include "config_collide.h" 23 #include "omniBoundingVolume.h" 25 #include "datagramIterator.h" 26 #include "bamReader.h" 27 #include "bamWriter.h" 28 #include "nearly_zero.h" 30 #include "geomTristrips.h" 31 #include "geomVertexWriter.h" 33 PStatCollector CollisionInvSphere::_volume_pcollector(
"Collision Volumes:CollisionInvSphere");
34 PStatCollector CollisionInvSphere::_test_pcollector(
"Collision Tests:CollisionInvSphere");
54 report_undefined_from_intersection(get_type());
67 return _volume_pcollector;
79 return _test_pcollector;
87 void CollisionInvSphere::
88 output(ostream &out)
const {
89 out <<
"invsphere, c (" << get_center() <<
"), r " << get_radius();
98 compute_internal_bounds()
const {
110 test_intersection_from_sphere(
const CollisionEntry &entry)
const {
112 DCAST_INTO_R(sphere, entry.
get_from(), NULL);
114 const LMatrix4 &wrt_mat = entry.get_wrt_mat();
116 LPoint3 from_center = sphere->get_center() * wrt_mat;
118 LVector3(sphere->get_radius(), 0.0f, 0.0f) * wrt_mat;
119 PN_stdfloat from_radius = length(from_radius_v);
121 LPoint3 into_center = get_center();
122 PN_stdfloat into_radius = get_radius();
124 LVector3 vec = from_center - into_center;
125 PN_stdfloat dist2 = dot(vec, vec);
126 if (dist2 < (into_radius - from_radius) * (into_radius - from_radius)) {
131 if (collide_cat.is_debug()) {
139 PN_stdfloat vec_length = vec.
length();
140 if (IS_NEARLY_ZERO(vec_length)) {
144 surface_normal.set(1.0, 0.0, 0.0);
146 surface_normal = vec / -vec_length;
151 new_entry->set_surface_normal(normal);
152 new_entry->set_surface_point(into_center - surface_normal * into_radius);
153 new_entry->set_interior_point(from_center - surface_normal * from_radius);
166 DCAST_INTO_R(line, entry.
get_from(), NULL);
168 const LMatrix4 &wrt_mat = entry.get_wrt_mat();
170 LPoint3 from_origin = line->get_origin() * wrt_mat;
171 LVector3 from_direction = line->get_direction() * wrt_mat;
174 if (!intersects_line(t1, t2, from_origin, from_direction, 0.0f)) {
180 if (collide_cat.is_debug()) {
187 LPoint3 into_intersection_point = from_origin + t2 * from_direction;
188 new_entry->set_surface_point(into_intersection_point);
193 LVector3 normal = into_intersection_point - get_center();
195 new_entry->set_surface_normal(-normal);
209 DCAST_INTO_R(ray, entry.
get_from(), NULL);
211 const LMatrix4 &wrt_mat = entry.get_wrt_mat();
213 LPoint3 from_origin = ray->get_origin() * wrt_mat;
214 LVector3 from_direction = ray->get_direction() * wrt_mat;
217 if (!intersects_line(t1, t2, from_origin, from_direction, 0.0f)) {
225 if (collide_cat.is_debug()) {
232 LPoint3 into_intersection_point;
233 into_intersection_point = from_origin + t2 * from_direction;
234 new_entry->set_surface_point(into_intersection_point);
239 LVector3 normal = into_intersection_point - get_center();
241 new_entry->set_surface_normal(-normal);
253 test_intersection_from_segment(
const CollisionEntry &entry)
const {
255 DCAST_INTO_R(segment, entry.
get_from(), NULL);
257 const LMatrix4 &wrt_mat = entry.get_wrt_mat();
259 LPoint3 from_a = segment->get_point_a() * wrt_mat;
260 LPoint3 from_b = segment->get_point_b() * wrt_mat;
261 LVector3 from_direction = from_b - from_a;
264 if (!intersects_line(t1, t2, from_a, from_direction, 0.0f)) {
275 }
else if (t1 >= 1.0) {
279 }
else if (t2 <= 1.0) {
283 }
else if (t1 >= 0.0) {
294 if (collide_cat.is_debug()) {
301 LPoint3 into_intersection_point = from_a + t * from_direction;
302 new_entry->set_surface_point(into_intersection_point);
307 LVector3 normal = into_intersection_point - get_center();
309 new_entry->set_surface_normal(-normal);
321 void CollisionInvSphere::
323 if (collide_cat.is_debug()) {
325 <<
"Recomputing viz for " << *
this <<
"\n";
328 static const int num_slices = 16;
329 static const int num_stacks = 8;
332 (
"collision", GeomVertexFormat::get_v3(),
337 for (
int sl = 0; sl < num_slices; ++sl) {
338 PN_stdfloat longitude0 = (PN_stdfloat)sl / (PN_stdfloat)num_slices;
339 PN_stdfloat longitude1 = (PN_stdfloat)(sl + 1) / (PN_stdfloat)num_slices;
340 vertex.
add_data3(compute_point(0.0, longitude0));
341 for (
int st = 1; st < num_stacks; ++st) {
342 PN_stdfloat latitude = (PN_stdfloat)st / (PN_stdfloat)num_stacks;
343 vertex.
add_data3(compute_point(latitude, longitude1));
344 vertex.
add_data3(compute_point(latitude, longitude0));
346 vertex.
add_data3(compute_point(1.0, longitude0));
348 strip->add_next_vertices(num_stacks * 2);
349 strip->close_primitive();
353 geom->add_primitive(strip);
355 _viz_geom->add_geom(geom, get_solid_viz_state());
390 parse_params(params, scan, manager);
391 me->fillin(scan, manager);
403 void CollisionInvSphere::
405 CollisionSphere::fillin(scan, manager);
const LVector3 & get_effective_normal() const
Returns the normal that was set by set_effective_normal().
This object provides a high-level interface for quickly writing a sequence of numeric values from a v...
An infinite ray, with a specific origin and direction.
NodePath get_into_node_path() const
Returns the NodePath that represents the specific CollisionNode or GeomNode instance that was collide...
virtual void write_datagram(BamWriter *manager, Datagram &me)
Function to write the important information in the particular object to a Datagram.
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
The abstract base class for all things that can collide with other things in the world, and all the things they can collide with (except geometry).
Base class for objects that can be written to and read from Bam files.
This is a three-component vector distance (as opposed to a three-component point, which represents a ...
Defines a series of triangle strips.
This is a three-component point in space (as opposed to a three-component vector, which represents a ...
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
A spherical collision volume or object.
This is an abstract class for any volume in any sense which can be said to define the locality of ref...
A lightweight class that represents a single element that may be timed and/or counted via stats...
A finite line segment, with two specific endpoints but no thickness.
This is a 4-by-4 transform matrix.
Defines a single collision event.
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...
void add_data3(PN_stdfloat x, PN_stdfloat y, PN_stdfloat z)
Sets the write row to a particular 3-component value, and advances the write row. ...
virtual PStatCollector & get_volume_pcollector()
Returns a PStatCollector that is used to count the number of bounding volume tests made against a sol...
void register_factory(TypeHandle handle, CreateFunc *func)
Registers a new kind of thing the Factory will be able to create.
static void register_with_read_factory()
Factory method to generate a CollisionInvSphere object.
An infinite line, similar to a CollisionRay, except that it extends in both directions.
float length() const
Returns the length of the vector, by the Pythagorean theorem.
static WritableFactory * get_factory()
Returns the global WritableFactory for generating TypedWritable objects.
This is a special kind of GeometricBoundingVolume that fills all of space.
bool has_effective_normal() const
Returns true if a special normal was set by set_effective_normal(), false otherwise.
A class to retrieve the individual data elements previously stored in a Datagram. ...
NodePath get_from_node_path() const
Returns the NodePath that represents the CollisionNode that contains the CollisionSolid that triggere...
virtual void write_datagram(BamWriter *manager, Datagram &me)
Function to write the important information in the particular object to a Datagram.
TypeHandle is the identifier used to differentiate C++ class types.
bool get_respect_effective_normal() const
See set_respect_effective_normal().
bool normalize()
Normalizes the vector in place.
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
An inverted sphere: this is a sphere whose collision surface is the inside surface of the sphere...
const CollisionSolid * get_from() const
Returns the CollisionSolid pointer for the particular solid that triggered this collision.
virtual PStatCollector & get_test_pcollector()
Returns a PStatCollector that is used to count the number of intersection tests made against a solid ...