Browse Source

pre-compute GSG::_internal_transform

David Rose 19 years ago
parent
commit
18de188129

+ 4 - 2
panda/src/collide/collisionVisualizer.cxx

@@ -215,7 +215,8 @@ cull_callback(CullTraverser *trav, CullTraverserData &data) {
           CullableObject *object = 
           CullableObject *object = 
             new CullableObject(geom, point_state, 
             new CullableObject(geom, point_state, 
                                xform_data.get_net_transform(trav),
                                xform_data.get_net_transform(trav),
-                               xform_data.get_modelview_transform(trav));
+                               xform_data.get_modelview_transform(trav),
+                               trav->get_gsg());
           
           
           trav->get_cull_handler()->record_object(object, trav);
           trav->get_cull_handler()->record_object(object, trav);
         }
         }
@@ -245,7 +246,8 @@ cull_callback(CullTraverser *trav, CullTraverserData &data) {
           CullableObject *object = 
           CullableObject *object = 
             new CullableObject(geom, empty_state, 
             new CullableObject(geom, empty_state, 
                                xform_data.get_net_transform(trav),
                                xform_data.get_net_transform(trav),
-                               xform_data.get_modelview_transform(trav));
+                               xform_data.get_modelview_transform(trav),
+                               trav->get_gsg());
           
           
           trav->get_cull_handler()->record_object(object, trav);
           trav->get_cull_handler()->record_object(object, trav);
         }
         }

+ 4 - 2
panda/src/cull/cullBinOcclusionTest.cxx

@@ -487,6 +487,7 @@ occlusion_test(CullBinOcclusionTest &bin) {
      LVecBase3f(_half_side, _half_side, _half_side));
      LVecBase3f(_half_side, _half_side, _half_side));
   CPT(TransformState) world_transform = bin._gsg->get_scene()->get_world_transform();
   CPT(TransformState) world_transform = bin._gsg->get_scene()->get_world_transform();
   CPT(TransformState) modelview_transform = world_transform->compose(net_transform);
   CPT(TransformState) modelview_transform = world_transform->compose(net_transform);
+  CPT(TransformState) internal_transform = bin._gsg->get_cs_transform()->compose(modelview_transform);
   
   
   CPT(RenderState) state = get_octree_solid_test_state();
   CPT(RenderState) state = get_octree_solid_test_state();
   PT(GeomMunger) munger = bin._gsg->get_geom_munger(state);
   PT(GeomMunger) munger = bin._gsg->get_geom_munger(state);
@@ -495,7 +496,7 @@ occlusion_test(CullBinOcclusionTest &bin) {
   CPT(GeomVertexData) munged_data = viz->get_vertex_data();
   CPT(GeomVertexData) munged_data = viz->get_vertex_data();
   munger->munge_geom(viz, munged_data);
   munger->munge_geom(viz, munged_data);
   
   
-  bin._gsg->set_state_and_transform(state, modelview_transform);
+  bin._gsg->set_state_and_transform(state, internal_transform);
 
 
   PStatTimer timer(bin._draw_occlusion_pcollector);
   PStatTimer timer(bin._draw_occlusion_pcollector);
   bin._gsg->begin_occlusion_query();
   bin._gsg->begin_occlusion_query();
@@ -624,6 +625,7 @@ draw_wireframe(CullBinOcclusionTest &bin) {
      LVecBase3f(_half_side, _half_side, _half_side));
      LVecBase3f(_half_side, _half_side, _half_side));
   CPT(TransformState) world_transform = bin._gsg->get_scene()->get_world_transform();
   CPT(TransformState) world_transform = bin._gsg->get_scene()->get_world_transform();
   CPT(TransformState) modelview_transform = world_transform->compose(net_transform);
   CPT(TransformState) modelview_transform = world_transform->compose(net_transform);
+  CPT(TransformState) internal_transform = bin._gsg->get_cs_transform()->compose(modelview_transform);
   
   
   CPT(RenderState) state = RenderState::make_empty();
   CPT(RenderState) state = RenderState::make_empty();
   PT(GeomMunger) munger = bin._gsg->get_geom_munger(state);
   PT(GeomMunger) munger = bin._gsg->get_geom_munger(state);
@@ -632,7 +634,7 @@ draw_wireframe(CullBinOcclusionTest &bin) {
   CPT(GeomVertexData) munged_data = viz->get_vertex_data();
   CPT(GeomVertexData) munged_data = viz->get_vertex_data();
   munger->munge_geom(viz, munged_data);
   munger->munge_geom(viz, munged_data);
   
   
-  bin._gsg->set_state_and_transform(state, modelview_transform);
+  bin._gsg->set_state_and_transform(state, internal_transform);
   viz->draw(bin._gsg, munger, munged_data);
   viz->draw(bin._gsg, munger, munged_data);
 }
 }
 
 

+ 17 - 18
panda/src/display/graphicsStateGuardian.I

