Panda3D
Loading...
Searching...
No Matches
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
27PStatCollector CollisionParabola::_volume_pcollector(
28 "Collision Volumes:CollisionParabola");
29PStatCollector CollisionParabola::_test_pcollector(
30 "Collision Tests:CollisionParabola");
31TypeHandle 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 */
40 return _parabola.calc_point(_t1);
41}
42
43/**
44 *
45 */
46CollisionSolid *CollisionParabola::
47make_copy() {
48 return new CollisionParabola(*this);
49}
50
51
52/**
53 *
54 */
55PT(CollisionEntry) CollisionParabola::
56test_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 */
63void CollisionParabola::
64xform(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 */
92void CollisionParabola::
93output(std::ostream &out) const {
94 out << _parabola << ", t1 = " << _t1 << ", t2 = " << _t2;
95}
96
97/**
98 *
99 */
100PT(BoundingVolume) CollisionParabola::
101compute_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 */
167void CollisionParabola::
168fill_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 */
214write_datagram(BamWriter *manager, Datagram &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 */
224TypedWritable *CollisionParabola::
225make_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 */
240void CollisionParabola::
241fillin(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}
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
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.
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
static WritableFactory * get_factory()
Returns the global WritableFactory for generating TypedWritable objects.
Definition bamReader.I:177
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
Definition bamWriter.h:63
This defines a bounding convex hexahedron.
This defines a bounding sphere, consisting of a center and a radius.
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_into
Returns the CollisionSolid pointer for the particular solid was collided into.
This defines a parabolic arc, or subset of an arc, similar to the path of a projectile or falling obj...
get_t1
Returns the starting point on the parabola.
static void register_with_read_factory()
Factory method to generate a CollisionParabola object.
virtual PStatCollector & get_test_pcollector()
Returns a PStatCollector that is used to count the number of intersection tests made against a solid ...
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 &dg)
Function to write the important information in the particular object to a Datagram.
get_t2
Returns the ending point on the parabola.
CollisionParabola()
Creates an invalid parabola.
virtual LPoint3 get_collision_origin() const
Returns the point in space deemed to be the "origin" of the solid for collision purposes.
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.
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...
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
Definition datagram.h:38
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
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.
Definition factory.I:73
Defines a series of line strips.
This defines the actual numeric vertex data stored in a Geom, in the structure defined by a particula...
static const GeomVertexFormat * get_v3cp()
Returns a standard vertex format with a packed color and a 3-component vertex position.
This object provides a high-level interface for quickly writing a sequence of numeric values from a v...
A container for geometry primitives.
Definition geom.h:54
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.
Definition typeHandle.h:81
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.