Panda3D
collisionRay.cxx
1 // Filename: collisionRay.cxx
2 // Created by: drose (22Jun00)
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 #include "collisionRay.h"
16 #include "collisionHandler.h"
17 #include "collisionEntry.h"
18 #include "config_collide.h"
19 #include "geom.h"
20 #include "geomNode.h"
21 #include "boundingLine.h"
22 #include "lensNode.h"
23 #include "lens.h"
24 #include "datagram.h"
25 #include "datagramIterator.h"
26 #include "bamReader.h"
27 #include "bamWriter.h"
28 #include "geom.h"
29 #include "geomLinestrips.h"
30 #include "geomVertexWriter.h"
31 
32 TypeHandle CollisionRay::_type_handle;
33 
34 
35 ////////////////////////////////////////////////////////////////////
36 // Function: CollisionRay::make_copy
37 // Access: Public, Virtual
38 // Description:
39 ////////////////////////////////////////////////////////////////////
40 CollisionSolid *CollisionRay::
41 make_copy() {
42  return new CollisionRay(*this);
43 }
44 
45 ////////////////////////////////////////////////////////////////////
46 // Function: CollisionRay::test_intersection
47 // Access: Public, Virtual
48 // Description:
49 ////////////////////////////////////////////////////////////////////
50 PT(CollisionEntry) CollisionRay::
51 test_intersection(const CollisionEntry &entry) const {
52  return entry.get_into()->test_intersection_from_ray(entry);
53 }
54 
55 ////////////////////////////////////////////////////////////////////
56 // Function: CollisionRay::xform
57 // Access: Public, Virtual
58 // Description: Transforms the solid by the indicated matrix.
59 ////////////////////////////////////////////////////////////////////
60 void CollisionRay::
61 xform(const LMatrix4 &mat) {
62  _origin = _origin * mat;
63  _direction = _direction * mat;
64 
65  CollisionSolid::xform(mat);
66 }
67 
68 ////////////////////////////////////////////////////////////////////
69 // Function: CollisionRay::get_collision_origin
70 // Access: Public, Virtual
71 // Description: Returns the point in space deemed to be the "origin"
72 // of the solid for collision purposes. The closest
73 // intersection point to this origin point is considered
74 // to be the most significant.
75 ////////////////////////////////////////////////////////////////////
78  return get_origin();
79 }
80 
81 ////////////////////////////////////////////////////////////////////
82 // Function: CollisionRay::output
83 // Access: Public, Virtual
84 // Description:
85 ////////////////////////////////////////////////////////////////////
86 void CollisionRay::
87 output(ostream &out) const {
88  out << "ray, o (" << get_origin() << "), d (" << get_direction() << ")";
89 }
90 
91 ////////////////////////////////////////////////////////////////////
92 // Function: CollisionRay::set_from_lens
93 // Access: Public
94 // Description: Accepts a LensNode and a 2-d point in the range
95 // [-1,1]. Sets the CollisionRay so that it begins at
96 // the LensNode's near plane and extends to
97 // infinity, making it suitable for picking objects from
98 // the screen given a camera and a mouse location.
99 //
100 // Returns true if the point was acceptable, false
101 // otherwise.
102 ////////////////////////////////////////////////////////////////////
103 bool CollisionRay::
104 set_from_lens(LensNode *camera, const LPoint2 &point) {
105  Lens *lens = camera->get_lens();
106 
107  bool success = true;
108  LPoint3 near_point, far_point;
109  if (!lens->extrude(point, near_point, far_point)) {
110  _origin = LPoint3::origin();
111  _direction = LVector3::forward();
112  success = false;
113  } else {
114  _origin = near_point;
115  _direction = far_point - near_point;
116  }
117 
118  mark_internal_bounds_stale();
119  mark_viz_stale();
120 
121  return success;
122 }
123 
124 ////////////////////////////////////////////////////////////////////
125 // Function: CollisionRay::compute_internal_bounds
126 // Access: Protected, Virtual
127 // Description:
128 ////////////////////////////////////////////////////////////////////
129 PT(BoundingVolume) CollisionRay::
130 compute_internal_bounds() const {
131  return new BoundingLine(_origin, _origin + _direction);
132 }
133 
134 ////////////////////////////////////////////////////////////////////
135 // Function: CollisionRay::fill_viz_geom
136 // Access: Protected, Virtual
137 // Description: Fills the _viz_geom GeomNode up with Geoms suitable
138 // for rendering this solid.
139 ////////////////////////////////////////////////////////////////////
140 void CollisionRay::
141 fill_viz_geom() {
142  if (collide_cat.is_debug()) {
143  collide_cat.debug()
144  << "Recomputing viz for " << *this << "\n";
145  }
146 
147  static const int num_points = 100;
148  static const double scale = 100.0;
149 
150  PT(GeomVertexData) vdata = new GeomVertexData
151  ("collision", GeomVertexFormat::get_v3cp(),
152  Geom::UH_static);
153  GeomVertexWriter vertex(vdata, InternalName::get_vertex());
154  GeomVertexWriter color(vdata, InternalName::get_color());
155 
156  for (int i = 0; i < num_points; i++) {
157  double t = ((double)i / (double)num_points);
158  vertex.add_data3(get_origin() + t * scale * get_direction());
159 
160  color.add_data4(LColor(1.0f, 1.0f, 1.0f, 1.0f) +
161  t * LColor(0.0f, 0.0f, 0.0f, -1.0f));
162  }
163 
164  PT(GeomLinestrips) line = new GeomLinestrips(Geom::UH_static);
165  line->add_next_vertices(num_points);
166  line->close_primitive();
167 
168  PT(Geom) geom = new Geom(vdata);
169  geom->add_primitive(line);
170 
171  _viz_geom->add_geom(geom, get_other_viz_state());
172  _bounds_viz_geom->add_geom(geom, get_other_bounds_viz_state());
173 }
174 
175 ////////////////////////////////////////////////////////////////////
176 // Function: CollisionRay::register_with_read_factory
177 // Access: Public, Static
178 // Description: Tells the BamReader how to create objects of type
179 // CollisionRay.
180 ////////////////////////////////////////////////////////////////////
181 void CollisionRay::
183  BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
184 }
185 
186 ////////////////////////////////////////////////////////////////////
187 // Function: CollisionRay::write_datagram
188 // Access: Public, Virtual
189 // Description: Writes the contents of this object to the datagram
190 // for shipping out to a Bam file.
191 ////////////////////////////////////////////////////////////////////
192 void CollisionRay::
194  CollisionSolid::write_datagram(manager, dg);
195  _origin.write_datagram(dg);
196  _direction.write_datagram(dg);
197 }
198 
199 ////////////////////////////////////////////////////////////////////
200 // Function: CollisionRay::make_from_bam
201 // Access: Protected, Static
202 // Description: This function is called by the BamReader's factory
203 // when a new object of type CollisionRay is encountered
204 // in the Bam file. It should create the CollisionRay
205 // and extract its information from the file.
206 ////////////////////////////////////////////////////////////////////
207 TypedWritable *CollisionRay::
208 make_from_bam(const FactoryParams &params) {
209  CollisionRay *node = new CollisionRay();
210  DatagramIterator scan;
211  BamReader *manager;
212 
213  parse_params(params, scan, manager);
214  node->fillin(scan, manager);
215 
216  return node;
217 }
218 
219 ////////////////////////////////////////////////////////////////////
220 // Function: CollisionRay::fillin
221 // Access: Protected
222 // Description: This internal function is called by make_from_bam to
223 // read in all of the relevant data from the BamFile for
224 // the new CollisionRay.
225 ////////////////////////////////////////////////////////////////////
226 void CollisionRay::
227 fillin(DatagramIterator &scan, BamReader *manager) {
228  CollisionSolid::fillin(scan, manager);
229  _origin.read_datagram(scan);
230  _direction.read_datagram(scan);
231 }
This object provides a high-level interface for quickly writing a sequence of numeric values from a v...
An infinite ray, with a specific origin and direction.
Definition: collisionRay.h:31
virtual LPoint3 get_collision_origin() const
Returns the point in space deemed to be the "origin" of the solid for collision purposes.
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:1389
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
Base class for objects that can be written to and read from Bam files.
Definition: typedWritable.h:37
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:451
void add_data4(PN_stdfloat x, PN_stdfloat y, PN_stdfloat z, PN_stdfloat w)
Sets the write row to a particular 4-component value, and advances the write row. ...
static LVector3f forward(CoordinateSystem cs=CS_default)
Returns the forward vector for the given coordinate system.
Definition: lvector3.h:579
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
This is an abstract class for any volume in any sense which can be said to define the locality of ref...
const CollisionSolid * get_into() const
Returns the CollisionSolid pointer for the particular solid was collided into.
This is a 4-by-4 transform matrix.
Definition: lmatrix.h:451
void write_datagram(Datagram &destination) const
Writes the vector to the Datagram using add_stdfloat().
Definition: lvecBase3.h:1371
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 add_data3(PN_stdfloat x, PN_stdfloat y, PN_stdfloat z)
Sets the write row to a particular 3-component value, and advances the write row. ...
void register_factory(TypeHandle handle, CreateFunc *func)
Registers a new kind of thing the Factory will be able to create.
Definition: factory.I:90
This is the base class for all three-component vectors and points.
Definition: lvecBase4.h:111
static void register_with_read_factory()
Tells the BamReader how to create objects of type CollisionRay.
static WritableFactory * get_factory()
Returns the global WritableFactory for generating TypedWritable objects.
Definition: bamReader.I:213
Defines a series of line strips.
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
A class to retrieve the individual data elements previously stored in a Datagram. ...
bool set_from_lens(LensNode *camera, const LPoint2 &point)
Accepts a LensNode and a 2-d point in the range [-1,1].
This is a two-component point in space.
Definition: lpoint2.h:92
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:85
CollisionRay()
Creates an invalid ray.
Definition: collisionRay.I:25
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
Definition: datagram.h:43
This funny bounding volume is an infinite line with no thickness and extending to infinity in both di...
Definition: boundingLine.h:33
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.