@@ -632,7 +632,7 @@ needs_reset() const {
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-//     Function: GraphicsStateGuardian::get_transform
+//     Function: GraphicsStateGuardian::get_external_transform
 //       Access: Public
 //       Access: Public
 //  Description: Fetches the external net transform.  This
 //  Description: Fetches the external net transform.  This
 //               transform is generally only set when geometry is
 //               transform is generally only set when geometry is
@@ -641,8 +641,22 @@ needs_reset() const {
 //               rendering process.
 //               rendering process.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE CPT(TransformState) GraphicsStateGuardian::
 INLINE CPT(TransformState) GraphicsStateGuardian::
-get_transform() {
-  return _external_transform;
+get_external_transform() const {
+  return _inv_cs_transform->compose(_internal_transform);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: GraphicsStateGuardian::get_internal_transform
+//       Access: Public
+//  Description: Fetches the external net transform.  This
+//               transform is generally only set when geometry is
+//               about to be rendered.  Therefore, this "get" function
+//               is typically only meaningful during the geometry
+//               rendering process.
+////////////////////////////////////////////////////////////////////
+INLINE CPT(TransformState) GraphicsStateGuardian::
+get_internal_transform() const {
+  return _internal_transform;
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -679,21 +693,6 @@ get_current_lens() const {
   return _current_lens;
   return _current_lens;
 }
 }
 
 
-////////////////////////////////////////////////////////////////////
-//     Function: GraphicsStateGuardian::get_cs_transform
-//       Access: Public
-//  Description: Returns a transform that converts from the GSG's
-//               external coordinate system (as returned by
-//               get_coordinate_system()) to its internal coordinate
-//               system (as returned by
-//               get_internal_coordinate_system()).  This is used for
-//               rendering.
-////////////////////////////////////////////////////////////////////
-INLINE const TransformState *GraphicsStateGuardian::
-get_cs_transform() const {
-  return _cs_transform;
-}
-
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: GraphicsStateGuardian::get_inv_cs_transform
 //     Function: GraphicsStateGuardian::get_inv_cs_transform
 //       Access: Public
 //       Access: Public

+ 120 - 107
panda/src/display/graphicsStateGuardian.cxx

@@ -84,7 +84,6 @@ GraphicsStateGuardian(const FrameBufferProperties &properties,
   _default_properties(properties)
   _default_properties(properties)
 {
 {
   _coordinate_system = CS_invalid;
   _coordinate_system = CS_invalid;
-  _external_transform = TransformState::make_identity();
   _internal_transform = TransformState::make_identity();
   _internal_transform = TransformState::make_identity();
   
   
   set_coordinate_system(get_default_coordinate_system());
   set_coordinate_system(get_default_coordinate_system());
@@ -238,8 +237,6 @@ set_coordinate_system(CoordinateSystem cs) {
       (LMatrix4f::convert_mat(_internal_coordinate_system,
       (LMatrix4f::convert_mat(_internal_coordinate_system,
                               _coordinate_system));
                               _coordinate_system));
   }
   }
-  _internal_transform = _cs_transform->compose(_external_transform);
-  _transform_stale = true;
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -275,7 +272,6 @@ reset() {
   _target_rs = NULL;
   _target_rs = NULL;
   _state.clear_to_zero();
   _state.clear_to_zero();
   _target.clear_to_defaults();
   _target.clear_to_defaults();
-  _external_transform = TransformState::make_identity();
   _internal_transform = _cs_transform;
   _internal_transform = _cs_transform;
   _scene_null = new SceneSetup;
   _scene_null = new SceneSetup;
   _scene_setup = _scene_null;
   _scene_setup = _scene_null;
@@ -316,11 +312,13 @@ reset() {
 //  Description: Simultaneously resets the render state and the
 //  Description: Simultaneously resets the render state and the
 //               transform state.
 //               transform state.
 //
 //
-//               This transform specified is the "external" net
-//               transform, expressed in the external coordinate
-//               space; internally, it will be pretransformed by
-//               get_cs_transform() to express it in the GSG's
-//               internal coordinate space.
+//               This transform specified is the "internal" net
+//               transform, already converted into the GSG's internal
+//               coordinate space by composing it to
+//               get_cs_transform().  (Previously, this used to be the
+//               "external" net transform, with the assumption that
+//               that GSG would convert it internally, but that is no
+//               longer the case.)
 //
 //
 //               Special case: if (state==NULL), then the target
 //               Special case: if (state==NULL), then the target
 //               state is already stored in _target.
 //               state is already stored in _target.
@@ -841,11 +839,11 @@ fetch_specified_part(ShaderContext::ShaderMatInput part, InternalName *name, LMa
     return &(get_scene()->get_camera_transform()->get_mat());
     return &(get_scene()->get_camera_transform()->get_mat());
   }
   }
   case ShaderContext::SMO_model_to_view: {
   case ShaderContext::SMO_model_to_view: {
-    return &(_external_transform->get_mat());
+    return &(get_external_transform()->get_mat());
   }
   }
   case ShaderContext::SMO_view_to_model: {
   case ShaderContext::SMO_view_to_model: {
     // DANGER: SLOW AND NOT CACHEABLE!
     // DANGER: SLOW AND NOT CACHEABLE!
-    t.invert_from(_external_transform->get_mat());
+    t.invert_from(get_external_transform()->get_mat());
     return &t;
     return &t;
   }
   }
   case ShaderContext::SMO_apiview_to_view: {
   case ShaderContext::SMO_apiview_to_view: {
@@ -1331,80 +1329,18 @@ end_draw_primitives() {
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-//     Function: GraphicsStateGuardian::do_issue_color_scale
+//     Function: GraphicsStateGuardian::get_cs_transform
 //       Access: Public, Virtual
 //       Access: Public, Virtual
-//  Description:
-////////////////////////////////////////////////////////////////////
-void GraphicsStateGuardian::
-do_issue_color_scale() {
-  const ColorScaleAttrib *attrib = _target._color_scale;
-  _color_scale_enabled = attrib->has_scale();
-  _current_color_scale = attrib->get_scale();
-  
-  if (_color_blend_involves_color_scale) {
-    _state_rs = 0;
-    _state._transparency = 0;
-  }
-  if (_texture_involves_color_scale) {
-    _state_rs = 0;
-    _state._texture = 0;
-  }
-  if (_color_scale_via_lighting) {
-    _state_rs = 0;
-    _state._light = 0;
-    _state._material = 0;
-
-    determine_light_color_scale();
-  }
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: GraphicsStateGuardian::do_issue_color
-//       Access: Public
-//  Description: This method is defined in the base class because it
-//               is likely that this functionality will be used for
-//               all (or at least most) kinds of
-//               GraphicsStateGuardians--it's not specific to any one
-//               rendering backend.
-//
-//               The ColorAttribute just changes the interpretation of
-//               the color on the vertices, and fiddles with
-//               _vertex_colors_enabled, etc.
+//  Description: Returns a transform that converts from the GSG's
+//               external coordinate system (as returned by
+//               get_coordinate_system()) to its internal coordinate
+//               system (as returned by
+//               get_internal_coordinate_system()).  This is used for
+//               rendering.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-void GraphicsStateGuardian::
-do_issue_color() {
-  const ColorAttrib *attrib = _target._color;
-  switch (attrib->get_color_type()) {
-  case ColorAttrib::T_flat:
-    // Color attribute flat: it specifies a scene graph color that
-    // overrides the vertex color.
-    _scene_graph_color = attrib->get_color();
-    _has_scene_graph_color = true;
-    _vertex_colors_enabled = false;
-    break;
-
-  case ColorAttrib::T_off:
-    // Color attribute off: it specifies that no scene graph color is
-    // in effect, and vertex color is not important either.
-    _has_scene_graph_color = false;
-    _vertex_colors_enabled = false;
-    break;
-
-  case ColorAttrib::T_vertex:
-    // Color attribute vertex: it specifies that vertex color should
-    // be revealed.
-    _has_scene_graph_color = false;
-    _vertex_colors_enabled = true;
-    break;
-  }
-
-  if (_color_scale_via_lighting) {
-    _state_rs = 0;
-    _state._light = 0;
-    _state._material = 0;
-
-    determine_light_color_scale();
-  }
+const TransformState *GraphicsStateGuardian::
+get_cs_transform() const {
+  return _cs_transform;
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -1527,39 +1463,80 @@ do_issue_clip_plane() {
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-//     Function: GraphicsStateGuardian::bind_light
-//       Access: Public, Virtual
-//  Description: Called the first time a particular light has been
-//               bound to a given id within a frame, this should set
-//               up the associated hardware light with the light's
-//               properties.
+//     Function: GraphicsStateGuardian::do_issue_color
+//       Access: Public
+//  Description: This method is defined in the base class because it
+//               is likely that this functionality will be used for
+//               all (or at least most) kinds of
+//               GraphicsStateGuardians--it's not specific to any one
+//               rendering backend.
+//
+//               The ColorAttribute just changes the interpretation of
+//               the color on the vertices, and fiddles with
+//               _vertex_colors_enabled, etc.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void GraphicsStateGuardian::
 void GraphicsStateGuardian::
-bind_light(PointLight *light_obj, const NodePath &light, int light_id) {
-}
+do_issue_color() {
+  const ColorAttrib *attrib = _target._color;
+  switch (attrib->get_color_type()) {
+  case ColorAttrib::T_flat:
+    // Color attribute flat: it specifies a scene graph color that
+    // overrides the vertex color.
+    _scene_graph_color = attrib->get_color();
+    _has_scene_graph_color = true;
+    _vertex_colors_enabled = false;
+    break;
 
 
-////////////////////////////////////////////////////////////////////
-//     Function: GraphicsStateGuardian::bind_light
-//       Access: Public, Virtual
-//  Description: Called the first time a particular light has been
-//               bound to a given id within a frame, this should set
-//               up the associated hardware light with the light's
-//               properties.
-////////////////////////////////////////////////////////////////////
-void GraphicsStateGuardian::
-bind_light(DirectionalLight *light_obj, const NodePath &light, int light_id) {
+  case ColorAttrib::T_off:
+    // Color attribute off: it specifies that no scene graph color is
+    // in effect, and vertex color is not important either.
+    _has_scene_graph_color = false;
+    _vertex_colors_enabled = false;
+    break;
+
+  case ColorAttrib::T_vertex:
+    // Color attribute vertex: it specifies that vertex color should
+    // be revealed.
+    _has_scene_graph_color = false;
+    _vertex_colors_enabled = true;
+    break;
+  }
+
+  if (_color_scale_via_lighting) {
+    _state_rs = 0;
+    _state._light = 0;
+    _state._material = 0;
+
+    determine_light_color_scale();
+  }
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-//     Function: GraphicsStateGuardian::bind_light
+//     Function: GraphicsStateGuardian::do_issue_color_scale
 //       Access: Public, Virtual
 //       Access: Public, Virtual
-//  Description: Called the first time a particular light has been
-//               bound to a given id within a frame, this should set
-//               up the associated hardware light with the light's
-//               properties.
+//  Description:
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void GraphicsStateGuardian::
 void GraphicsStateGuardian::
-bind_light(Spotlight *light_obj, const NodePath &light, int light_id) {
+do_issue_color_scale() {
+  const ColorScaleAttrib *attrib = _target._color_scale;
+  _color_scale_enabled = attrib->has_scale();
+  _current_color_scale = attrib->get_scale();
+  
+  if (_color_blend_involves_color_scale) {
+    _state_rs = 0;
+    _state._transparency = 0;
+  }
+  if (_texture_involves_color_scale) {
+    _state_rs = 0;
+    _state._texture = 0;
+  }
+  if (_color_scale_via_lighting) {
+    _state_rs = 0;
+    _state._light = 0;
+    _state._material = 0;
+
+    determine_light_color_scale();
+  }
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -1724,6 +1701,42 @@ do_issue_light() {
   }
   }
 }
 }
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: GraphicsStateGuardian::bind_light
+//       Access: Public, Virtual
+//  Description: Called the first time a particular light has been
+//               bound to a given id within a frame, this should set
+//               up the associated hardware light with the light's
+//               properties.
+////////////////////////////////////////////////////////////////////
+void GraphicsStateGuardian::
+bind_light(PointLight *light_obj, const NodePath &light, int light_id) {
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: GraphicsStateGuardian::bind_light
+//       Access: Public, Virtual
+//  Description: Called the first time a particular light has been
+//               bound to a given id within a frame, this should set
+//               up the associated hardware light with the light's
+//               properties.
+////////////////////////////////////////////////////////////////////
+void GraphicsStateGuardian::
+bind_light(DirectionalLight *light_obj, const NodePath &light, int light_id) {
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: GraphicsStateGuardian::bind_light
+//       Access: Public, Virtual
+//  Description: Called the first time a particular light has been
+//               bound to a given id within a frame, this should set
+//               up the associated hardware light with the light's
+//               properties.
+////////////////////////////////////////////////////////////////////
+void GraphicsStateGuardian::
+bind_light(Spotlight *light_obj, const NodePath &light, int light_id) {
+}
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: GraphicsStateGuardian::enable_lighting
 //     Function: GraphicsStateGuardian::enable_lighting
 //       Access: Protected, Virtual
 //       Access: Protected, Virtual

+ 3 - 3
panda/src/display/graphicsStateGuardian.h

@@ -208,7 +208,8 @@ public:
   INLINE void mark_new();
   INLINE void mark_new();
   virtual void reset();
   virtual void reset();
 
 
-  INLINE CPT(TransformState) get_transform();
+  INLINE CPT(TransformState) get_external_transform() const;
+  INLINE CPT(TransformState) get_internal_transform() const;
   
   
   RenderBuffer get_render_buffer(int buffer_type, const FrameBufferProperties &prop);
   RenderBuffer get_render_buffer(int buffer_type, const FrameBufferProperties &prop);
   
   
@@ -216,7 +217,7 @@ public:
   INLINE Lens::StereoChannel get_current_stereo_channel() const;
   INLINE Lens::StereoChannel get_current_stereo_channel() const;
   INLINE const Lens *get_current_lens() const;
   INLINE const Lens *get_current_lens() const;
 
 
-  INLINE const TransformState *get_cs_transform() const;
+  virtual const TransformState *get_cs_transform() const;
   INLINE const TransformState *get_inv_cs_transform() const;
   INLINE const TransformState *get_inv_cs_transform() const;
   
   
   void do_issue_clip_plane();
   void do_issue_clip_plane();
@@ -268,7 +269,6 @@ protected:
   AttribSlots _target;
   AttribSlots _target;
   CPT(RenderState) _state_rs;
   CPT(RenderState) _state_rs;
   CPT(RenderState) _target_rs;
   CPT(RenderState) _target_rs;
-  CPT(TransformState) _external_transform;
   CPT(TransformState) _internal_transform;
   CPT(TransformState) _internal_transform;
   CPT(GeomMunger) _munger;
   CPT(GeomMunger) _munger;
   CPT(GeomVertexData) _vertex_data;
   CPT(GeomVertexData) _vertex_data;

+ 10 - 9
panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx

@@ -2112,11 +2112,13 @@ do_issue_shade_model() {
 //  Description: Simultaneously resets the render state and the
 //  Description: Simultaneously resets the render state and the
 //               transform state.
 //               transform state.
 //
 //
-//               This transform specified is the "external" net
-//               transform, expressed in the external coordinate
-//               space; internally, it will be pretransformed by
-//               get_cs_transform() to express it in the GSG's
-//               internal coordinate space.
+//               This transform specified is the "internal" net
+//               transform, already converted into the GSG's internal
+//               coordinate space by composing it to
+//               get_cs_transform().  (Previously, this used to be the
+//               "external" net transform, with the assumption that
+//               that GSG would convert it internally, but that is no
+//               longer the case.)
 //
 //
 //               Special case: if (state==NULL), then the target
 //               Special case: if (state==NULL), then the target
 //               state is already stored in _target.
 //               state is already stored in _target.
@@ -2132,10 +2134,9 @@ set_state_and_transform(const RenderState *target,
 #endif
 #endif
   _state_pcollector.add_level(1);
   _state_pcollector.add_level(1);
 
 
-  if (transform != _external_transform) {
+  if (transform != _internal_transform) {
     _state_pcollector.add_level(1);
     _state_pcollector.add_level(1);
-    _external_transform = transform;
-    _internal_transform = _cs_transform->compose(transform);
+    _internal_transform = transform;
     do_issue_transform();
     do_issue_transform();
   }
   }
 
 
@@ -2957,7 +2958,7 @@ set_read_buffer(const RenderBuffer &rb) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian8::
 void DXGraphicsStateGuardian8::
 do_auto_rescale_normal() {
 do_auto_rescale_normal() {
-  if (_external_transform->has_identity_scale()) {
+  if (_internal_transform->has_identity_scale()) {
     // If there's no scale, don't normalize anything.
     // If there's no scale, don't normalize anything.
     _d3d_device->SetRenderState(D3DRS_NORMALIZENORMALS, false);
     _d3d_device->SetRenderState(D3DRS_NORMALIZENORMALS, false);
 
 

+ 10 - 9
panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx

@@ -3093,11 +3093,13 @@ do_issue_shade_model() {
 //  Description: Simultaneously resets the render state and the
 //  Description: Simultaneously resets the render state and the
 //               transform state.
 //               transform state.
 //
 //
-//               This transform specified is the "external" net
-//               transform, expressed in the external coordinate
-//               space; internally, it will be pretransformed by
-//               get_cs_transform() to express it in the GSG's
-//               internal coordinate space.
+//               This transform specified is the "internal" net
+//               transform, already converted into the GSG's internal
+//               coordinate space by composing it to
+//               get_cs_transform().  (Previously, this used to be the
+//               "external" net transform, with the assumption that
+//               that GSG would convert it internally, but that is no
+//               longer the case.)
 //
 //
 //               Special case: if (state==NULL), then the target
 //               Special case: if (state==NULL), then the target
 //               state is already stored in _target.
 //               state is already stored in _target.
@@ -3113,10 +3115,9 @@ set_state_and_transform(const RenderState *target,
 #endif
 #endif
   _state_pcollector.add_level(1);
   _state_pcollector.add_level(1);
 
 
-  if (transform != _external_transform) {
+  if (transform != _internal_transform) {
     _state_pcollector.add_level(1);
     _state_pcollector.add_level(1);
-    _external_transform = transform;
-    _internal_transform = _cs_transform->compose(transform);
+    _internal_transform = transform;
     do_issue_transform();
     do_issue_transform();
   }
   }
 
 
@@ -4010,7 +4011,7 @@ set_read_buffer(const RenderBuffer &rb) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian9::
 void DXGraphicsStateGuardian9::
 do_auto_rescale_normal() {
 do_auto_rescale_normal() {
-  if (_external_transform->has_identity_scale()) {
+  if (_internal_transform->has_identity_scale()) {
     // If there's no scale, don't normalize anything.
     // If there's no scale, don't normalize anything.
     set_render_state(D3DRS_NORMALIZENORMALS, false);
     set_render_state(D3DRS_NORMALIZENORMALS, false);
   } else {
   } else {

+ 16 - 12
panda/src/glstuff/glGraphicsStateGuardian_src.cxx

@@ -1089,7 +1089,7 @@ do_clear(const RenderBuffer &buffer) {
   int buffer_type = buffer._buffer_type;
   int buffer_type = buffer._buffer_type;
   GLbitfield mask = 0;
   GLbitfield mask = 0;
 
 
-  set_state_and_transform(RenderState::make_empty(), _external_transform);
+  set_state_and_transform(RenderState::make_empty(), _internal_transform);
 
 
   if (buffer_type & RenderBuffer::T_color) {
   if (buffer_type & RenderBuffer::T_color) {
     GLP(ClearColor)(_color_clear_value[0],
     GLP(ClearColor)(_color_clear_value[0],
@@ -3070,7 +3070,7 @@ framebuffer_copy_to_ram(Texture *tex, int z, const DisplayRegion *dr,
   // for GLP(ReadPixels)() to work
   // for GLP(ReadPixels)() to work
   // NOTE: reading the depth buffer is *much* slower than reading the
   // NOTE: reading the depth buffer is *much* slower than reading the
   // color buffer
   // color buffer
-  set_state_and_transform(RenderState::make_empty(), _external_transform);
+  set_state_and_transform(RenderState::make_empty(), _internal_transform);
 
 
   int xo, yo, w, h;
   int xo, yo, w, h;
   dr->get_region_pixels(xo, yo, w, h);
   dr->get_region_pixels(xo, yo, w, h);
@@ -5457,11 +5457,16 @@ end_bind_clip_planes() {
 //  Description: Simultaneously resets the render state and the
 //  Description: Simultaneously resets the render state and the
 //               transform state.
 //               transform state.
 //
 //
-//               This transform specified is the "external" net
-//               transform, expressed in the external coordinate
-//               space; internally, it will be pretransformed by
-//               get_cs_transform() to express it in the GSG's
-//               internal coordinate space.
+//               This transform specified is the "internal" net
+//               transform, already converted into the GSG's internal
+//               coordinate space by composing it to
+//               get_cs_transform().  (Previously, this used to be the
+//               "external" net transform, with the assumption that
+//               that GSG would convert it internally, but that is no
+//               longer the case.)
+//
+//               Special case: if (state==NULL), then the target
+//               state is already stored in _target.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void CLP(GraphicsStateGuardian)::
 void CLP(GraphicsStateGuardian)::
 set_state_and_transform(const RenderState *target,
 set_state_and_transform(const RenderState *target,
@@ -5474,10 +5479,9 @@ set_state_and_transform(const RenderState *target,
 #endif
 #endif
   _state_pcollector.add_level(1);
   _state_pcollector.add_level(1);
 
 
-  if (transform != _external_transform) {
+  if (transform != _internal_transform) {
     _state_pcollector.add_level(1);
     _state_pcollector.add_level(1);
-    _external_transform = transform;
-    _internal_transform = _cs_transform->compose(transform);
+    _internal_transform = transform;
     do_issue_transform();
     do_issue_transform();
   }
   }
 
 
@@ -5633,7 +5637,7 @@ free_pointers() {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void CLP(GraphicsStateGuardian)::
 void CLP(GraphicsStateGuardian)::
 do_auto_rescale_normal() {
 do_auto_rescale_normal() {
-  if (_external_transform->has_identity_scale()) {
+  if (_internal_transform->has_identity_scale()) {
     // If there's no scale at all, don't do anything.
     // If there's no scale at all, don't do anything.
     GLP(Disable)(GL_NORMALIZE);
     GLP(Disable)(GL_NORMALIZE);
     if (GLCAT.is_spam()) {
     if (GLCAT.is_spam()) {
@@ -5646,7 +5650,7 @@ do_auto_rescale_normal() {
       }
       }
     }
     }
 
 
-  } else if (_external_transform->has_uniform_scale()) {
+  } else if (_internal_transform->has_uniform_scale()) {
     // There's a uniform scale; use the rescale feature if available.
     // There's a uniform scale; use the rescale feature if available.
     if (_supports_rescale_normal && support_rescale_normal) {
     if (_supports_rescale_normal && support_rescale_normal) {
       GLP(Enable)(GL_RESCALE_NORMAL);
       GLP(Enable)(GL_RESCALE_NORMAL);

+ 1 - 0
panda/src/gsgbase/graphicsStateGuardianBase.h

@@ -205,6 +205,7 @@ public:
   (Texture *tex, int z, const DisplayRegion *dr, const RenderBuffer &rb)=0;
   (Texture *tex, int z, const DisplayRegion *dr, const RenderBuffer &rb)=0;
   
   
   virtual CoordinateSystem get_internal_coordinate_system() const=0;
   virtual CoordinateSystem get_internal_coordinate_system() const=0;
+  virtual const TransformState *get_cs_transform() const=0;
 
 
   virtual void bind_light(PointLight *light_obj, const NodePath &light, 
   virtual void bind_light(PointLight *light_obj, const NodePath &light, 
                           int light_id) { }
                           int light_id) { }

+ 20 - 12
panda/src/parametrics/ropeNode.cxx

@@ -361,9 +361,11 @@ render_thread(CullTraverser *trav, CullTraverserData &data,
   CPT(RenderAttrib) thick = RenderModeAttrib::make(RenderModeAttrib::M_unchanged, get_thickness());
   CPT(RenderAttrib) thick = RenderModeAttrib::make(RenderModeAttrib::M_unchanged, get_thickness());
   CPT(RenderState) state = data._state->add_attrib(thick);
   CPT(RenderState) state = data._state->add_attrib(thick);
   
   
-  CullableObject *object = new CullableObject(geom, state,
-                                              data.get_net_transform(trav),
-                                              data.get_modelview_transform(trav));
+  CullableObject *object = 
+    new CullableObject(geom, state,
+                       data.get_net_transform(trav),
+                       data.get_modelview_transform(trav),
+                       trav->get_gsg());
   trav->get_cull_handler()->record_object(object, trav);
   trav->get_cull_handler()->record_object(object, trav);
 }
 }
 
 
@@ -404,9 +406,11 @@ render_tape(CullTraverser *trav, CullTraverserData &data,
   PT(Geom) geom = new Geom(vdata);
   PT(Geom) geom = new Geom(vdata);
   geom->add_primitive(strip);
   geom->add_primitive(strip);
   
   
-  CullableObject *object = new CullableObject(geom, data._state,
-                                              data.get_net_transform(trav),
-                                              data.get_modelview_transform(trav));
+  CullableObject *object = 
+    new CullableObject(geom, data._state,
+                       data.get_net_transform(trav),
+                       data.get_modelview_transform(trav),
+                       trav->get_gsg());
   trav->get_cull_handler()->record_object(object, trav);
   trav->get_cull_handler()->record_object(object, trav);
 }
 }
 
 
@@ -454,9 +458,11 @@ render_billboard(CullTraverser *trav, CullTraverserData &data,
   PT(Geom) geom = new Geom(vdata);
   PT(Geom) geom = new Geom(vdata);
   geom->add_primitive(strip);
   geom->add_primitive(strip);
   
   
-  CullableObject *object = new CullableObject(geom, data._state,
-                                              data.get_net_transform(trav),
-                                              data.get_modelview_transform(trav));
+  CullableObject *object = 
+    new CullableObject(geom, data._state,
+                       data.get_net_transform(trav),
+                       data.get_modelview_transform(trav),
+                       trav->get_gsg());
   trav->get_cull_handler()->record_object(object, trav);
   trav->get_cull_handler()->record_object(object, trav);
 }
 }
 
 
@@ -511,9 +517,11 @@ render_tube(CullTraverser *trav, CullTraverserData &data,
   PT(Geom) geom = new Geom(vdata);
   PT(Geom) geom = new Geom(vdata);
   geom->add_primitive(strip);
   geom->add_primitive(strip);
   
   
-  CullableObject *object = new CullableObject(geom, data._state,
-                                              data.get_net_transform(trav),
-                                              data.get_modelview_transform(trav));
+  CullableObject *object = 
+    new CullableObject(geom, data._state,
+                       data.get_net_transform(trav),
+                       data.get_modelview_transform(trav),
+                       trav->get_gsg());
   trav->get_cull_handler()->record_object(object, trav);
   trav->get_cull_handler()->record_object(object, trav);
 }
 }
 
 

+ 5 - 3
panda/src/parametrics/sheetNode.cxx

@@ -334,9 +334,11 @@ render_sheet(CullTraverser *trav, CullTraverserData &data,
   PT(Geom) geom = new Geom(vdata);
   PT(Geom) geom = new Geom(vdata);
   geom->add_primitive(strip);
   geom->add_primitive(strip);
   
   
-  CullableObject *object = new CullableObject(geom, data._state,
-                                              data.get_net_transform(trav),
-                                              data.get_modelview_transform(trav));
+  CullableObject *object = 
+    new CullableObject(geom, data._state,
+                       data.get_net_transform(trav),
+                       data.get_modelview_transform(trav),
+                       trav->get_gsg());
   trav->get_cull_handler()->record_object(object, trav);
   trav->get_cull_handler()->record_object(object, trav);
 }
 }
 
 

+ 1 - 1
panda/src/pgraph/cullHandler.I

@@ -29,7 +29,7 @@ draw(CullableObject *object, GraphicsStateGuardianBase *gsg) {
   if (object->_next != (CullableObject *)NULL) {
   if (object->_next != (CullableObject *)NULL) {
     draw_with_decals(object, gsg);
     draw_with_decals(object, gsg);
   } else {
   } else {
-    gsg->set_state_and_transform(object->_state, object->_modelview_transform);
+    gsg->set_state_and_transform(object->_state, object->_internal_transform);
     object->draw(gsg);
     object->draw(gsg);
   }
   }
 }
 }

+ 3 - 3
panda/src/pgraph/cullHandler.cxx

@@ -65,7 +65,7 @@ draw_with_decals(CullableObject *object, GraphicsStateGuardianBase *gsg) {
 
 
   CullableObject *base = object;
   CullableObject *base = object;
   while (base != (CullableObject *)NULL && base->_geom != (Geom *)NULL) {
   while (base != (CullableObject *)NULL && base->_geom != (Geom *)NULL) {
-    gsg->set_state_and_transform(base->_state->compose(state), base->_modelview_transform);
+    gsg->set_state_and_transform(base->_state->compose(state), base->_internal_transform);
     base->draw(gsg);
     base->draw(gsg);
     
     
     base = base->_next;
     base = base->_next;
@@ -77,7 +77,7 @@ draw_with_decals(CullableObject *object, GraphicsStateGuardianBase *gsg) {
 
 
     CullableObject *decal = base->_next;
     CullableObject *decal = base->_next;
     while (decal != (CullableObject *)NULL) {
     while (decal != (CullableObject *)NULL) {
-      gsg->set_state_and_transform(decal->_state->compose(state), decal->_modelview_transform);
+      gsg->set_state_and_transform(decal->_state->compose(state), decal->_internal_transform);
       decal->draw(gsg);
       decal->draw(gsg);
       decal = decal->_next;
       decal = decal->_next;
     }
     }
@@ -88,7 +88,7 @@ draw_with_decals(CullableObject *object, GraphicsStateGuardianBase *gsg) {
   if (state != (const RenderState *)NULL) {
   if (state != (const RenderState *)NULL) {
     base = object;
     base = object;
     while (base != (CullableObject *)NULL && base->_geom != (Geom *)NULL) {
     while (base != (CullableObject *)NULL && base->_geom != (Geom *)NULL) {
-      gsg->set_state_and_transform(base->_state->compose(state), base->_modelview_transform);
+      gsg->set_state_and_transform(base->_state->compose(state), base->_internal_transform);
       base->draw(gsg);
       base->draw(gsg);
       
       
       base = base->_next;
       base = base->_next;

+ 6 - 3
panda/src/pgraph/cullTraverser.cxx

@@ -288,7 +288,8 @@ show_bounds(CullTraverserData &data, bool tight) {
       CullableObject *outer_viz = 
       CullableObject *outer_viz = 
         new CullableObject(bounds_viz, get_bounds_outer_viz_state(), 
         new CullableObject(bounds_viz, get_bounds_outer_viz_state(), 
                            data.get_net_transform(this),
                            data.get_net_transform(this),
-                           data.get_modelview_transform(this));
+                           data.get_modelview_transform(this),
+                           get_gsg());
       _cull_handler->record_object(outer_viz, this);
       _cull_handler->record_object(outer_viz, this);
     }
     }
     
     
@@ -300,13 +301,15 @@ show_bounds(CullTraverserData &data, bool tight) {
       CullableObject *outer_viz = 
       CullableObject *outer_viz = 
         new CullableObject(bounds_viz, get_bounds_outer_viz_state(), 
         new CullableObject(bounds_viz, get_bounds_outer_viz_state(), 
                            data.get_net_transform(this),
                            data.get_net_transform(this),
-                           data.get_modelview_transform(this));
+                           data.get_modelview_transform(this),
+                           get_gsg());
       _cull_handler->record_object(outer_viz, this);
       _cull_handler->record_object(outer_viz, this);
       
       
       CullableObject *inner_viz = 
       CullableObject *inner_viz = 
         new CullableObject(bounds_viz, get_bounds_inner_viz_state(), 
         new CullableObject(bounds_viz, get_bounds_inner_viz_state(), 
                            data.get_net_transform(this),
                            data.get_net_transform(this),
-                           data.get_modelview_transform(this));
+                           data.get_modelview_transform(this),
+                           get_gsg());
       _cull_handler->record_object(inner_viz, this);
       _cull_handler->record_object(inner_viz, this);
     }
     }
   }
   }

+ 5 - 0
panda/src/pgraph/cullableObject.I

@@ -43,6 +43,7 @@ CullableObject(const CullTraverser *trav, const CullTraverserData &data,
   _state(data._state->compose(geom_node->get_geom_state(i))),
   _state(data._state->compose(geom_node->get_geom_state(i))),
   _net_transform(data.get_net_transform(trav)),
   _net_transform(data.get_net_transform(trav)),
   _modelview_transform(data.get_modelview_transform(trav)),
   _modelview_transform(data.get_modelview_transform(trav)),
+  _internal_transform(trav->get_gsg()->get_cs_transform()->compose(_modelview_transform)),
   _next(next)
   _next(next)
 {
 {
 }
 }
@@ -57,11 +58,13 @@ INLINE CullableObject::
 CullableObject(const Geom *geom, const RenderState *state,
 CullableObject(const Geom *geom, const RenderState *state,
                const TransformState *net_transform,
                const TransformState *net_transform,
                const TransformState *modelview_transform,
                const TransformState *modelview_transform,
+               const GraphicsStateGuardianBase *gsg,
                CullableObject *next) :
                CullableObject *next) :
   _geom(geom),
   _geom(geom),
   _state(state),
   _state(state),
   _net_transform(net_transform),
   _net_transform(net_transform),
   _modelview_transform(modelview_transform),
   _modelview_transform(modelview_transform),
+  _internal_transform(gsg->get_cs_transform()->compose(modelview_transform)),
   _next(next)
   _next(next)
 {
 {
 }
 }
@@ -79,6 +82,7 @@ CullableObject(const CullableObject &copy) :
   _state(copy._state),
   _state(copy._state),
   _net_transform(copy._net_transform),
   _net_transform(copy._net_transform),
   _modelview_transform(copy._modelview_transform),
   _modelview_transform(copy._modelview_transform),
+  _internal_transform(copy._internal_transform),
   _next((CullableObject *)NULL)
   _next((CullableObject *)NULL)
 {
 {
 }
 }
@@ -95,6 +99,7 @@ operator = (const CullableObject &copy) {
   _state = copy._state;
   _state = copy._state;
   _net_transform = copy._net_transform;
   _net_transform = copy._net_transform;
   _modelview_transform = copy._modelview_transform;
   _modelview_transform = copy._modelview_transform;
+  _internal_transform = copy._internal_transform;
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////

+ 2 - 0
panda/src/pgraph/cullableObject.h

@@ -53,6 +53,7 @@ public:
   INLINE CullableObject(const Geom *geom, const RenderState *state,
   INLINE CullableObject(const Geom *geom, const RenderState *state,
                         const TransformState *net_transform,
                         const TransformState *net_transform,
                         const TransformState *modelview_transform,
                         const TransformState *modelview_transform,
+                        const GraphicsStateGuardianBase *gsg,
                         CullableObject *next = NULL);
                         CullableObject *next = NULL);
     
     
   INLINE CullableObject(const CullableObject &copy);
   INLINE CullableObject(const CullableObject &copy);
@@ -77,6 +78,7 @@ public:
   CPT(RenderState) _state;
   CPT(RenderState) _state;
   CPT(TransformState) _net_transform;
   CPT(TransformState) _net_transform;
   CPT(TransformState) _modelview_transform;
   CPT(TransformState) _modelview_transform;
+  CPT(TransformState) _internal_transform;
   CullableObject *_next;
   CullableObject *_next;
 
 
   // This flag is only used by certain CullBin types.  In particular,
   // This flag is only used by certain CullBin types.  In particular,

+ 2 - 1
panda/src/pgraph/planeNode.cxx

@@ -177,7 +177,8 @@ cull_callback(CullTraverser *trav, CullTraverserData &data) {
   CullableObject *plane_viz = 
   CullableObject *plane_viz = 
     new CullableObject(get_viz(trav, data), data._state, 
     new CullableObject(get_viz(trav, data), data._state, 
                        data.get_net_transform(trav),
                        data.get_net_transform(trav),
-                       data.get_modelview_transform(trav));
+                       data.get_modelview_transform(trav),
+                       trav->get_gsg());
   trav->get_cull_handler()->record_object(plane_viz, trav);
   trav->get_cull_handler()->record_object(plane_viz, trav);
 
 
   // Now carry on to render our child nodes.
   // Now carry on to render our child nodes.