Panda3D

collisionCone.cxx
Go to the documentation of this file.
1 /**
2 * PANDA 3D SOFTWARE
3 * Copyright (c) Carnegie Mellon University. All rights reserved.
4 *
5 * All use of this software is subject to the terms of the revised BSD
6 * license. You should have received a copy of this license along
7 * with this source code in a file named "LICENSE."
8 *
9 * @file collisionCone.cxx
10 * @author rdb
11 * @date 2021-01-29
12 */
13
14 #include "collisionCone.h"
15 #include "collisionEntry.h"
16 #include "collisionSphere.h"
17 #include "collisionPolygon.h"
18 #include "config_collide.h"
19 #include "cmath.h"
20 #include "geom.h"
21 #include "geomTrifans.h"
22 #include "geomLinestrips.h"
23 #include "mathNumbers.h"
24 #include "billboardEffect.h"
25
26 PStatCollector CollisionCone::_volume_pcollector("Collision Volumes:CollisionCone");
27 PStatCollector CollisionCone::_test_pcollector("Collision Tests:CollisionCone");
28 TypeHandle CollisionCone::_type_handle;
29
30 /**
31 *
32 */
33 CollisionSolid *CollisionCone::
34 make_copy() {
35 return new CollisionCone(*this);
36 }
37
38 /**
39 * Transforms the solid by the indicated matrix.
40 */
41 void CollisionCone::
42 xform(const LMatrix4 &mat) {
43 CollisionSolid::xform(mat);
44 }
45
46 /**
47 * Returns the point in space deemed to be the "origin" of the solid for
48 * collision purposes. The closest intersection point to this origin point is
49 * considered to be the most significant.
50 */
51 LPoint3 CollisionCone::
52 get_collision_origin() const {
53 return LPoint3::origin();
54 }
55
56 /**
57 * Returns a PStatCollector that is used to count the number of bounding
58 * volume tests made against a solid of this type in a given frame.
59 */
60 PStatCollector &CollisionCone::
61 get_volume_pcollector() {
62 return _volume_pcollector;
63 }
64
65 /**
66 * Returns a PStatCollector that is used to count the number of intersection
67 * tests made against a solid of this type in a given frame.
68 */
69 PStatCollector &CollisionCone::
70 get_test_pcollector() {
71 return _test_pcollector;
72 }
73
74 /**
75 *
76 */
77 void CollisionCone::
78 output(std::ostream &out) const {
79 out << "ccone, (" << _radius << ")";
80 }
81
82 /**
83 *
84 */
85 PT(BoundingVolume) CollisionCone::
86 compute_internal_bounds() const {
87 return new BoundingSphere(LPoint3(0, 0, 0), std::max(_radius, _apex[2]) * 2);
88 }
89
90 /**
91 *
92 */
93 PT(CollisionEntry) CollisionCone::
94 test_intersection_from_sphere(const CollisionEntry &entry) const {
95 const CollisionSphere *sphere;
96 DCAST_INTO_R(sphere, entry.get_from(), nullptr);
97
98 const LMatrix4 &wrt_mat = entry.get_wrt_mat();
99
100 LPoint3 from_center = sphere->get_center() * wrt_mat;
101 LVector3 from_radius_v =
102 LVector3(sphere->get_radius(), 0.0f, 0.0f) * wrt_mat;
103 PN_stdfloat from_radius = length(from_radius_v);
104
105 // Distance to center line
106 PN_stdfloat dist_to_line = from_center.get_xy().length();
107 if (dist_to_line > _radius + from_radius) {
108 return nullptr;
109 }
110
111 if (from_center.get_z() > _apex.get_z() + from_radius) {
112 return nullptr;
113 }
114
115 LPlane side(LPoint3(_radius, 1, 0), LPoint3(_radius, 0, 0), _apex);
116
117 PN_stdfloat dist_bottom = from_center.get_z() + from_radius;
118 PN_stdfloat dist_side = side.dist_to_plane(LPoint3(dist_to_line, 0, from_center.get_z())) + from_radius;
119
120 std::cerr << dist_side << " " << dist_to_line << "\n";
121
122
123 if (dist_bottom < 0 || dist_side < 0) {
124 return nullptr;
125 }
126
127 if (collide_cat.is_debug()) {
128 collide_cat.debug()
129 << "intersection detected from " << entry.get_from_node_path()
130 << " into " << entry.get_into_node_path() << "\n";
131 }
132 PT(CollisionEntry) new_entry = new CollisionEntry(entry);
133
134 LPoint3 surface_point;
135 LVector3 surface_normal;
136
137 if (dist_bottom < dist_side) {
138 surface_normal = LVector3(0, 0, -1);
139 surface_point = LPoint3(from_center[0], from_center[1], 0);
140 if (dist_to_line > _radius) {
141 surface_point = surface_point * (_radius / dist_to_line);
142 }
143 }
144 else {
145 surface_normal = side.get_normal();
146 surface_point = get_apex();
147 }
148
149 LVector3 normal = (
150 has_effective_normal() && sphere->get_respect_effective_normal())
151 ? get_effective_normal() : surface_normal;
152 //
153 new_entry->set_surface_normal(normal);
154 new_entry->set_surface_point(surface_point);
155 //new_entry->set_interior_point(from_center - get_normal() * from_radius);
156
157 return new_entry;
158 }
159
160 /**
161 * Fills the _viz_geom GeomNode up with Geoms suitable for rendering this
162 * solid.
163 */
164 void CollisionCone::
165 fill_viz_geom() {
166 if (collide_cat.is_debug()) {
167 collide_cat.debug()
168 << "Recomputing viz for " << *this << "\n";
169 }
170
171 static int num_base_vertices = 8;
172
173 PT(GeomVertexData) vdata = new GeomVertexData
174 ("collision", GeomVertexFormat::get_v3(),
175 Geom::UH_static);
176 vdata->unclean_set_num_rows(num_base_vertices + 2);
177
178 {
179 GeomVertexWriter vertex(vdata, InternalName::get_vertex());
180 double factor = MathNumbers::pi * 2.0 / (double)num_base_vertices;
181 for (int i = 0; i < num_base_vertices; ++i) {
182 double angle = i * factor;
183 vertex.set_data3(ccos(angle) * _radius, csin(angle) * _radius, 0);
184 }
185 vertex.set_data3(0, 0, 0);
186 vertex.set_data3(get_apex());
187 }
188
189 PT(GeomTrifans) body = new GeomTrifans(Geom::UH_static);
190 body->add_vertex(num_base_vertices);
191 body->add_vertex(0);
192 for (int i = num_base_vertices - 1; i >= 0; --i) {
193 body->add_vertex(i);
194 }
195 body->close_primitive();
196
197 body->add_vertex(num_base_vertices + 1);
198 body->add_consecutive_vertices(0, num_base_vertices);
199 body->add_vertex(0);
200 body->close_primitive();
201
202 PT(GeomLinestrips) border = new GeomLinestrips(Geom::UH_static);
203 border->add_consecutive_vertices(0, num_base_vertices);
204 border->add_vertex(0);
205 border->add_vertex(num_base_vertices + 1);
206 border->add_vertex(num_base_vertices / 2);
207 border->close_primitive();
208
209 PT(Geom) geom1 = new Geom(vdata);
210 geom1->add_primitive(body);
211
212 PT(Geom) geom2 = new Geom(vdata);
213 geom2->add_primitive(border);
214
215 _viz_geom->add_geom(geom1, get_solid_viz_state());
216 _viz_geom->add_geom(geom2, get_wireframe_viz_state());
217 _viz_geom->set_effect(BillboardEffect::make_axis());
218
219 _bounds_viz_geom->add_geom(geom1, get_solid_bounds_viz_state());
220 _bounds_viz_geom->add_geom(geom2, get_wireframe_bounds_viz_state());
221 _bounds_viz_geom->set_effect(BillboardEffect::make_axis());
222 }
223
224 /**
225 * Function to write the important information in the particular object to a
226 * Datagram
227 */
228 void CollisionCone::
229 write_datagram(BamWriter *manager, Datagram &me) {
230 CollisionSolid::write_datagram(manager, me);
231 //_plane.write_datagram(me);
232 }
233
234 /**
235 * Function that reads out of the datagram (or asks manager to read) all of
236 * the data that is needed to re-create this object and stores it in the
237 * appropiate place
238 */
239 void CollisionCone::
240 fillin(DatagramIterator& scan, BamReader* manager)
241 {
242 CollisionSolid::fillin(scan, manager);
243 //_plane.read_datagram(scan);
244 }
245
246 /**
247 * Factory method to generate a CollisionCone object
248 */
249 TypedWritable *CollisionCone::
250 make_from_bam(const FactoryParams &params) {
251 CollisionCone *me = new CollisionCone;
252 DatagramIterator scan;
253 BamReader *manager;
254
255 parse_params(params, scan, manager);
256 me->fillin(scan, manager);
257 return me;
258 }
259
260 /**
261 * Factory method to generate a CollisionCone object
262 */
263 void CollisionCone::
264 register_with_read_factory() {
265 BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
266 }
parse_params
void parse_params(const FactoryParams &params, DatagramIterator &scan, BamReader *&manager)
Takes in a FactoryParams, passed from a WritableFactory into any TypedWritable's make function,...
Definition: bamReader.I:275
billboardEffect.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
BamReader
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
Definition: bamReader.h:110
BamReader::get_factory
static WritableFactory * get_factory()
Returns the global WritableFactory for generating TypedWritable objects.
Definition: bamReader.I:177
BamWriter
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
Definition: bamWriter.h:63
BoundingSphere
This defines a bounding sphere, consisting of a center and a radius.
Definition: boundingSphere.h:25
BoundingVolume
This is an abstract class for any volume in any sense which can be said to define the locality of ref...
Definition: boundingVolume.h:41
CollisionCone
This implements a conical solid consisting a circular base with a pointy tip.
Definition: collisionCone.h:23
CollisionCone::get_collision_origin
virtual LPoint3 get_collision_origin() const
Returns the point in space deemed to be the "origin" of the solid for collision purposes.
Definition: collisionCone.cxx:52
CollisionCone::write_datagram
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Function to write the important information in the particular object to a Datagram.
Definition: collisionCone.cxx:229
CollisionCone::get_volume_pcollector
virtual PStatCollector & get_volume_pcollector()
Returns a PStatCollector that is used to count the number of bounding volume tests made against a sol...
Definition: collisionCone.cxx:61
CollisionCone::register_with_read_factory
static void register_with_read_factory()
Factory method to generate a CollisionCone object.
Definition: collisionCone.cxx:264
CollisionCone::get_test_pcollector
virtual PStatCollector & get_test_pcollector()
Returns a PStatCollector that is used to count the number of intersection tests made against a solid ...
Definition: collisionCone.cxx:70
CollisionCone::xform
virtual void xform(const LMatrix4 &mat)
Transforms the solid by the indicated matrix.
Definition: collisionCone.cxx:42
CollisionEntry
Defines a single collision event.
Definition: collisionEntry.h:42
CollisionEntry::get_from_node_path
get_from_node_path
Returns the NodePath that represents the CollisionNode that contains the CollisionSolid that triggere...
Definition: collisionEntry.h:101
CollisionEntry::get_into_node_path
get_into_node_path
Returns the NodePath that represents the specific CollisionNode or GeomNode instance that was collide...
Definition: collisionEntry.h:102
CollisionEntry::get_from
get_from
Returns the CollisionSolid pointer for the particular solid that triggered this collision.
Definition: collisionEntry.h:97
CollisionSolid
The abstract base class for all things that can collide with other things in the world,...
Definition: collisionSolid.h:45
CollisionSolid::write_datagram
virtual void write_datagram(BamWriter *manager, Datagram &me)
Function to write the important information in the particular object to a Datagram.
Definition: collisionSolid.cxx:345
CollisionSolid::has_effective_normal
bool has_effective_normal() const
Returns true if a special normal was set by set_effective_normal(), false otherwise.
Definition: collisionSolid.I:71
CollisionSolid::get_effective_normal
const LVector3 & get_effective_normal() const
Returns the normal that was set by set_effective_normal().
Definition: collisionSolid.I:81
CollisionSolid::get_respect_effective_normal
get_respect_effective_normal
See set_respect_effective_normal().
Definition: collisionSolid.h:72
CollisionSphere
A spherical collision volume or object.
Definition: collisionSphere.h:25
DatagramIterator
A class to retrieve the individual data elements previously stored in a Datagram.
Definition: datagramIterator.h:27
Datagram
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
Definition: datagram.h:38
FactoryParams
An instance of this class is passed to the Factory when requesting it to do its business and construc...
Definition: factoryParams.h:36
Factory::register_factory
void register_factory(TypeHandle handle, CreateFunc *func, void *user_data=nullptr)
Registers a new kind of thing the Factory will be able to create.
Definition: factory.I:73
GeomLinestrips
Defines a series of line strips.
Definition: geomLinestrips.h:23
GeomTrifans
Defines a series of triangle fans.
Definition: geomTrifans.h:23
GeomVertexData
This defines the actual numeric vertex data stored in a Geom, in the structure defined by a particula...
Definition: geomVertexData.h:68
GeomVertexFormat::get_v3
static const GeomVertexFormat * get_v3()
Returns a standard vertex format with just a 3-component vertex position.
Definition: geomVertexFormat.I:251
GeomVertexWriter
This object provides a high-level interface for quickly writing a sequence of numeric values from a v...
Definition: geomVertexWriter.h:55
Geom
A container for geometry primitives.
Definition: geom.h:54
PStatCollector
A lightweight class that represents a single element that may be timed and/or counted via stats.
Definition: pStatCollector.h:43
TypeHandle
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
TypedWritable
Base class for objects that can be written to and read from Bam files.
Definition: typedWritable.h:35
cmath.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PT
PT(BoundingVolume) CollisionCone
Fills the _viz_geom GeomNode up with Geoms suitable for rendering this solid.
Definition: collisionCone.cxx:85
collisionCone.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
collisionEntry.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
collisionPolygon.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
collisionSphere.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
config_collide.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
geomLinestrips.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
geomTrifans.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
geom.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
mathNumbers.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.