Panda3D
collisionParabola.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 collisionParabola.cxx
10  * @author drose
11  * @date 2007-10-11
12  */
13 
14 #include "collisionParabola.h"
15 #include "collisionEntry.h"
16 #include "datagram.h"
17 #include "datagramIterator.h"
18 #include "bamReader.h"
19 #include "bamWriter.h"
20 #include "geom.h"
21 #include "geomLinestrips.h"
22 #include "geomVertexWriter.h"
23 #include "boundingHexahedron.h"
24 #include "boundingSphere.h"
25 #include "look_at.h"
26 
27 PStatCollector CollisionParabola::_volume_pcollector(
28  "Collision Volumes:CollisionParabola");
29 PStatCollector CollisionParabola::_test_pcollector(
30  "Collision Tests:CollisionParabola");
31 TypeHandle CollisionParabola::_type_handle;
32 
33 /**
34  * Returns the point in space deemed to be the "origin" of the solid for
35  * collision purposes. The closest intersection point to this origin point is
36  * considered to be the most significant.
37  */
38 LPoint3 CollisionParabola::
40  return _parabola.calc_point(_t1);
41 }
42 
43 /**
44  *
45  */
46 CollisionSolid *CollisionParabola::
47 make_copy() {
48  return new CollisionParabola(*this);
49 }
50 
51 
52 /**
53  *
54  */
55 PT(CollisionEntry) CollisionParabola::
56 test_intersection(const CollisionEntry &entry) const {
57  return entry.get_into()->test_intersection_from_parabola(entry);
58 }
59 
60 /**
61  * Transforms the solid by the indicated matrix.
62  */
63 void CollisionParabola::
64 xform(const LMatrix4 &mat) {
65  _parabola.xform(mat);
66 
67  mark_viz_stale();
68  mark_internal_bounds_stale();
69 }
70 
71 /**
72  * Returns a PStatCollector that is used to count the number of bounding
73  * volume tests made against a solid of this type in a given frame.
74  */
77  return _volume_pcollector;
78 }
79 
80 /**
81  * Returns a PStatCollector that is used to count the number of intersection
82  * tests made against a solid of this type in a given frame.
83  */
86  return _test_pcollector;
87 }
88 
89 /**
90  *
91  */
92 void CollisionParabola::
93 output(std::ostream &out) const {
94  out << _parabola << ", t1 = " << _t1 << ", t2 = " << _t2;
95 }
96 
97 /**
98  *
99  */
100 PT(BoundingVolume) CollisionParabola::
101 compute_internal_bounds() const {
102  LPoint3 p1 = _parabola.calc_point(get_t1());
103  LPoint3 p2 = _parabola.calc_point(get_t2());
104  LVector3 pdelta = p2 - p1;
105 
106  // If p1 and p2 are sufficiently close, just put a sphere around them.
107  PN_stdfloat d2 = pdelta.length_squared();
108  if (d2 < collision_parabola_bounds_threshold * collision_parabola_bounds_threshold) {
109  LPoint3 pmid = (p1 + p2) * 0.5f;
110  return new BoundingSphere(pmid, csqrt(d2) * 0.5f);
111  }
112 
113  // OK, the more general bounding volume. We use BoundingHexahedron to
114  // define a very thin box that roughly bounds the parabola's arc. We must
115  // use BoundingHexahedron instead of BoundingBox, because the box will not
116  // be axis-aligned, and might be inflated too large if we insist on using
117  // the axis-aligned BoundingBox.
118 
119  // We first define "parabola space" as a coordinate space such that the YZ
120  // plane of parabola space corresponds to the plane of the parabola.
121 
122  // We have to be explicit about the coordinate system--we specifically mean
123  // CS_zup_right here, to make the YZ plane.
124 
125  LMatrix4 from_parabola;
126  look_at(from_parabola, pdelta, -_parabola.get_a(), CS_zup_right);
127  from_parabola.set_row(3, p1);
128 
129  // The matrix that computes from world space to parabola space is the
130  // inverse of that which we just computed.
131  LMatrix4 to_parabola;
132  to_parabola.invert_from(from_parabola);
133 
134  // Now convert the parabola itself into parabola space.
135  LParabola psp = _parabola;
136  psp.xform(to_parabola);
137 
138  LPoint3 pp2 = psp.calc_point(get_t2());
139  PN_stdfloat max_y = pp2[1];
140 
141  // We compute a few points along the parabola to attempt to get the minmax.
142  PN_stdfloat min_z = 0.0f;
143  PN_stdfloat max_z = 0.0f;
144  int num_points = collision_parabola_bounds_sample;
145  for (int i = 0; i < num_points; ++i) {
146  double t = (double)(i + 1) / (double)(num_points + 1);
147  LPoint3 p = psp.calc_point(get_t1() + t * (get_t2() - get_t1()));
148  min_z = std::min(min_z, p[2]);
149  max_z = std::max(max_z, p[2]);
150  }
151 
152  // That gives us a simple bounding volume in parabola space.
153  PT(BoundingHexahedron) volume =
154  new BoundingHexahedron(LPoint3(-0.01, max_y, min_z), LPoint3(0.01, max_y, min_z),
155  LPoint3(0.01, max_y, max_z), LPoint3(-0.01, max_y, max_z),
156  LPoint3(-0.01, 0, min_z), LPoint3(0.01, 0, min_z),
157  LPoint3(0.01, 0, max_z), LPoint3(-0.01, 0, max_z));
158  // And convert that back into real space.
159  volume->xform(from_parabola);
160  return volume;
161 }
162 
163 /**
164  * Fills the _viz_geom GeomNode up with Geoms suitable for rendering this
165  * solid.
166  */
167 void CollisionParabola::
168 fill_viz_geom() {
169  if (collide_cat.is_debug()) {
170  collide_cat.debug()
171  << "Recomputing viz for " << *this << "\n";
172  }
173 
174  static const int num_points = 100;
175 
176  PT(GeomVertexData) vdata = new GeomVertexData
177  ("collision", GeomVertexFormat::get_v3cp(),
178  Geom::UH_static);
179  GeomVertexWriter vertex(vdata, InternalName::get_vertex());
180  GeomVertexWriter color(vdata, InternalName::get_color());
181 
182  for (int i = 0; i < num_points; i++) {
183  double t = ((double)i / (double)num_points);
184  vertex.add_data3(_parabola.calc_point(_t1 + t * (_t2 - _t1)));
185 
186  color.add_data4(LColor(1.0f, 1.0f, 1.0f, 0.0f) +
187  t * LColor(0.0f, 0.0f, 0.0f, 1.0f));
188  }
189 
190  PT(GeomLinestrips) line = new GeomLinestrips(Geom::UH_static);
191  line->add_next_vertices(num_points);
192  line->close_primitive();
193 
194  PT(Geom) geom = new Geom(vdata);
195  geom->add_primitive(line);
196 
197  _viz_geom->add_geom(geom, get_other_viz_state());
198  _bounds_viz_geom->add_geom(geom, get_other_bounds_viz_state());
199 }
200 
201 /**
202  * Factory method to generate a CollisionParabola object
203  */
206  BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
207 }
208 
209 /**
210  * Function to write the important information in the particular object to a
211  * Datagram
212  */
215  CollisionSolid::write_datagram(manager, me);
216  _parabola.write_datagram(me);
217  me.add_stdfloat(_t1);
218  me.add_stdfloat(_t2);
219 }
220 
221 /**
222  * Factory method to generate a CollisionParabola object
223  */
224 TypedWritable *CollisionParabola::
225 make_from_bam(const FactoryParams &params) {
227  DatagramIterator scan;
228  BamReader *manager;
229 
230  parse_params(params, scan, manager);
231  me->fillin(scan, manager);
232  return me;
233 }
234 
235 /**
236  * Function that reads out of the datagram (or asks manager to read) all of
237  * the data that is needed to re-create this object and stores it in the
238  * appropiate place
239  */
240 void CollisionParabola::
241 fillin(DatagramIterator& scan, BamReader* manager) {
242  CollisionSolid::fillin(scan, manager);
243  _parabola.read_datagram(scan);
244  _t1 = scan.get_stdfloat();
245  _t2 = scan.get_stdfloat();
246 }
This object provides a high-level interface for quickly writing a sequence of numeric values from a v...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PN_stdfloat get_stdfloat()
Extracts either a 32-bit or a 64-bit floating-point number, according to Datagram::set_stdfloat_doubl...
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...
Definition: bamReader.h:110
The abstract base class for all things that can collide with other things in the world,...
static const GeomVertexFormat * get_v3cp()
Returns a standard vertex format with a packed color and a 3-component vertex position.
This defines a bounding sphere, consisting of a center and a radius.
virtual PStatCollector & get_volume_pcollector()
Returns a PStatCollector that is used to count the number of bounding volume tests made against a sol...
Base class for objects that can be written to and read from Bam files.
Definition: typedWritable.h:35
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
Definition: bamWriter.h:63
virtual void write_datagram(BamWriter *manager, Datagram &me)
Function to write the important information in the particular object to a Datagram.
void add_stdfloat(PN_stdfloat value)
Adds either a 32-bit or a 64-bit floating-point number, according to set_stdfloat_double().
Definition: datagram.I:133
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.
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
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
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.
Definition: geom.h:54
An instance of this class is passed to the Factory when requesting it to do its business and construc...
Definition: factoryParams.h:36
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
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
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
static WritableFactory * get_factory()
Returns the global WritableFactory for generating TypedWritable objects.
Definition: bamReader.I:177
get_into
Returns the CollisionSolid pointer for the particular solid was collided into.
CollisionParabola()
Creates an invalid parabola.
This defines a parabolic arc, or subset of an arc, similar to the path of a projectile or falling obj...
Defines a series of line strips.
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Function to write the important information in the particular object to a Datagram.
static void register_with_read_factory()
Factory method to generate a CollisionParabola object.
A class to retrieve the individual data elements previously stored in a Datagram.
virtual LPoint3 get_collision_origin() const
Returns the point in space deemed to be the "origin" of the solid for collision purposes.
PT(CollisionEntry) CollisionParabola
Transforms the solid by the indicated matrix.
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
virtual PStatCollector & get_test_pcollector()
Returns a PStatCollector that is used to count the number of intersection tests made against a solid ...
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
Definition: datagram.h:38
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This defines a bounding convex hexahedron.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.