Panda3D
|
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 ¶ms) { 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 }