00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "collisionParabola.h"
00016 #include "collisionEntry.h"
00017 #include "datagram.h"
00018 #include "datagramIterator.h"
00019 #include "bamReader.h"
00020 #include "bamWriter.h"
00021 #include "geom.h"
00022 #include "geomLinestrips.h"
00023 #include "geomVertexWriter.h"
00024 #include "boundingHexahedron.h"
00025 #include "look_at.h"
00026
00027 PStatCollector CollisionParabola::_volume_pcollector(
00028 "Collision Volumes:CollisionParabola");
00029 PStatCollector CollisionParabola::_test_pcollector(
00030 "Collision Tests:CollisionParabola");
00031 TypeHandle CollisionParabola::_type_handle;
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 LPoint3 CollisionParabola::
00042 get_collision_origin() const {
00043 return _parabola.calc_point(_t1);
00044 }
00045
00046
00047
00048
00049
00050
00051 CollisionSolid *CollisionParabola::
00052 make_copy() {
00053 return new CollisionParabola(*this);
00054 }
00055
00056
00057
00058
00059
00060
00061
00062 PT(CollisionEntry) CollisionParabola::
00063 test_intersection(const CollisionEntry &entry) const {
00064 return entry.get_into()->test_intersection_from_parabola(entry);
00065 }
00066
00067
00068
00069
00070
00071
00072 void CollisionParabola::
00073 xform(const LMatrix4 &mat) {
00074 _parabola.xform(mat);
00075
00076 mark_viz_stale();
00077 mark_internal_bounds_stale();
00078 }
00079
00080
00081
00082
00083
00084
00085
00086
00087 PStatCollector &CollisionParabola::
00088 get_volume_pcollector() {
00089 return _volume_pcollector;
00090 }
00091
00092
00093
00094
00095
00096
00097
00098
00099 PStatCollector &CollisionParabola::
00100 get_test_pcollector() {
00101 return _test_pcollector;
00102 }
00103
00104
00105
00106
00107
00108
00109 void CollisionParabola::
00110 output(ostream &out) const {
00111 out << _parabola << ", t1 = " << _t1 << ", t2 = " << _t2;
00112 }
00113
00114
00115
00116
00117
00118
00119 PT(BoundingVolume) CollisionParabola::
00120 compute_internal_bounds() const {
00121 LPoint3 p1 = _parabola.calc_point(get_t1());
00122 LPoint3 p2 = _parabola.calc_point(get_t2());
00123 LVector3 pdelta = p2 - p1;
00124
00125
00126
00127 PN_stdfloat d2 = pdelta.length_squared();
00128 if (d2 < collision_parabola_bounds_threshold * collision_parabola_bounds_threshold) {
00129 LPoint3 pmid = (p1 + p2) * 0.5f;
00130 return new BoundingSphere(pmid, csqrt(d2) * 0.5f);
00131 }
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146 LMatrix4 from_parabola;
00147 look_at(from_parabola, pdelta, -_parabola.get_a(), CS_zup_right);
00148 from_parabola.set_row(3, p1);
00149
00150
00151
00152 LMatrix4 to_parabola;
00153 to_parabola.invert_from(from_parabola);
00154
00155
00156 LParabola psp = _parabola;
00157 psp.xform(to_parabola);
00158
00159 LPoint3 pp2 = psp.calc_point(get_t2());
00160 PN_stdfloat max_y = pp2[1];
00161
00162
00163
00164 PN_stdfloat min_z = 0.0f;
00165 PN_stdfloat max_z = 0.0f;
00166 int num_points = collision_parabola_bounds_sample;
00167 for (int i = 0; i < num_points; ++i) {
00168 double t = (double)(i + 1) / (double)(num_points + 1);
00169 LPoint3 p = psp.calc_point(get_t1() + t * (get_t2() - get_t1()));
00170 min_z = min(min_z, p[2]);
00171 max_z = max(max_z, p[2]);
00172 }
00173
00174
00175 PT(BoundingHexahedron) volume =
00176 new BoundingHexahedron(LPoint3(-0.01, max_y, min_z), LPoint3(0.01, max_y, min_z),
00177 LPoint3(0.01, max_y, max_z), LPoint3(-0.01, max_y, max_z),
00178 LPoint3(-0.01, 0, min_z), LPoint3(0.01, 0, min_z),
00179 LPoint3(0.01, 0, max_z), LPoint3(-0.01, 0, max_z));
00180
00181 volume->xform(from_parabola);
00182 return volume.p();
00183 }
00184
00185
00186
00187
00188
00189
00190
00191 void CollisionParabola::
00192 fill_viz_geom() {
00193 if (collide_cat.is_debug()) {
00194 collide_cat.debug()
00195 << "Recomputing viz for " << *this << "\n";
00196 }
00197
00198 static const int num_points = 100;
00199
00200 PT(GeomVertexData) vdata = new GeomVertexData
00201 ("collision", GeomVertexFormat::get_v3cp(),
00202 Geom::UH_static);
00203 GeomVertexWriter vertex(vdata, InternalName::get_vertex());
00204 GeomVertexWriter color(vdata, InternalName::get_color());
00205
00206 for (int i = 0; i < num_points; i++) {
00207 double t = ((double)i / (double)num_points);
00208 vertex.add_data3(_parabola.calc_point(_t1 + t * (_t2 - _t1)));
00209
00210 color.add_data4(LColor(1.0f, 1.0f, 1.0f, 0.0f) +
00211 t * LColor(0.0f, 0.0f, 0.0f, 1.0f));
00212 }
00213
00214 PT(GeomLinestrips) line = new GeomLinestrips(Geom::UH_static);
00215 line->add_next_vertices(num_points);
00216 line->close_primitive();
00217
00218 PT(Geom) geom = new Geom(vdata);
00219 geom->add_primitive(line);
00220
00221 _viz_geom->add_geom(geom, get_other_viz_state());
00222 _bounds_viz_geom->add_geom(geom, get_other_bounds_viz_state());
00223 }
00224
00225
00226
00227
00228
00229
00230 void CollisionParabola::
00231 register_with_read_factory() {
00232 BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
00233 }
00234
00235
00236
00237
00238
00239
00240
00241 void CollisionParabola::
00242 write_datagram(BamWriter *manager, Datagram &me) {
00243 CollisionSolid::write_datagram(manager, me);
00244 _parabola.write_datagram(me);
00245 me.add_stdfloat(_t1);
00246 me.add_stdfloat(_t2);
00247 }
00248
00249
00250
00251
00252
00253
00254 TypedWritable *CollisionParabola::
00255 make_from_bam(const FactoryParams ¶ms) {
00256 CollisionParabola *me = new CollisionParabola;
00257 DatagramIterator scan;
00258 BamReader *manager;
00259
00260 parse_params(params, scan, manager);
00261 me->fillin(scan, manager);
00262 return me;
00263 }
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273 void CollisionParabola::
00274 fillin(DatagramIterator& scan, BamReader* manager) {
00275 CollisionSolid::fillin(scan, manager);
00276 _parabola.read_datagram(scan);
00277 _t1 = scan.get_stdfloat();
00278 _t2 = scan.get_stdfloat();
00279 }