00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "collisionVisualizer.h"
00016 #include "collisionEntry.h"
00017 #include "cullTraverser.h"
00018 #include "cullTraverserData.h"
00019 #include "cullableObject.h"
00020 #include "cullHandler.h"
00021 #include "renderState.h"
00022 #include "renderModeAttrib.h"
00023 #include "geomVertexData.h"
00024 #include "geomVertexFormat.h"
00025 #include "geomVertexArrayFormat.h"
00026 #include "geom.h"
00027 #include "geomPoints.h"
00028 #include "geomLines.h"
00029 #include "omniBoundingVolume.h"
00030 #include "depthOffsetAttrib.h"
00031 #include "colorScaleAttrib.h"
00032 #include "transparencyAttrib.h"
00033 #include "clipPlaneAttrib.h"
00034 #include "geomVertexWriter.h"
00035
00036
00037 #ifdef DO_COLLISION_RECORDING
00038
00039 TypeHandle CollisionVisualizer::_type_handle;
00040
00041
00042
00043
00044
00045
00046 CollisionVisualizer::
00047 CollisionVisualizer(const string &name) : PandaNode(name) {
00048 set_cull_callback();
00049
00050
00051
00052 set_internal_bounds(new OmniBoundingVolume());
00053 _point_scale = 1.0f;
00054 _normal_scale = 1.0f;
00055 }
00056
00057
00058
00059
00060
00061
00062 CollisionVisualizer::
00063 ~CollisionVisualizer() {
00064 }
00065
00066
00067
00068
00069
00070
00071
00072 void CollisionVisualizer::
00073 clear() {
00074 _data.clear();
00075 }
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085 PandaNode *CollisionVisualizer::
00086 make_copy() const {
00087 return new CollisionVisualizer(*this);
00088 }
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115 bool CollisionVisualizer::
00116 cull_callback(CullTraverser *trav, CullTraverserData &data) {
00117
00118
00119 Data::const_iterator di;
00120 for (di = _data.begin(); di != _data.end(); ++di) {
00121 const TransformState *net_transform = (*di).first;
00122 const VizInfo &viz_info = (*di).second;
00123
00124 CullTraverserData xform_data(data);
00125
00126
00127
00128
00129
00130 xform_data._net_transform = TransformState::make_identity();
00131 xform_data._view_frustum = trav->get_view_frustum();
00132 xform_data.apply_transform_and_state(trav, net_transform,
00133 RenderState::make_empty(),
00134 RenderEffects::make_empty(),
00135 ClipPlaneAttrib::make());
00136
00137
00138 Solids::const_iterator si;
00139 for (si = viz_info._solids.begin(); si != viz_info._solids.end(); ++si) {
00140
00141
00142
00143
00144
00145 const CollisionSolid *solid = (*si).first;
00146 const SolidInfo &solid_info = (*si).second;
00147 bool was_detected = (solid_info._detected_count > 0);
00148 PT(PandaNode) node = solid->get_viz(trav, xform_data, !was_detected);
00149 if (node != (PandaNode *)NULL) {
00150 CullTraverserData next_data(xform_data, node);
00151
00152
00153
00154 next_data._state = get_viz_state();
00155 trav->traverse(next_data);
00156 }
00157 }
00158
00159
00160 if (!viz_info._points.empty()) {
00161 CPT(RenderState) empty_state = RenderState::make_empty();
00162 CPT(RenderState) point_state = RenderState::make(RenderModeAttrib::make(RenderModeAttrib::M_unchanged, 1.0f, false));
00163
00164 PT(GeomVertexArrayFormat) point_array_format =
00165 new GeomVertexArrayFormat(InternalName::get_vertex(), 3,
00166 Geom::NT_stdfloat, Geom::C_point,
00167 InternalName::get_color(), 1,
00168 Geom::NT_packed_dabc, Geom::C_color,
00169 InternalName::get_size(), 1,
00170 Geom::NT_stdfloat, Geom::C_other);
00171 CPT(GeomVertexFormat) point_format =
00172 GeomVertexFormat::register_format(point_array_format);
00173
00174 Points::const_iterator pi;
00175 for (pi = viz_info._points.begin(); pi != viz_info._points.end(); ++pi) {
00176 const CollisionPoint &point = (*pi);
00177
00178
00179
00180 {
00181 PT(GeomVertexData) point_vdata =
00182 new GeomVertexData("viz", point_format, Geom::UH_stream);
00183
00184 PT(GeomPoints) points = new GeomPoints(Geom::UH_stream);
00185
00186 GeomVertexWriter vertex(point_vdata, InternalName::get_vertex());
00187 GeomVertexWriter color(point_vdata, InternalName::get_color());
00188 GeomVertexWriter size(point_vdata, InternalName::get_size());
00189
00190 vertex.add_data3(point._surface_point);
00191 color.add_data4(1.0f, 0.0f, 0.0f, 1.0f);
00192 size.add_data1f(16.0f * _point_scale);
00193 points->add_next_vertices(1);
00194 points->close_primitive();
00195
00196 if (point._interior_point != point._surface_point) {
00197 vertex.add_data3(point._interior_point);
00198 color.add_data4(1.0f, 1.0f, 1.0f, 1.0f);
00199 size.add_data1f(8.0f * _point_scale);
00200 points->add_next_vertices(1);
00201 points->close_primitive();
00202 }
00203
00204 PT(Geom) geom = new Geom(point_vdata);
00205 geom->add_primitive(points);
00206
00207 CullableObject *object =
00208 new CullableObject(geom, point_state,
00209 xform_data.get_net_transform(trav),
00210 xform_data.get_modelview_transform(trav),
00211 trav->get_gsg());
00212
00213 trav->get_cull_handler()->record_object(object, trav);
00214 }
00215
00216
00217 if (!point._surface_normal.almost_equal(LVector3::zero())) {
00218 PT(GeomVertexData) line_vdata =
00219 new GeomVertexData("viz", GeomVertexFormat::get_v3cp(),
00220 Geom::UH_stream);
00221
00222 PT(GeomLines) lines = new GeomLines(Geom::UH_stream);
00223
00224 GeomVertexWriter vertex(line_vdata, InternalName::get_vertex());
00225 GeomVertexWriter color(line_vdata, InternalName::get_color());
00226
00227 vertex.add_data3(point._surface_point);
00228 vertex.add_data3(point._surface_point +
00229 point._surface_normal * _normal_scale);
00230 color.add_data4(1.0f, 0.0f, 0.0f, 1.0f);
00231 color.add_data4(1.0f, 1.0f, 1.0f, 1.0f);
00232 lines->add_next_vertices(2);
00233 lines->close_primitive();
00234
00235 PT(Geom) geom = new Geom(line_vdata);
00236 geom->add_primitive(lines);
00237
00238 CullableObject *object =
00239 new CullableObject(geom, empty_state,
00240 xform_data.get_net_transform(trav),
00241 xform_data.get_modelview_transform(trav),
00242 trav->get_gsg());
00243
00244 trav->get_cull_handler()->record_object(object, trav);
00245 }
00246 }
00247 }
00248 }
00249
00250
00251 return true;
00252 }
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264 bool CollisionVisualizer::
00265 is_renderable() const {
00266 return true;
00267 }
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278 void CollisionVisualizer::
00279 output(ostream &out) const {
00280 PandaNode::output(out);
00281 out << " ";
00282 CollisionRecorder::output(out);
00283 }
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293 void CollisionVisualizer::
00294 begin_traversal() {
00295 CollisionRecorder::begin_traversal();
00296 _data.clear();
00297 }
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307 void CollisionVisualizer::
00308 collision_tested(const CollisionEntry &entry, bool detected) {
00309 CollisionRecorder::collision_tested(entry, detected);
00310
00311 NodePath node_path = entry.get_into_node_path();
00312 CPT(TransformState) net_transform = node_path.get_net_transform();
00313 const CollisionSolid *solid = entry.get_into();
00314 nassertv(solid != (CollisionSolid *)NULL);
00315
00316 VizInfo &viz_info = _data[net_transform];
00317 if (detected) {
00318 viz_info._solids[solid]._detected_count++;
00319
00320 if (entry.has_surface_point()) {
00321 CollisionPoint p;
00322 entry.get_all(entry.get_into_node_path(),
00323 p._surface_point, p._surface_normal, p._interior_point);
00324 viz_info._points.push_back(p);
00325 }
00326
00327 } else {
00328 viz_info._solids[solid]._missed_count++;
00329 }
00330 }
00331
00332
00333
00334
00335
00336
00337
00338
00339 CPT(RenderState) CollisionVisualizer::
00340 get_viz_state() {
00341
00342
00343 static CPT(RenderState) state = (const RenderState *)NULL;
00344 if (state == (const RenderState *)NULL) {
00345 state = RenderState::make
00346 (DepthOffsetAttrib::make());
00347 }
00348
00349 return state;
00350 }
00351
00352 #endif // DO_COLLISION_RECORDING