Panda3D

collisionRay.cxx

00001 // Filename: collisionRay.cxx
00002 // Created by:  drose (22Jun00)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 #include "collisionRay.h"
00016 #include "collisionHandler.h"
00017 #include "collisionEntry.h"
00018 #include "config_collide.h"
00019 #include "geom.h"
00020 #include "geomNode.h"
00021 #include "boundingLine.h"
00022 #include "lensNode.h"
00023 #include "lens.h"
00024 #include "datagram.h"
00025 #include "datagramIterator.h"
00026 #include "bamReader.h"
00027 #include "bamWriter.h"
00028 #include "geom.h"
00029 #include "geomLinestrips.h"
00030 #include "geomVertexWriter.h"
00031 
00032 TypeHandle CollisionRay::_type_handle;
00033 
00034 
00035 ////////////////////////////////////////////////////////////////////
00036 //     Function: CollisionRay::make_copy
00037 //       Access: Public, Virtual
00038 //  Description:
00039 ////////////////////////////////////////////////////////////////////
00040 CollisionSolid *CollisionRay::
00041 make_copy() {
00042   return new CollisionRay(*this);
00043 }
00044 
00045 ////////////////////////////////////////////////////////////////////
00046 //     Function: CollisionRay::test_intersection
00047 //       Access: Public, Virtual
00048 //  Description:
00049 ////////////////////////////////////////////////////////////////////
00050 PT(CollisionEntry) CollisionRay::
00051 test_intersection(const CollisionEntry &entry) const {
00052   return entry.get_into()->test_intersection_from_ray(entry);
00053 }
00054 
00055 ////////////////////////////////////////////////////////////////////
00056 //     Function: CollisionRay::xform
00057 //       Access: Public, Virtual
00058 //  Description: Transforms the solid by the indicated matrix.
00059 ////////////////////////////////////////////////////////////////////
00060 void CollisionRay::
00061 xform(const LMatrix4 &mat) {
00062   _origin = _origin * mat;
00063   _direction = _direction * mat;
00064 
00065   CollisionSolid::xform(mat);
00066 }
00067 
00068 ////////////////////////////////////////////////////////////////////
00069 //     Function: CollisionRay::get_collision_origin
00070 //       Access: Public, Virtual
00071 //  Description: Returns the point in space deemed to be the "origin"
00072 //               of the solid for collision purposes.  The closest
00073 //               intersection point to this origin point is considered
00074 //               to be the most significant.
00075 ////////////////////////////////////////////////////////////////////
00076 LPoint3 CollisionRay::
00077 get_collision_origin() const {
00078   return get_origin();
00079 }
00080 
00081 ////////////////////////////////////////////////////////////////////
00082 //     Function: CollisionRay::output
00083 //       Access: Public, Virtual
00084 //  Description:
00085 ////////////////////////////////////////////////////////////////////
00086 void CollisionRay::
00087 output(ostream &out) const {
00088   out << "ray, o (" << get_origin() << "), d (" << get_direction() << ")";
00089 }
00090 
00091 ////////////////////////////////////////////////////////////////////
00092 //     Function: CollisionRay::set_from_lens
00093 //       Access: Public
00094 //  Description: Accepts a LensNode and a 2-d point in the range
00095 //               [-1,1].  Sets the CollisionRay so that it begins at
00096 //               the LensNode's near plane and extends to
00097 //               infinity, making it suitable for picking objects from
00098 //               the screen given a camera and a mouse location.
00099 //
00100 //               Returns true if the point was acceptable, false
00101 //               otherwise.
00102 ////////////////////////////////////////////////////////////////////
00103 bool CollisionRay::
00104 set_from_lens(LensNode *camera, const LPoint2 &point) {
00105   Lens *lens = camera->get_lens();
00106 
00107   bool success = true;
00108   LPoint3 near_point, far_point;
00109   if (!lens->extrude(point, near_point, far_point)) {
00110     _origin = LPoint3::origin();
00111     _direction = LVector3::forward();
00112     success = false;
00113   } else {
00114     _origin = near_point;
00115     _direction = far_point - near_point;
00116   }
00117 
00118   mark_internal_bounds_stale();
00119   mark_viz_stale();
00120 
00121   return success;
00122 }
00123 
00124 ////////////////////////////////////////////////////////////////////
00125 //     Function: CollisionRay::compute_internal_bounds
00126 //       Access: Protected, Virtual
00127 //  Description:
00128 ////////////////////////////////////////////////////////////////////
00129 PT(BoundingVolume) CollisionRay::
00130 compute_internal_bounds() const {
00131   return new BoundingLine(_origin, _origin + _direction);
00132 }
00133 
00134 ////////////////////////////////////////////////////////////////////
00135 //     Function: CollisionRay::fill_viz_geom
00136 //       Access: Protected, Virtual
00137 //  Description: Fills the _viz_geom GeomNode up with Geoms suitable
00138 //               for rendering this solid.
00139 ////////////////////////////////////////////////////////////////////
00140 void CollisionRay::
00141 fill_viz_geom() {
00142   if (collide_cat.is_debug()) {
00143     collide_cat.debug()
00144       << "Recomputing viz for " << *this << "\n";
00145   }
00146 
00147   static const int num_points = 100;
00148   static const double scale = 100.0;
00149 
00150   PT(GeomVertexData) vdata = new GeomVertexData
00151     ("collision", GeomVertexFormat::get_v3cp(),
00152      Geom::UH_static);
00153   GeomVertexWriter vertex(vdata, InternalName::get_vertex());
00154   GeomVertexWriter color(vdata, InternalName::get_color());
00155   
00156   for (int i = 0; i < num_points; i++) {
00157     double t = ((double)i / (double)num_points);
00158     vertex.add_data3(get_origin() + t * scale * get_direction());
00159     
00160     color.add_data4(LColor(1.0f, 1.0f, 1.0f, 1.0f) +
00161                     t * LColor(0.0f, 0.0f, 0.0f, -1.0f));
00162   }
00163 
00164   PT(GeomLinestrips) line = new GeomLinestrips(Geom::UH_static);
00165   line->add_next_vertices(num_points);
00166   line->close_primitive();
00167   
00168   PT(Geom) geom = new Geom(vdata);
00169   geom->add_primitive(line);
00170   
00171   _viz_geom->add_geom(geom, get_other_viz_state());
00172   _bounds_viz_geom->add_geom(geom, get_other_bounds_viz_state());
00173 }
00174 
00175 ////////////////////////////////////////////////////////////////////
00176 //     Function: CollisionRay::register_with_read_factory
00177 //       Access: Public, Static
00178 //  Description: Tells the BamReader how to create objects of type
00179 //               CollisionRay.
00180 ////////////////////////////////////////////////////////////////////
00181 void CollisionRay::
00182 register_with_read_factory() {
00183   BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
00184 }
00185 
00186 ////////////////////////////////////////////////////////////////////
00187 //     Function: CollisionRay::write_datagram
00188 //       Access: Public, Virtual
00189 //  Description: Writes the contents of this object to the datagram
00190 //               for shipping out to a Bam file.
00191 ////////////////////////////////////////////////////////////////////
00192 void CollisionRay::
00193 write_datagram(BamWriter *manager, Datagram &dg) {
00194   CollisionSolid::write_datagram(manager, dg);
00195   _origin.write_datagram(dg);
00196   _direction.write_datagram(dg);
00197 }
00198 
00199 ////////////////////////////////////////////////////////////////////
00200 //     Function: CollisionRay::make_from_bam
00201 //       Access: Protected, Static
00202 //  Description: This function is called by the BamReader's factory
00203 //               when a new object of type CollisionRay is encountered
00204 //               in the Bam file.  It should create the CollisionRay
00205 //               and extract its information from the file.
00206 ////////////////////////////////////////////////////////////////////
00207 TypedWritable *CollisionRay::
00208 make_from_bam(const FactoryParams &params) {
00209   CollisionRay *node = new CollisionRay();
00210   DatagramIterator scan;
00211   BamReader *manager;
00212 
00213   parse_params(params, scan, manager);
00214   node->fillin(scan, manager);
00215 
00216   return node;
00217 }
00218 
00219 ////////////////////////////////////////////////////////////////////
00220 //     Function: CollisionRay::fillin
00221 //       Access: Protected
00222 //  Description: This internal function is called by make_from_bam to
00223 //               read in all of the relevant data from the BamFile for
00224 //               the new CollisionRay.
00225 ////////////////////////////////////////////////////////////////////
00226 void CollisionRay::
00227 fillin(DatagramIterator &scan, BamReader *manager) {
00228   CollisionSolid::fillin(scan, manager);
00229   _origin.read_datagram(scan);
00230   _direction.read_datagram(scan);
00231 }
 All Classes Functions Variables Enumerations