Panda3D
 All Classes Functions Variables Enumerations
collisionSegment.cxx
1 // Filename: collisionSegment.cxx
2 // Created by: drose (30Jan01)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 
16 #include "collisionSegment.h"
17 #include "collisionHandler.h"
18 #include "collisionEntry.h"
19 #include "config_collide.h"
20 #include "geom.h"
21 #include "lensNode.h"
22 #include "geomNode.h"
23 #include "lens.h"
24 #include "geometricBoundingVolume.h"
25 #include "datagram.h"
26 #include "datagramIterator.h"
27 #include "bamReader.h"
28 #include "bamWriter.h"
29 #include "geom.h"
30 #include "geomLines.h"
31 #include "boundingSphere.h"
32 #include "boundingHexahedron.h"
33 #include "geomVertexWriter.h"
34 #include "look_at.h"
35 
36 TypeHandle CollisionSegment::_type_handle;
37 
38 
39 ////////////////////////////////////////////////////////////////////
40 // Function: CollisionSegment::make_copy
41 // Access: Public, Virtual
42 // Description:
43 ////////////////////////////////////////////////////////////////////
44 CollisionSolid *CollisionSegment::
45 make_copy() {
46  return new CollisionSegment(*this);
47 }
48 
49 ////////////////////////////////////////////////////////////////////
50 // Function: CollisionSegment::test_intersection
51 // Access: Public, Virtual
52 // Description:
53 ////////////////////////////////////////////////////////////////////
55 test_intersection(const CollisionEntry &entry) const {
56  return entry.get_into()->test_intersection_from_segment(entry);
57 }
58 
59 ////////////////////////////////////////////////////////////////////
60 // Function: CollisionSegment::xform
61 // Access: Public, Virtual
62 // Description: Transforms the solid by the indicated matrix.
63 ////////////////////////////////////////////////////////////////////
65 xform(const LMatrix4 &mat) {
66  _a = _a * mat;
67  _b = _b * mat;
68 
70 }
71 
72 ////////////////////////////////////////////////////////////////////
73 // Function: CollisionSegment::get_collision_origin
74 // Access: Public, Virtual
75 // Description: Returns the point in space deemed to be the "origin"
76 // of the solid for collision purposes. The closest
77 // intersection point to this origin point is considered
78 // to be the most significant.
79 ////////////////////////////////////////////////////////////////////
82  return get_point_a();
83 }
84 
85 ////////////////////////////////////////////////////////////////////
86 // Function: CollisionSegment::output
87 // Access: Public, Virtual
88 // Description:
89 ////////////////////////////////////////////////////////////////////
90 void CollisionSegment::
91 output(ostream &out) const {
92  out << "segment, a (" << _a << "), b (" << _b << ")";
93 }
94 
95 ////////////////////////////////////////////////////////////////////
96 // Function: CollisionSegment::set_from_lens
97 // Access: Public
98 // Description: Accepts a LensNode and a 2-d point in the range
99 // [-1,1]. Sets the CollisionSegment so that it begins at
100 // the LensNode's near plane and extends to the
101 // far plane, making it suitable for picking objects
102 // from the screen given a camera and a mouse location.
103 //
104 // Returns true if the point was acceptable, false
105 // otherwise.
106 ////////////////////////////////////////////////////////////////////
108 set_from_lens(LensNode *camera, const LPoint2 &point) {
109  Lens *proj = camera->get_lens();
110 
111  bool success = true;
112  if (!proj->extrude(point, _a, _b)) {
113  _a = LPoint3::origin();
114  _b = _a + LVector3::forward();
115  success = false;
116  }
117 
118  mark_internal_bounds_stale();
119  mark_viz_stale();
120 
121  return success;
122 }
123 
124 ////////////////////////////////////////////////////////////////////
125 // Function: CollisionSegment::compute_internal_bounds
126 // Access: Protected, Virtual
127 // Description:
128 ////////////////////////////////////////////////////////////////////
130 compute_internal_bounds() const {
131 
132  LVector3 pdelta = _b - _a;
133 
134  // If p1 and p2 are sufficiently close, just put a sphere around
135  // them.
136  PN_stdfloat d2 = pdelta.length_squared();
137  if (d2 < collision_parabola_bounds_threshold * collision_parabola_bounds_threshold) {
138  LPoint3 pmid = (_a + _b) * 0.5f;
139  return new BoundingSphere(pmid, csqrt(d2) * 0.5f);
140  }
141 
142  LMatrix4 from_segment;
143  look_at(from_segment, pdelta, LPoint3(0,0,1), CS_zup_right);
144  from_segment.set_row(3, _a);
145 
146  PN_stdfloat max_y = sqrt(d2) + 0.01;
147  PT(BoundingHexahedron) volume =
148  new BoundingHexahedron(LPoint3(-0.01, max_y, -0.01), LPoint3(0.01, max_y, -0.01),
149  LPoint3(0.01, max_y, 0.01), LPoint3(-0.01, max_y, 0.01),
150  LPoint3(-0.01, -0.01, -0.01), LPoint3(0.01, 0.01, -0.01),
151  LPoint3(0.01, -0.01, 0.01), LPoint3(-0.01, -0.01, 0.01));
152 
153  volume->xform(from_segment);
154  return volume.p();
155 }
156 
157 ////////////////////////////////////////////////////////////////////
158 // Function: CollisionSegment::fill_viz_geom
159 // Access: Protected, Virtual
160 // Description: Fills the _viz_geom GeomNode up with Geoms suitable
161 // for rendering this solid.
162 ////////////////////////////////////////////////////////////////////
163 void CollisionSegment::
164 fill_viz_geom() {
165  if (collide_cat.is_debug()) {
166  collide_cat.debug()
167  << "Recomputing viz for " << *this << "\n";
168  }
169 
170  PT(GeomVertexData) vdata = new GeomVertexData
171  ("collision", GeomVertexFormat::get_v3cp(),
172  Geom::UH_static);
173  GeomVertexWriter vertex(vdata, InternalName::get_vertex());
174 
175  vertex.add_data3(_a);
176  vertex.add_data3(_b);
177 
178  PT(GeomLines) line = new GeomLines(Geom::UH_static);
179  line->add_next_vertices(2);
180  line->close_primitive();
181 
182  PT(Geom) geom = new Geom(vdata);
183  geom->add_primitive(line);
184 
185  _viz_geom->add_geom(geom, get_other_viz_state());
186  _bounds_viz_geom->add_geom(geom, get_other_bounds_viz_state());
187 }
188 
189 ////////////////////////////////////////////////////////////////////
190 // Function: CollisionSegment::register_with_read_factory
191 // Access: Public, Static
192 // Description: Tells the BamReader how to create objects of type
193 // CollisionSegment.
194 ////////////////////////////////////////////////////////////////////
195 void CollisionSegment::
196 register_with_read_factory() {
197  BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
198 }
199 
200 ////////////////////////////////////////////////////////////////////
201 // Function: CollisionSegment::write_datagram
202 // Access: Public, Virtual
203 // Description: Writes the contents of this object to the datagram
204 // for shipping out to a Bam file.
205 ////////////////////////////////////////////////////////////////////
208  CollisionSolid::write_datagram(manager, dg);
209  _a.write_datagram(dg);
210  _b.write_datagram(dg);
211 }
212 
213 ////////////////////////////////////////////////////////////////////
214 // Function: CollisionSegment::make_from_bam
215 // Access: Protected, Static
216 // Description: This function is called by the BamReader's factory
217 // when a new object of type CollisionSegment is encountered
218 // in the Bam file. It should create the CollisionSegment
219 // and extract its information from the file.
220 ////////////////////////////////////////////////////////////////////
221 TypedWritable *CollisionSegment::
222 make_from_bam(const FactoryParams &params) {
223  CollisionSegment *node = new CollisionSegment();
224  DatagramIterator scan;
225  BamReader *manager;
226 
227  parse_params(params, scan, manager);
228  node->fillin(scan, manager);
229 
230  return node;
231 }
232 
233 ////////////////////////////////////////////////////////////////////
234 // Function: CollisionSegment::fillin
235 // Access: Protected
236 // Description: This internal function is called by make_from_bam to
237 // read in all of the relevant data from the BamFile for
238 // the new CollisionSegment.
239 ////////////////////////////////////////////////////////////////////
240 void CollisionSegment::
241 fillin(DatagramIterator &scan, BamReader *manager) {
242  CollisionSolid::fillin(scan, manager);
243  _a.read_datagram(scan);
244  _b.read_datagram(scan);
245 }
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
bool set_from_lens(LensNode *camera, const LPoint2 &point)
Accepts a LensNode and a 2-d point in the range [-1,1].
This object provides a high-level interface for quickly writing a sequence of numeric values from a v...
A base class for any number of different kinds of lenses, linear and otherwise.
Definition: lens.h:45
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
Definition: bamReader.h:122
void read_datagram(DatagramIterator &source)
Reads the vector from the Datagram using get_stdfloat().
Definition: lvecBase3.h:1373
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).
A node that contains a Lens.
Definition: lensNode.h:32
CollisionSegment()
Creates an invalid segment.
This defines a bounding sphere, consisting of a center and a radius.
virtual void xform(const LMatrix4 &mat)
Transforms the solid by the indicated matrix.
Base class for objects that can be written to and read from Bam files.
Definition: typedWritable.h:37
float length_squared() const
Returns the square of the vector&#39;s length, cheap and easy.
Definition: lvecBase3.h:748
This is a three-component vector distance (as opposed to a three-component point, which represents a ...
Definition: lvector3.h:100
This is a three-component point in space (as opposed to a three-component vector, which represents a ...
Definition: lpoint3.h:99
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
Definition: bamWriter.h:73
virtual void write_datagram(BamWriter *manager, Datagram &me)
Function to write the important information in the particular object to a Datagram.
static const LPoint3f & origin(CoordinateSystem cs=CS_default)
Returns the origin of the indicated coordinate system.
Definition: lpoint3.h:438
static LVector3f forward(CoordinateSystem cs=CS_default)
Returns the forward vector for the given coordinate system.
Definition: lvector3.h:565
bool extrude(const LPoint2 &point2d, LPoint3 &near_point, LPoint3 &far_point) const
Given a 2-d point in the range (-1,1) in both dimensions, where (0,0) is the center of the lens and (...
Definition: lens.I:32
This is an abstract class for any volume in any sense which can be said to define the locality of ref...
A finite line segment, with two specific endpoints but no thickness.
This is a 4-by-4 transform matrix.
Definition: lmatrix.h:451
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:58
An instance of this class is passed to the Factory when requesting it to do its business and construc...
Definition: factoryParams.h:40
void register_factory(TypeHandle handle, CreateFunc *func)
Registers a new kind of thing the Factory will be able to create.
Definition: factory.I:90
Defines a series of disconnected line segments.
Definition: geomLines.h:25
static WritableFactory * get_factory()
Returns the global WritableFactory for generating TypedWritable objects.
Definition: bamReader.I:213
virtual void xform(const LMatrix4 &mat)
Transforms the solid by the indicated matrix.
void set_row(int row, const LVecBase4f &v)
Replaces the indicated row of the matrix.
Definition: lmatrix.h:1187
A class to retrieve the individual data elements previously stored in a Datagram. ...
This is a two-component point in space.
Definition: lpoint2.h:92
virtual LPoint3 get_collision_origin() const
Returns the point in space deemed to be the &quot;origin&quot; of the solid for collision purposes.
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:85
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
Definition: datagram.h:43
void write_datagram(Datagram &destination) const
Writes the vector to the Datagram using add_stdfloat().
Definition: lvecBase3.h:1355
This defines a bounding convex hexahedron.
Lens * get_lens(int index=0) const
Returns a pointer to the particular Lens associated with this LensNode, or NULL if there is not yet a...
Definition: lensNode.I:60