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  */
39 get_collision_origin() const {
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  */
214 write_datagram(BamWriter *manager, Datagram &me) {
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 }
PT
PT(CollisionEntry) CollisionParabola
Transforms the solid by the indicated matrix.
Definition: collisionParabola.cxx:55
Geom
A container for geometry primitives.
Definition: geom.h:54
collisionParabola.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
geomVertexWriter.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
GeomVertexData
This defines the actual numeric vertex data stored in a Geom, in the structure defined by a particula...
Definition: geomVertexData.h:68
BoundingSphere
This defines a bounding sphere, consisting of a center and a radius.
Definition: boundingSphere.h:25
CollisionParabola
This defines a parabolic arc, or subset of an arc, similar to the path of a projectile or falling obj...
Definition: collisionParabola.h:32
CollisionParabola::write_datagram
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Function to write the important information in the particular object to a Datagram.
Definition: collisionParabola.cxx:214
CollisionParabola::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: collisionParabola.cxx:85
CollisionParabola::register_with_read_factory
static void register_with_read_factory()
Factory method to generate a CollisionParabola object.
Definition: collisionParabola.cxx:205
DatagramIterator
A class to retrieve the individual data elements previously stored in a Datagram.
Definition: datagramIterator.h:27
CollisionEntry
Defines a single collision event.
Definition: collisionEntry.h:42
BamReader
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
Definition: bamReader.h:110
BamWriter
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
Definition: bamWriter.h:63
GeomVertexWriter
This object provides a high-level interface for quickly writing a sequence of numeric values from a v...
Definition: geomVertexWriter.h:55
CollisionParabola::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: collisionParabola.cxx:76
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
BamReader::get_factory
static WritableFactory * get_factory()
Returns the global WritableFactory for generating TypedWritable objects.
Definition: bamReader.I:177
bamReader.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
GeomLinestrips
Defines a series of line strips.
Definition: geomLinestrips.h:23
TypedWritable
Base class for objects that can be written to and read from Bam files.
Definition: typedWritable.h:35
Datagram
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
Definition: datagram.h:38
DatagramIterator::get_stdfloat
PN_stdfloat get_stdfloat()
Extracts either a 32-bit or a 64-bit floating-point number, according to Datagram::set_stdfloat_doubl...
Definition: datagramIterator.I:242
Datagram::add_stdfloat
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
TypeHandle
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
FactoryParams
An instance of this class is passed to the Factory when requesting it to do its business and construc...
Definition: factoryParams.h:36
boundingHexahedron.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
boundingSphere.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PStatCollector
A lightweight class that represents a single element that may be timed and/or counted via stats.
Definition: pStatCollector.h:43
CollisionParabola::get_t1
get_t1
Returns the starting point on the parabola.
Definition: collisionParabola.h:65
datagram.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
geom.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
CollisionParabola::CollisionParabola
CollisionParabola()
Creates an invalid parabola.
Definition: collisionParabola.I:18
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
CollisionSolid
The abstract base class for all things that can collide with other things in the world,...
Definition: collisionSolid.h:45
collisionEntry.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
CollisionParabola::get_t2
get_t2
Returns the ending point on the parabola.
Definition: collisionParabola.h:66
geomLinestrips.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
CollisionEntry::get_into
get_into
Returns the CollisionSolid pointer for the particular solid was collided into.
Definition: collisionEntry.h:98
datagramIterator.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
BoundingHexahedron
This defines a bounding convex hexahedron.
Definition: boundingHexahedron.h:32
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
bamWriter.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
look_at.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
GeomVertexFormat::get_v3cp
static const GeomVertexFormat * get_v3cp()
Returns a standard vertex format with a packed color and a 3-component vertex position.
Definition: geomVertexFormat.I:287
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
CollisionParabola::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: collisionParabola.cxx:39