Browse Source

add a spindle to the viz

David Rose 19 years ago
parent
commit
02916bf726
3 changed files with 159 additions and 38 deletions
  1. 31 3
      panda/src/pgraph/lodNode.I
  2. 122 35
      panda/src/pgraph/lodNode.cxx
  3. 6 0
      panda/src/pgraph/lodNode.h

+ 31 - 3
panda/src/pgraph/lodNode.I

@@ -316,7 +316,7 @@ INLINE void LODNode::Switch::
 set_range(float in, float out) {
   _in = in;
   _out = out;
-  _ring_viz.clear();
+  clear_ring_viz();
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -352,7 +352,7 @@ INLINE void LODNode::Switch::
 rescale(float factor) {
   _in *= factor;
   _out *= factor;
-  _ring_viz.clear();
+  clear_ring_viz();
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -402,6 +402,21 @@ get_ring_viz() const {
   return _ring_viz;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: LODNode::Switch::get_spindle_viz
+//       Access: Public
+//  Description: Returns a PandaNode suitable for rendering the center
+//               spindle of the LODNode, in the color of this switch.
+////////////////////////////////////////////////////////////////////
+INLINE PandaNode *LODNode::Switch::
+get_spindle_viz() const {
+  if (_spindle_viz.is_null()) {
+    ((Switch *)this)->compute_spindle_viz();
+  }
+
+  return _spindle_viz;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: LODNode::Switch::get_viz_model_state
 //       Access: Public
@@ -412,7 +427,7 @@ get_ring_viz() const {
 INLINE const RenderState *LODNode::Switch::
 get_viz_model_state() const {
   if (_viz_model_state.is_null()) {
-    ((Switch *)this)->compute_ring_viz();
+    ((Switch *)this)->compute_viz_model_state();
   }
 
   return _viz_model_state;
@@ -443,3 +458,16 @@ read_datagram(DatagramIterator &source) {
   _out = source.get_float32();
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: LODNode::Switch::clear_ring_viz
+//       Access: Private
+//  Description: Resets the internal cache values for the ring and
+//               spindle viz, and related pointers, for the
+//               set_switch() debugging mode.
+////////////////////////////////////////////////////////////////////
+INLINE void LODNode::Switch::
+clear_ring_viz() {
+  _ring_viz.clear();
+  _spindle_viz.clear();
+  _viz_model_state.clear();
+}

+ 122 - 35
panda/src/pgraph/lodNode.cxx

@@ -393,33 +393,28 @@ show_switches_cull_callback(CullTraverser *trav, CullTraverserData &data) {
        ++si) {
     const Switch &sw = (*si);
     if (sw.is_shown()) {
-      PT(PandaNode) ring_viz = sw.get_ring_viz();
-      CullTraverserData next_data(data, ring_viz);
+      CullTraverserData next_data(data, sw.get_ring_viz());
       next_data._net_transform = viz_transform;
-      
       trav->traverse(next_data);
 
       if (sw.in_range_2(dist2)) {
-        // This switch level is in range.  Draw its children in the
-        // funny wireframe mode.
+        // This switch level is in range.  Draw the spindle in this
+        // color.
+        CullTraverserData next_data2(data, sw.get_spindle_viz());
+        next_data2._net_transform = viz_transform;
+        trav->traverse(next_data2);
+
+        // And draw its children in the funny wireframe mode.
         int index = (si - cdata->_switch_vector.begin());
         if (index < get_num_children()) {
-          CullTraverserData next_data(data, get_child(index));
-          next_data._state = next_data._state->compose(sw.get_viz_model_state());
-          trav->traverse(next_data);
+          CullTraverserData next_data3(data, get_child(index));
+          next_data3._state = next_data3._state->compose(sw.get_viz_model_state());
+          trav->traverse(next_data3);
         }
       }
     }
   }
 
-  // Finally, draw the visible child(ren) in the appropriate state as
-  // well.
-
-  for (int index = 0; index < (int)cdata->_switch_vector.size(); index++) {
-    if (cdata->_switch_vector[index].in_range_2(dist2)) { 
-    }
-  }
-
   // Now return false indicating that we have already taken care of
   // the traversal from here.
   return false;
@@ -658,12 +653,17 @@ fillin(DatagramIterator &scan, BamReader *manager) {
 ////////////////////////////////////////////////////////////////////
 void LODNode::Switch::
 compute_ring_viz() {
+  // We render the ring as a series of concentric ring-shaped triangle
+  // strips, each of which has num_slices quads.
   static const int num_slices = 50;
   static const int num_rings = 1;
+
+  // There are also two more triangle strips, one for the outer edge,
+  // and one for the inner edge.
   static const float edge_ratio = 0.1;  // ratio of edge height to diameter.
 
   const GeomVertexFormat *format = GeomVertexFormat::get_v3n3cp();
-  PT(GeomVertexData) vdata = new GeomVertexData("LOD", format, Geom::UH_static);
+  PT(GeomVertexData) vdata = new GeomVertexData("LOD_ring", format, Geom::UH_static);
 
   // Fill up the vertex table with all of the vertices.
   GeomVertexWriter vertex(vdata, InternalName::get_vertex());
@@ -699,12 +699,6 @@ compute_ring_viz() {
     float r = (float)ri;
     float d = r * (_in - _out) + _out;
 
-    // Invert the direction of Z on the outer ring, to invert the
-    // vertex winding order (and thereby invert the facing of the
-    // polygons).  We want the outer ring to face inward, and the
-    // inner ring to face outward.
-    float sign = 1.0f - (ri * 2);
-
     for (si = 0; si < num_slices; ++si) {
       float s = (float)si / (float)num_slices;
       float t = MathNumbers::pi_f * 2.0f * s;
@@ -712,8 +706,8 @@ compute_ring_viz() {
       float x = cosf(t);
       float y = sinf(t);
 
-      vertex.add_data3f(x * d, y * d, 0.5f * edge_ratio * d * sign);
-      normal.add_data3f(x * sign, y * sign, 0.0f);
+      vertex.add_data3f(x * d, y * d, 0.5f * edge_ratio * d);
+      normal.add_data3f(x, y, 0.0f);
       color.add_data4f(_show_color);
     }
 
@@ -724,8 +718,8 @@ compute_ring_viz() {
       float x = cosf(t);
       float y = sinf(t);
 
-      vertex.add_data3f(x * d, y * d, -0.5f * edge_ratio * d * sign);
-      normal.add_data3f(x * sign, y * sign, 0.0f);
+      vertex.add_data3f(x * d, y * d, -0.5f * edge_ratio * d);
+      normal.add_data3f(x, y, 0.0f);
       color.add_data4f(_show_color);
     }
   }
@@ -765,25 +759,118 @@ compute_ring_viz() {
   material->set_twoside(true);
   material = MaterialPool::get_material(material);
 
-  CPT(RenderState) viz_state = RenderState::make(CullFaceAttrib::make(CullFaceAttrib::M_cull_none),
-                                                 TextureAttrib::make_off(),
-                                                 MaterialAttrib::make(material),
-                                                 RenderState::get_max_priority());
+  CPT(RenderState) viz_state = 
+    RenderState::make(CullFaceAttrib::make(CullFaceAttrib::M_cull_none),
+                      TextureAttrib::make_off(),
+                      ShaderAttrib::make_off(),
+                      MaterialAttrib::make(material),
+                      RenderState::get_max_priority());
   if (_show_color[3] != 1.0f) {
     viz_state = viz_state->add_attrib(TransparencyAttrib::make(TransparencyAttrib::M_alpha),
-                                      RenderState::get_max_priority());
+                                        RenderState::get_max_priority());
   }
 
   geom_node->set_state(viz_state);
 
   _ring_viz = geom_node.p();
+}
 
-  // Also compute a RenderState for rendering the children in
-  // wireframe mode.
+////////////////////////////////////////////////////////////////////
+//     Function: LODNode::Switch::compute_spindle_viz
+//       Access: Private
+//  Description: Computes a Geom suitable for rendering the LODNode
+//               spindle in the color of this switch.
+////////////////////////////////////////////////////////////////////
+void LODNode::Switch::
+compute_spindle_viz() {
+  // We render the spindle as a cylinder, which consists of num_rings
+  // rings stacked vertically, each of which is a triangle strip of
+  // num_slices quads.  The scale is -10 .. 10 vertically, with a radius
+  // of 1.0.
+  static const int num_slices = 10;
+  static const int num_rings = 10;
+
+  const GeomVertexFormat *format = GeomVertexFormat::get_v3n3cp();
+  PT(GeomVertexData) vdata = new GeomVertexData("LOD_spindle", format, Geom::UH_static);
 
+  // Fill up the vertex table with all of the vertices.
+  GeomVertexWriter vertex(vdata, InternalName::get_vertex());
+  GeomVertexWriter normal(vdata, InternalName::get_normal());
+  GeomVertexWriter color(vdata, InternalName::get_color());
+
+  int ri, si;
+  for (ri = 0; ri <= num_rings; ++ri) {
+    // r is in the range [0.0, 1.0].
+    float r = (float)ri / (float)num_rings;
+
+    // z is in the range [100.0, -100.0]
+    float z = 100.0f - r * 200.0f;
+
+    for (si = 0; si < num_slices; ++si) {
+      // s is in the range [0.0, 1.0).
+      float s = (float)si / (float)num_slices;
+
+      // t is in the range [0.0, 2pi).
+      float t = MathNumbers::pi_f * 2.0f * s;
+
+      float x = cosf(t);
+      float y = sinf(t);
+      vertex.add_data3f(x, y, z);
+      normal.add_data3f(x, y, 0.0f);
+      color.add_data4f(_show_color);
+    }
+  }
+
+  // Now create the triangle strips.  One tristrip for each ring.
+  PT(GeomTristrips) strips = new GeomTristrips(Geom::UH_static);
+  for (ri = 0; ri < num_rings; ++ri) {
+    for (si = 0; si < num_slices; ++si) {
+      strips->add_vertex(ri * num_slices + si);
+      strips->add_vertex((ri + 1) * num_slices + si);
+    }
+    strips->add_vertex(ri * num_slices);
+    strips->add_vertex((ri + 1) * num_slices);
+    strips->close_primitive();
+  }
+
+  PT(Geom) spindle_geom = new Geom(vdata);
+  spindle_geom->add_primitive(strips);
+
+  PT(GeomNode) geom_node = new GeomNode("spindle");
+  geom_node->add_geom(spindle_geom);
+
+  CPT(RenderState) viz_state = 
+    RenderState::make(CullFaceAttrib::make(CullFaceAttrib::M_cull_clockwise),
+                      TextureAttrib::make_off(),
+                      ShaderAttrib::make_off(),
+                      RenderState::get_max_priority());
+  if (_show_color[3] != 1.0f) {
+    viz_state = viz_state->add_attrib(TransparencyAttrib::make(TransparencyAttrib::M_alpha),
+                                      RenderState::get_max_priority());
+  }
+
+  geom_node->set_state(viz_state);
+
+  _spindle_viz = geom_node.p();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: LODNode::Switch::compute_viz_model_state
+//       Access: Private
+//  Description: Computes a RenderState for rendering the children of
+//               this switch in colored wireframe mode.
+////////////////////////////////////////////////////////////////////
+void LODNode::Switch::
+compute_viz_model_state() {
+  // The RenderState::make() function only takes up to four attribs at
+  // once.  Since we need more attribs than that, we have to make up
+  // our state in two steps.
   _viz_model_state = RenderState::make(RenderModeAttrib::make(RenderModeAttrib::M_wireframe),
                                        TextureAttrib::make_off(),
+                                       ShaderAttrib::make_off(),
                                        ColorAttrib::make_flat(_show_color),
-                                       TransparencyAttrib::make(TransparencyAttrib::M_none),
                                        RenderState::get_max_priority());
+  CPT(RenderState) st2 = RenderState::make(TransparencyAttrib::make(TransparencyAttrib::M_none),
+                                           RenderState::get_max_priority());
+  _viz_model_state = _viz_model_state->compose(st2);
 }

+ 6 - 0
panda/src/pgraph/lodNode.h

@@ -110,13 +110,18 @@ protected:
     INLINE void hide();
 
     INLINE PandaNode *get_ring_viz() const;
+    INLINE PandaNode *get_spindle_viz() const;
     INLINE const RenderState *get_viz_model_state() const;
 
     INLINE void write_datagram(Datagram &destination) const;
     INLINE void read_datagram(DatagramIterator &source);
 
   private:
+    INLINE void clear_ring_viz();
+
     void compute_ring_viz();
+    void compute_spindle_viz();
+    void compute_viz_model_state();
 
   private:
     float _in;
@@ -124,6 +129,7 @@ protected:
     bool _shown;
     Colorf _show_color;
     PT(PandaNode) _ring_viz;
+    PT(PandaNode) _spindle_viz;
     CPT(RenderState) _viz_model_state;
   };
   typedef pvector<Switch> SwitchVector;