00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
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
00037
00038
00039
00040 CollisionSolid *CollisionRay::
00041 make_copy() {
00042 return new CollisionRay(*this);
00043 }
00044
00045
00046
00047
00048
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
00057
00058
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
00070
00071
00072
00073
00074
00075
00076 LPoint3 CollisionRay::
00077 get_collision_origin() const {
00078 return get_origin();
00079 }
00080
00081
00082
00083
00084
00085
00086 void CollisionRay::
00087 output(ostream &out) const {
00088 out << "ray, o (" << get_origin() << "), d (" << get_direction() << ")";
00089 }
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
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
00126
00127
00128
00129 PT(BoundingVolume) CollisionRay::
00130 compute_internal_bounds() const {
00131 return new BoundingLine(_origin, _origin + _direction);
00132 }
00133
00134
00135
00136
00137
00138
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
00177
00178
00179
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
00188
00189
00190
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
00201
00202
00203
00204
00205
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
00221
00222
00223
00224
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 }