00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "collisionSegment.h"
00017 #include "collisionHandler.h"
00018 #include "collisionEntry.h"
00019 #include "config_collide.h"
00020 #include "geom.h"
00021 #include "lensNode.h"
00022 #include "geomNode.h"
00023 #include "lens.h"
00024 #include "geometricBoundingVolume.h"
00025 #include "datagram.h"
00026 #include "datagramIterator.h"
00027 #include "bamReader.h"
00028 #include "bamWriter.h"
00029 #include "geom.h"
00030 #include "geomLines.h"
00031 #include "boundingHexahedron.h"
00032 #include "geomVertexWriter.h"
00033
00034 TypeHandle CollisionSegment::_type_handle;
00035
00036
00037
00038
00039
00040
00041
00042 CollisionSolid *CollisionSegment::
00043 make_copy() {
00044 return new CollisionSegment(*this);
00045 }
00046
00047
00048
00049
00050
00051
00052 PT(CollisionEntry) CollisionSegment::
00053 test_intersection(const CollisionEntry &entry) const {
00054 return entry.get_into()->test_intersection_from_segment(entry);
00055 }
00056
00057
00058
00059
00060
00061
00062 void CollisionSegment::
00063 xform(const LMatrix4 &mat) {
00064 _a = _a * mat;
00065 _b = _b * mat;
00066
00067 CollisionSolid::xform(mat);
00068 }
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078 LPoint3 CollisionSegment::
00079 get_collision_origin() const {
00080 return get_point_a();
00081 }
00082
00083
00084
00085
00086
00087
00088 void CollisionSegment::
00089 output(ostream &out) const {
00090 out << "segment, a (" << _a << "), b (" << _b << ")";
00091 }
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105 bool CollisionSegment::
00106 set_from_lens(LensNode *camera, const LPoint2 &point) {
00107 Lens *proj = camera->get_lens();
00108
00109 bool success = true;
00110 if (!proj->extrude(point, _a, _b)) {
00111 _a = LPoint3::origin();
00112 _b = _a + LVector3::forward();
00113 success = false;
00114 }
00115
00116 mark_internal_bounds_stale();
00117 mark_viz_stale();
00118
00119 return success;
00120 }
00121
00122
00123
00124
00125
00126
00127 PT(BoundingVolume) CollisionSegment::
00128 compute_internal_bounds() const {
00129
00130 LVector3 pdelta = _b - _a;
00131
00132
00133
00134 PN_stdfloat d2 = pdelta.length_squared();
00135 if (d2 < collision_parabola_bounds_threshold * collision_parabola_bounds_threshold) {
00136 LPoint3 pmid = (_a + _b) * 0.5f;
00137 return new BoundingSphere(pmid, csqrt(d2) * 0.5f);
00138 }
00139
00140 LMatrix4 from_segment;
00141 look_at(from_segment, pdelta, LPoint3(0,0,1), CS_zup_right);
00142 from_segment.set_row(3, _a);
00143
00144 PN_stdfloat max_y = sqrt(d2) + 0.01;
00145 PT(BoundingHexahedron) volume =
00146 new BoundingHexahedron(LPoint3(-0.01, max_y, -0.01), LPoint3(0.01, max_y, -0.01),
00147 LPoint3(0.01, max_y, 0.01), LPoint3(-0.01, max_y, 0.01),
00148 LPoint3(-0.01, -0.01, -0.01), LPoint3(0.01, 0.01, -0.01),
00149 LPoint3(0.01, -0.01, 0.01), LPoint3(-0.01, -0.01, 0.01));
00150
00151 volume->xform(from_segment);
00152 return volume.p();
00153 }
00154
00155
00156
00157
00158
00159
00160
00161 void CollisionSegment::
00162 fill_viz_geom() {
00163 if (collide_cat.is_debug()) {
00164 collide_cat.debug()
00165 << "Recomputing viz for " << *this << "\n";
00166 }
00167
00168 PT(GeomVertexData) vdata = new GeomVertexData
00169 ("collision", GeomVertexFormat::get_v3cp(),
00170 Geom::UH_static);
00171 GeomVertexWriter vertex(vdata, InternalName::get_vertex());
00172
00173 vertex.add_data3(_a);
00174 vertex.add_data3(_b);
00175
00176 PT(GeomLines) line = new GeomLines(Geom::UH_static);
00177 line->add_next_vertices(2);
00178 line->close_primitive();
00179
00180 PT(Geom) geom = new Geom(vdata);
00181 geom->add_primitive(line);
00182
00183 _viz_geom->add_geom(geom, get_other_viz_state());
00184 _bounds_viz_geom->add_geom(geom, get_other_bounds_viz_state());
00185 }
00186
00187
00188
00189
00190
00191
00192
00193 void CollisionSegment::
00194 register_with_read_factory() {
00195 BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
00196 }
00197
00198
00199
00200
00201
00202
00203
00204 void CollisionSegment::
00205 write_datagram(BamWriter *manager, Datagram &dg) {
00206 CollisionSolid::write_datagram(manager, dg);
00207 _a.write_datagram(dg);
00208 _b.write_datagram(dg);
00209 }
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219 TypedWritable *CollisionSegment::
00220 make_from_bam(const FactoryParams ¶ms) {
00221 CollisionSegment *node = new CollisionSegment();
00222 DatagramIterator scan;
00223 BamReader *manager;
00224
00225 parse_params(params, scan, manager);
00226 node->fillin(scan, manager);
00227
00228 return node;
00229 }
00230
00231
00232
00233
00234
00235
00236
00237
00238 void CollisionSegment::
00239 fillin(DatagramIterator &scan, BamReader *manager) {
00240 CollisionSolid::fillin(scan, manager);
00241 _a.read_datagram(scan);
00242 _b.read_datagram(scan);
00243 }