Przeglądaj źródła

NodePath::get_mat(other) needs to return a concrete

David Rose 20 lat temu
rodzic
commit
4f1a424610

+ 1 - 1
panda/src/audio/audioSound.cxx

@@ -71,4 +71,4 @@ float AudioSound::
 get_3d_max_distance() const {
   // Intentionally blank.
   return 0.0f;
-}
+}

+ 8 - 4
panda/src/collide/collisionEntry.cxx

@@ -76,7 +76,8 @@ operator = (const CollisionEntry &copy) {
 LPoint3f CollisionEntry::
 get_surface_point(const NodePath &space) const {
   nassertr(has_surface_point(), LPoint3f::zero());
-  return _surface_point * _into_node_path.get_mat(space);
+  CPT(TransformState) transform = _into_node_path.get_transform(space);
+  return _surface_point * transform->get_mat();
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -91,7 +92,8 @@ get_surface_point(const NodePath &space) const {
 LVector3f CollisionEntry::
 get_surface_normal(const NodePath &space) const {
   nassertr(has_surface_normal(), LVector3f::zero());
-  return _surface_normal * _into_node_path.get_mat(space);
+  CPT(TransformState) transform = _into_node_path.get_transform(space);
+  return _surface_normal * transform->get_mat();
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -113,7 +115,8 @@ get_interior_point(const NodePath &space) const {
   if (!has_interior_point()) {
     return get_surface_point(space);
   }
-  return _interior_point * _into_node_path.get_mat(space);
+  CPT(TransformState) transform = _into_node_path.get_transform(space);
+  return _interior_point * transform->get_mat();
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -129,7 +132,8 @@ get_interior_point(const NodePath &space) const {
 bool CollisionEntry::
 get_all(const NodePath &space, LPoint3f &surface_point,
         LVector3f &surface_normal, LPoint3f &interior_point) const {
-  const LMatrix4f &mat = _into_node_path.get_mat(space);
+  CPT(TransformState) transform = _into_node_path.get_transform(space);
+  const LMatrix4f &mat = transform->get_mat();
   bool all_ok = true;
 
   if (!has_surface_point()) {

+ 2 - 1
panda/src/collide/collisionHandlerGravity.cxx

@@ -191,7 +191,8 @@ set_highest_collision(const NodePath &target_node_path, const NodePath &from_nod
     //_contact_normal = DCAST(CollisionPlane, highest->get_into())->get_normal();
     // This is asking: what is the normal of the avatar that the avatar
     // is colliding with relative to the plane.
-    _contact_normal = DCAST(CollisionPlane, highest->get_into())->get_normal() * highest->get_into_node_path().get_mat(from_node_path);
+    CPT(TransformState) transform = highest->get_into_node_path().get_transform(from_node_path);
+    _contact_normal = DCAST(CollisionPlane, highest->get_into())->get_normal() * transform->get_mat();
   } else {
     _contact_normal = highest->get_surface_normal(from_node_path);
   }

+ 1 - 1
panda/src/collide/collisionLevelState.cxx

@@ -82,7 +82,7 @@ prepare_collider(const ColliderDef &def) {
     }
     */
 
-    gbv->xform(def._node_path.get_mat(NodePath()));
+    gbv->xform(def._node_path.get_net_transform()->get_mat());
     _local_bounds.push_back(gbv);
   }
 

+ 5 - 4
panda/src/distort/projectionScreen.cxx

@@ -196,7 +196,7 @@ generate_screen(const NodePath &projector, const string &screen_name,
   // First, get the relative coordinate space of the projector.
   LMatrix4f rel_mat;
   NodePath this_np(this);
-  rel_mat = projector.get_mat(this_np);
+  rel_mat = projector.get_transform(this_np)->get_mat();
 
   // Create a GeomNode to hold this mesh.
   PT(GeomNode) geom_node = new GeomNode(screen_name);
@@ -442,7 +442,8 @@ recompute_if_stale(const NodePath &this_np) {
 
     } else {
       // Get the relative transform to ensure it hasn't changed.
-      const LMatrix4f &top_mat = this_np.get_mat(_projector);
+      CPT(TransformState) transform = this_np.get_transform(_projector);
+      const LMatrix4f &top_mat = transform->get_mat();
       if (!_rel_top_mat.almost_equal(top_mat)) {
         _rel_top_mat = top_mat;
         _computed_rel_top_mat = true;
@@ -556,7 +557,7 @@ recompute_geom_node(const WorkingNodePath &np, LMatrix4f &rel_mat,
   if (!computed_rel_mat) {
     // All right, time to compute the matrix.
     NodePath true_np = np.get_node_path();
-    rel_mat = true_np.get_mat(_projector);
+    rel_mat = true_np.get_transform(_projector)->get_mat();
     computed_rel_mat = true;
 
     if (distort_cat.is_spam()) {
@@ -785,7 +786,7 @@ make_mesh_geom_node(const WorkingNodePath &np, const NodePath &camera,
   if (!computed_rel_mat) {
     // All right, time to compute the matrix.
     NodePath true_np = np.get_node_path();
-    rel_mat = true_np.get_mat(camera);
+    rel_mat = true_np.get_transform(camera)->get_mat();
     computed_rel_mat = true;
   }
 

+ 8 - 7
panda/src/glstuff/glGraphicsStateGuardian_src.cxx

@@ -3962,8 +3962,8 @@ bind_light(PointLight *light_obj, const NodePath &light, int light_id) {
 
   // Position needs to specify x, y, z, and w
   // w == 1 implies non-infinite position
-  const LMatrix4f &light_mat = light.get_mat(_scene_setup->get_scene_root());
-  LPoint3f pos = light_obj->get_point() * light_mat;
+  CPT(TransformState) transform = light.get_transform(_scene_setup->get_scene_root());
+  LPoint3f pos = light_obj->get_point() * transform->get_mat();
 
   LPoint4f fpos(pos[0], pos[1], pos[2], 1.0f);
   GLP(Lightfv)(id, GL_POSITION, fpos.get_data());
@@ -4002,8 +4002,8 @@ bind_light(DirectionalLight *light_obj, const NodePath &light, int light_id) {
 
   // Position needs to specify x, y, z, and w.
   // w == 0 implies light is at infinity
-  const LMatrix4f &light_mat = light.get_mat(_scene_setup->get_scene_root());
-  LVector3f dir = light_obj->get_direction() * light_mat;
+  CPT(TransformState) transform = light.get_transform(_scene_setup->get_scene_root());
+  LVector3f dir = light_obj->get_direction() * transform->get_mat();
   LPoint4f fdir(-dir[0], -dir[1], -dir[2], 0);
   GLP(Lightfv)(id, GL_POSITION, fdir.get_data());
 
@@ -4046,7 +4046,8 @@ bind_light(Spotlight *light_obj, const NodePath &light, int light_id) {
 
   // Position needs to specify x, y, z, and w
   // w == 1 implies non-infinite position
-  const LMatrix4f &light_mat = light.get_mat(_scene_setup->get_scene_root());
+  CPT(TransformState) transform = light.get_transform(_scene_setup->get_scene_root());
+  const LMatrix4f &light_mat = transform->get_mat();
   LPoint3f pos = lens->get_nodal_point() * light_mat;
   LVector3f dir = lens->get_view_vector() * light_mat;
 
@@ -5698,10 +5699,10 @@ void CLP(GraphicsStateGuardian)::
 bind_clip_plane(const NodePath &plane, int plane_id) {
   GLenum id = get_clip_plane_id(plane_id);
 
-  const LMatrix4f &plane_mat = plane.get_mat(_scene_setup->get_scene_root());
+  CPT(TransformState) transform = plane.get_transform(_scene_setup->get_scene_root());
   const PlaneNode *plane_node;
   DCAST_INTO_V(plane_node, plane.node());
-  Planef xformed_plane = plane_node->get_plane() * plane_mat;
+  Planef xformed_plane = plane_node->get_plane() * transform->get_mat();
 
   Planed double_plane(LCAST(double, xformed_plane));
   GLP(ClipPlane)(id, double_plane.get_data());

+ 4 - 2
panda/src/parametrics/nurbsSurfaceEvaluator.cxx

@@ -276,7 +276,8 @@ get_vertices(pvector<LVecBase4f> &verts, const NodePath &rel_to) const {
     if (space.is_empty()) {
       verts.push_back(vertex);
     } else {
-      const LMatrix4f &mat = space.get_mat(rel_to);
+      CPT(TransformState) transform = space.get_transform(rel_to);
+      const LMatrix4f &mat = transform->get_mat();
       verts.push_back(vertex * mat);
     }
   }
@@ -302,7 +303,8 @@ get_vertices(pvector<LPoint3f> &verts, const NodePath &rel_to) const {
     const NodePath &space = _vertices[vi].get_space(rel_to);
     LVecBase4f vertex = _vertices[vi].get_vertex();
     if (!space.is_empty()) {
-      const LMatrix4f &mat = space.get_mat(rel_to);
+      CPT(TransformState) transform = space.get_transform(rel_to);
+      const LMatrix4f &mat = transform->get_mat();
       vertex = vertex * mat;
     }
     LPoint3f v3(vertex[0] / vertex[3], vertex[1] / vertex[3], vertex[2] / vertex[3]);

+ 5 - 2
panda/src/particlesystem/particleSystem.cxx

@@ -179,7 +179,9 @@ birth_particle(void) {
   // go from birth space to render space
   NodePath physical_np(get_physical_node());
   NodePath render_np(render_node);
-  const LMatrix4f &birth_to_render_xform = physical_np.get_mat(render_np);
+
+  CPT(TransformState) transform = physical_np.get_transform(render_np);
+  const LMatrix4f &birth_to_render_xform = transform->get_mat();
   world_pos = new_pos * birth_to_render_xform;
 
   //  cout << "New particle at " << world_pos << endl;
@@ -272,7 +274,8 @@ spawn_child_system(BaseParticle *bp) {
   NodePath parent_np(parent);
   NodePath physical_np(get_physical_node());
 
-  const LMatrix4f &old_system_to_parent_xform = physical_np.get_mat(parent_np);
+  CPT(TransformState) transform = physical_np.get_transform(parent_np);
+  const LMatrix4f &old_system_to_parent_xform = transform->get_mat();
 
   LMatrix4f child_space_xform = old_system_to_parent_xform *
     bp->get_lcs();

+ 20 - 18
panda/src/pgraph/nodePath.cxx

@@ -1850,14 +1850,14 @@ set_pos_quat_scale_shear(const NodePath &other,
 //               space of the bottom node, relative to the other
 //               path's bottom node's coordinate space.
 ////////////////////////////////////////////////////////////////////
-const LMatrix4f &NodePath::
+LMatrix4f NodePath::
 get_mat(const NodePath &other) const {
   CPT(TransformState) transform = get_transform(other);
-  // We can safely assume the transform won't go away when the
-  // function returns, since its reference count is also held in the
-  // cache.  This assumption allows us to return a reference to the
-  // matrix, instead of having to return a matrix on the stack.
-  nassertr(transform->get_ref_count() > 1, LMatrix4f::ident_mat());
+  // We can't safely return a reference to the matrix, because we
+  // can't assume the transform won't go away when the function
+  // returns.  If the transform was partially modified by, say, a
+  // CompassEffect, it won't be stored in the cache, and thus we might
+  // have the only reference to it.
   return transform->get_mat();
 }
 
@@ -1884,7 +1884,8 @@ set_mat(const NodePath &other, const LMatrix4f &mat) {
 ////////////////////////////////////////////////////////////////////
 LPoint3f NodePath::
 get_relative_point(const NodePath &other, const LVecBase3f &point) const {
-  LPoint3f rel_point = LPoint3f(point) * other.get_mat(*this);
+  CPT(TransformState) transform = other.get_transform(*this);
+  LPoint3f rel_point = LPoint3f(point) * transform->get_mat();
   return rel_point;
 }
 
@@ -1897,7 +1898,8 @@ get_relative_point(const NodePath &other, const LVecBase3f &point) const {
 ////////////////////////////////////////////////////////////////////
 LVector3f NodePath::
 get_relative_vector(const NodePath &other, const LVecBase3f &vec) const {
-  LVector3f rel_vector = LVector3f(vec) * other.get_mat(*this);
+  CPT(TransformState) transform = other.get_transform(*this);
+  LVector3f rel_vector = LVector3f(vec) * transform->get_mat();
   return rel_vector;
 }
 
@@ -1912,8 +1914,8 @@ void NodePath::
 look_at(const NodePath &other, const LPoint3f &point, const LVector3f &up) {
   nassertv_always(!is_empty());
 
-  NodePath parent = get_parent();
-  LPoint3f rel_point = point * other.get_mat(parent);
+  CPT(TransformState) transform = other.get_transform(get_parent());
+  LPoint3f rel_point = point * transform->get_mat();
 
   LPoint3f pos = get_pos();
 
@@ -1933,8 +1935,8 @@ void NodePath::
 heads_up(const NodePath &other, const LPoint3f &point, const LVector3f &up) {
   nassertv_always(!is_empty());
 
-  NodePath parent = get_parent();
-  LPoint3f rel_point = point * other.get_mat(parent);
+  CPT(TransformState) transform = other.get_transform(get_parent());
+  LPoint3f rel_point = point * transform->get_mat();
 
   LPoint3f pos = get_pos();
 
@@ -4185,8 +4187,8 @@ void NodePath::
 do_billboard_axis(const NodePath &camera, float offset) {
   nassertv_always(!is_empty());
 
-  NodePath parent = get_parent();
-  LMatrix4f rel_mat = camera.get_mat(parent);
+  CPT(TransformState) transform = camera.get_transform(get_parent());
+  const LMatrix4f &rel_mat = transform->get_mat();
 
   LVector3f up = LVector3f::up();
   LVector3f rel_pos = -rel_mat.get_row3(3);
@@ -4218,8 +4220,8 @@ void NodePath::
 do_billboard_point_eye(const NodePath &camera, float offset) {
   nassertv_always(!is_empty());
 
-  NodePath parent = get_parent();
-  LMatrix4f rel_mat = camera.get_mat(parent);
+  CPT(TransformState) transform = camera.get_transform(get_parent());
+  const LMatrix4f &rel_mat = transform->get_mat();
 
   LVector3f up = LVector3f::up() * rel_mat;
   LVector3f rel_pos = LVector3f::forward() * rel_mat;
@@ -4249,8 +4251,8 @@ void NodePath::
 do_billboard_point_world(const NodePath &camera, float offset) {
   nassertv_always(!is_empty());
 
-  NodePath parent = get_parent();
-  LMatrix4f rel_mat = camera.get_mat(parent);
+  CPT(TransformState) transform = camera.get_transform(get_parent());
+  const LMatrix4f &rel_mat = transform->get_mat();
 
   LVector3f up = LVector3f::up();
   LVector3f rel_pos = -rel_mat.get_row3(3);

+ 1 - 1
panda/src/pgraph/nodePath.h

@@ -465,7 +465,7 @@ PUBLISHED:
                                 const LVecBase3f &scale,
                                 const LVecBase3f &shear);
 
-  const LMatrix4f &get_mat(const NodePath &other) const;
+  LMatrix4f get_mat(const NodePath &other) const;
   void set_mat(const NodePath &other, const LMatrix4f &mat);
 
   LPoint3f get_relative_point(const NodePath &other, const LVecBase3f &point) const;

+ 4 - 4
panda/src/physics/baseIntegrator.cxx

@@ -78,7 +78,7 @@ precompute_linear_matrices(Physical *physical,
     nassertv(force_node != (ForceNode *) NULL);
 
     NodePath force_np(force_node);
-    _precomputed_linear_matrices.push_back(force_np.get_mat(parent_physical_np));
+    _precomputed_linear_matrices.push_back(force_np.get_transform(parent_physical_np)->get_mat());
   }
 
   // tally the local xforms
@@ -88,7 +88,7 @@ precompute_linear_matrices(Physical *physical,
     nassertv(force_node != (ForceNode *) NULL);
 
     NodePath force_np(force_node);
-    _precomputed_linear_matrices.push_back(force_np.get_mat(parent_physical_np));
+    _precomputed_linear_matrices.push_back(force_np.get_transform(parent_physical_np)->get_mat());
   }
 }
 
@@ -130,7 +130,7 @@ precompute_angular_matrices(Physical *physical,
     nassertv(force_node != (ForceNode *) NULL);
 
     NodePath force_np(force_node);
-    _precomputed_angular_matrices.push_back(force_np.get_mat(parent_physical_np));
+    _precomputed_angular_matrices.push_back(force_np.get_transform(parent_physical_np)->get_mat());
   }
 
   // tally the local xforms
@@ -140,7 +140,7 @@ precompute_angular_matrices(Physical *physical,
     nassertv(force_node != (ForceNode *) NULL);
 
     NodePath force_np(force_node);
-    _precomputed_angular_matrices.push_back(force_np.get_mat(parent_physical_np));
+    _precomputed_angular_matrices.push_back(force_np.get_transform(parent_physical_np)->get_mat());
   }
 }
 

+ 0 - 536
panda/src/testbed/demo.cxx

@@ -1,536 +0,0 @@
-// Filename: demo.cxx
-// Created by:  
-//
-////////////////////////////////////////////////////////////////////
-//
-// PANDA 3D SOFTWARE
-// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
-//
-// All use of this software is subject to the terms of the Panda 3d
-// Software license.  You should have received a copy of this license
-// along with this source code; you will also find a current copy of
-// the license at http://etc.cmu.edu/panda3d/docs/license/ .
-//
-// To contact the maintainers of this program write to
-// [email protected] .
-//
-////////////////////////////////////////////////////////////////////
-
-#include "framework.h"
-
-#include "eventHandler.h"
-#include "chancfg.h"
-#include "string"
-#include "renderModeTransition.h"
-#include "colorTransition.h"
-#include "colorBlendTransition.h"
-#include "cullFaceTransition.h"
-#include "depthTestTransition.h"
-#include "depthWriteTransition.h"
-#include "textureTransition.h"
-#include "textureApplyTransition.h"
-#include "materialTransition.h"
-#include "transformTransition.h"
-#include "transparencyTransition.h"
-#include "drawBoundsTransition.h"
-#include "pruneTransition.h"
-#include "get_rel_pos.h"
-#include "boundingSphere.h"
-#include "geomSphere.h"
-#include "geomNode.h"
-#include "notify.h"
-#include "directionalLight.h"
-#include "renderRelation.h"
-#include "camera.h"
-#include "frustum.h"
-#include "textNode.h"
-#include "colorMatrixTransition.h"
-#include "alphaTransformTransition.h"
-#include "lensFlareNode.h"
-#include "texture.h"
-#include "texturePool.h"
-#include "spotlight.h"
-#include "nodePath.h"
-#include "pta_Colorf.h"
-#include "pta_float.h"
-#include "pt_Node.h"
-#include "panda.h"
-
-// If we're doing a static link, we should explicitly initialize some
-// of our external libraries, or they may not get linked in.
-#ifdef LINK_ALL_STATIC
-  #ifdef HAVE_GL
-    #include "pandagl.h"
-  #endif
-  #ifdef HAVE_DX
-    #include "pandadx.h"
-  #endif
-  #include "pandaegg.h"
-#endif
-
-//From framework
-extern PT(GeomNode) geomnode;
-extern RenderRelation* first_arc;
-
-// These variables are used to implement the set_highlight() and
-// related functions to allow the user to walk through the scene graph
-// with the arrow keys.
-
-// highlight_render_node is a special node that has a funny render
-// mode set on it to draw things in red wireframe, but it has no
-// geometry of its own.  The node that we're currently highlighting
-// (current_node) is instanced under highlight_render_node via
-// current_arc, so that the highlight applies to that node.
-RenderRelation *highlight_arc = NULL;
-PT_NamedNode highlight_render_node;
-RenderRelation *current_arc = NULL;
-
-NodePath selected_node;
-
-PT_NamedNode render2d_top;
-RenderRelation *render2d_arc = NULL;
-PT_NamedNode render2d;
-
-PT(TextNode) label2d;
-
-//Global Node used by LensFlare and NodePath color/alpha demos
-PT_NamedNode sky = (NamedNode *)NULL;
-RenderRelation *sky_arc = (RenderRelation *)NULL;
-RenderRelation *flare_arc = (RenderRelation *)NULL;
-
-
-static void
-clear_highlight() {
-  if (selected_node.has_arcs()) {
-    selected_node.hide_bounds();
-  }
-
-  if (current_arc != NULL) {
-    remove_arc(current_arc);
-    current_arc = NULL;
-  }
-}
-
-static void
-set_highlight() {
-  // Transform the highlight to the coordinate space of the node.
-  LMatrix4f mat = selected_node.get_mat(NodePath(render));
-  highlight_arc->set_transition(new TransformTransition(mat));
-
-  nout << "Highlighting " << selected_node.as_string(1) << "\n";
-
-  nout << "Bounding volume of node is " << selected_node.node()->get_bound() << "\n";
-
-  if (selected_node.has_arcs()) {
-    nout << "Bounding volume of arc is " << *selected_node.get_bounds() << "\n";
-
-    nout << "Transitions on arc:\n";
-    selected_node.arc()->write_transitions(nout, 2);
-    selected_node.show_bounds();
-  }
-
-  current_arc = new RenderRelation(highlight_render_node, selected_node.node());
-}
-
-static void
-event_up(CPT_Event) {
-  if (selected_node.has_arcs() && selected_node.get_node(1) != root) {
-    clear_highlight();
-    selected_node.shorten(1);
-    set_highlight();
-  }
-}
-
-static void
-event_down(CPT_Event) {
-  if (!selected_node.is_empty() &&
-      selected_node.get_num_children() != 0) {
-    clear_highlight();
-    selected_node = selected_node.get_child(0);
-    set_highlight();
-  }
-}
-
-static void
-event_left(CPT_Event) {
-  // Go to the previous child in the sibling list, if there is one.
-  if (selected_node.has_arcs()) {
-    NodePath parent = selected_node;
-    parent.shorten(1);
-    int num_children = parent.get_num_children();
-
-    for (int i = 0; i < num_children; i++) {
-      if (parent.get_child(i) == selected_node) {
-        // We've currently got child i; now select child i-1.
-        if (i - 1 >=  0) {
-          clear_highlight();
-          selected_node = parent.get_child(i - 1);
-          set_highlight();
-        }
-        return;
-      }
-    }
-  }
-}
-
-static void
-event_right(CPT_Event) {
-  // Go to the next child in the sibling list, if there is one.
-  if (selected_node.has_arcs()) {
-    NodePath parent = selected_node;
-    parent.shorten(1);
-    int num_children = parent.get_num_children();
-
-    for (int i = 0; i < num_children; i++) {
-      if (parent.get_child(i) == selected_node) {
-        // We've currently got child i; now select child i + 11.
-        if (i + 1 < num_children) {
-          clear_highlight();
-          selected_node = parent.get_child(i + 1);
-          set_highlight();
-        }
-        return;
-      }
-    }
-  }
-}
-
-static void
-event_fkey(CPT_Event event) {
-  if (selected_node.has_arcs()) {
-    string name = event->get_name();
-    if (name.substr(0, 6) == "shift-") {
-      // Shift-fkey: work with color scale.
-      if (name == "shift-f9") {
-        selected_node.clear_color_scale();
-        selected_node.clear_transparency();
-        cerr << "Clearing color scale on " << selected_node << "\n";
-
-      } else {
-        Colorf color_scale;
-        if (name == "shift-f1") {
-          color_scale.set(0.5, 0.5, 1.0, 1.0);
-        } else if (name == "shift-f2") {
-          color_scale.set(0.5, 1.0, 0.5, 1.0);
-        } else if (name == "shift-f3") {
-          color_scale.set(0.5, 1.0, 1.0, 1.0);
-        } else if (name == "shift-f4") {
-          color_scale.set(1.0, 0.5, 0.5, 1.0);
-        } else if (name == "shift-f5") {
-          color_scale.set(1.0, 0.5, 1.0, 1.0);
-        } else if (name == "shift-f6") {
-          color_scale.set(1.0, 1.0, 0.5, 1.0);
-        } else if (name == "shift-f7") {
-          color_scale.set(1.0, 1.0, 1.0, 1.0);
-        } else if (name == "shift-f8") {
-          color_scale.set(1.0, 1.0, 1.0, 0.5);
-        }
-        selected_node.set_color_scale(color_scale);
-        if (color_scale[3] != 1.0) { 
-          selected_node.set_transparency(true);
-        }
-        cerr << "Setting color scale on " << selected_node << " to " << color_scale << "\n";
-      }
-    } else {
-      // Non shifted fkey: work with flat color.
-        
-      if (name == "f9") {
-        // F9: restore the natural color.
-        selected_node.clear_color();
-        selected_node.clear_transparency();
-        cerr << "Clearing color on " << selected_node << "\n";
-        
-      } else {
-        Colorf color;
-        if (name == "f1") {
-          color.set(0.0, 0.0, 1.0, 1.0);
-        } else if (name == "f2") {
-          color.set(0.0, 1.0, 0.0, 1.0);
-        } else if (name == "f3") {
-          color.set(0.0, 1.0, 1.0, 1.0);
-        } else if (name == "f4") {
-          color.set(1.0, 0.0, 0.0, 1.0);
-        } else if (name == "f5") {
-          color.set(1.0, 0.0, 1.0, 1.0);
-        } else if (name == "f6") {
-          color.set(1.0, 1.0, 0.0, 1.0);
-        } else if (name == "f7") {
-          color.set(1.0, 1.0, 1.0, 1.0);
-        } else if (name == "f8") {
-          color.set(1.0, 1.0, 1.0, 0.5);
-        }
-        selected_node.set_color(color, 1);
-        if (color[3] != 1.0) { 
-          selected_node.set_transparency(true);
-        }
-        cerr << "Setting color on " << selected_node << " to " << color << "\n";
-      }
-    }
-  }
-}
-
-static void
-event_B(CPT_Event event) {
-  // List everything under the selected bounding volume and
-  // recompute the volume.
-  selected_node.ls();
-  selected_node.analyze();
-
-  if (selected_node.has_arcs()) {
-    selected_node.arc()->force_bound_stale();
-  }
-}
-
-static void
-enable_highlight() {
-  if (highlight_render_node == NULL) {
-    highlight_render_node = new NamedNode("highlight");
-    highlight_arc = new RenderRelation(render, highlight_render_node);
-
-    // Set up the funny rendering attributes on the highlighted
-    // geometry.
-    RenderModeTransition *rmt =
-      new RenderModeTransition(RenderModeProperty::M_wireframe);
-    ColorTransition *ct =
-      new ColorTransition(1.0, 0.0, 0.0, 1.0);
-    CullFaceTransition *cft =
-      new CullFaceTransition(CullFaceProperty::M_cull_none);
-    TextureTransition *tt =
-      new TextureTransition;
-
-    rmt->set_priority(100);
-    ct->set_priority(100);
-    cft->set_priority(100);
-    tt->set_priority(100);
-
-    highlight_arc->set_transition(rmt);
-    highlight_arc->set_transition(ct);
-    highlight_arc->set_transition(cft);
-    highlight_arc->set_transition(tt);
-  }
-
-  // Add a temporary arc from the highlight render node to the node we
-  // are highlighting.
-  selected_node = NodePath(root);
-  if (selected_node.get_num_children() == 0) {
-    nout << "No nodes.\n";
-    selected_node.clear();
-
-  } else {
-    selected_node = selected_node.get_child(0);
-    set_highlight();
-  }
-}
-
-static void
-disable_highlight() {
-  nout << "Disabling highlight\n";
-  clear_highlight();
-  selected_node.clear();
-}
-
-static void
-event_h(CPT_Event) {
-  if (selected_node.is_empty()) {
-    enable_highlight();
-  } else {
-    disable_highlight();
-  }
-}
-
-static bool attach_sky() {
-  // Load the sun and sky
-  sky = DCAST(NamedNode, loader.load_sync("sky"));
-  if (sky != (NamedNode *)NULL) {
-    if (sky_arc == (RenderRelation *)NULL) {
-      sky_arc = new RenderRelation(render, sky);
-    }
-  }
-  return (sky!=NULL) && (sky_arc!=NULL);
-}
-
-static void
-event_k(CPT_Event) {
-  static bool is_color_mat = false;
-
-  if (!is_color_mat) {
-    LMatrix4f color_mat = LMatrix4f::scale_mat(0,0,0) * LMatrix4f::translate_mat(1,0,0);
-
-    first_arc->set_transition(new ColorMatrixTransition(color_mat));
-  }
-  else {
-    LMatrix4f color_mat = LMatrix4f::ident_mat();
-
-    first_arc->set_transition(new ColorMatrixTransition(color_mat));
-  }
-  is_color_mat = !is_color_mat;
-}
-
-static void
-event_a(CPT_Event) {
-  static bool is_alpha = false;
-
-  if (!is_alpha) {
-    first_arc->set_transition(new AlphaTransformTransition(-0.5, 1));
-    first_arc->set_transition(new TransparencyTransition(TransparencyProperty::M_alpha));
-  }
-  else {
-    first_arc->clear_transition(AlphaTransformTransition::get_class_type());
-    first_arc->clear_transition(TransparencyTransition::get_class_type());
-  }
-  is_alpha = !is_alpha;
-}
-
-
-static void
-event_v(CPT_Event) {
-  static bool is_color_scale = false;
-
-  if(!attach_sky())
-    return;
-
-  NodePath search(sky);
-  NodePath sky_search = search.find("**/sun");
-
-  if (!is_color_scale) {
-    sky_search.set_color_scale(1, 0.5, 0.5, 0.5);
-    sky_search.set_transparency(true);
-  }
-  else {
-    sky_search.clear_color_scale();
-    sky_search.clear_transparency();
-  }
-  is_color_scale = !is_color_scale;
-}
-
-static void
-event_L(CPT_Event) {
-  static bool is_flare = false;
-
-  if(!attach_sky())
-    return;
-
-  if (!is_flare) {
-    //Texture *shine = TexturePool::load_texture("MyShine.bw");
-    Texture *shine = TexturePool::load_texture("bigsmileycrop.rgba");
-
-    Texture *f4 = TexturePool::load_texture("Flare4.bw");
-    Texture *f5 = TexturePool::load_texture("Flare5.bw");
-    Texture *f6 = TexturePool::load_texture("Flare6.bw");
-
-    LensFlareNode *flare = new LensFlareNode();
-
-    PTA_float scales, offsets, angles;
-    PTA_Colorf colors;
-
-    scales.push_back(0.5); offsets.push_back(0.2); angles.push_back(0); colors.push_back(Colorf(0.3, 0.6, 0.3, 1));
-    scales.push_back(0.5); offsets.push_back(0.4); angles.push_back(0); colors.push_back(Colorf(0.6, 0.6, 0.6, 1));
-    scales.push_back(0.75); offsets.push_back(0.7); angles.push_back(0.2); colors.push_back(Colorf(0.3, 0.6, 0.3, 1));
-    scales.push_back(1.5); offsets.push_back(1.2); angles.push_back(0); colors.push_back(Colorf(0.6, 0.6, 0.6, 1));
-    scales.push_back(0.75); offsets.push_back(1.5); angles.push_back(0); colors.push_back(Colorf(0.6, 0.6, 0.6, 1));
-
-    flare->add_flare(f6, scales, offsets, angles, colors);
-
-    scales.clear(); offsets.clear(); angles.clear(); colors.clear();
-
-    scales.push_back(0.3); offsets.push_back(0.55); angles.push_back(0); colors.push_back(Colorf(0.0, 0.0, 0.6, 1));
-    scales.push_back(0.3); offsets.push_back(0.8); angles.push_back(0); colors.push_back(Colorf(0.0, 0.0, 0.6, 1));
-    scales.push_back(0.5); offsets.push_back(1.1); angles.push_back(0); colors.push_back(Colorf(0.0, 0.0, 0.6, 1));
-    scales.push_back(0.15); offsets.push_back(1.35); angles.push_back(0.2); colors.push_back(Colorf(0.3, 0.6, 0.3, 1));
-
-    flare->add_flare(f5, scales, offsets, angles, colors);
-
-    scales.clear(); offsets.clear(); angles.clear(); colors.clear();
-
-    scales.push_back(1); offsets.push_back(0.0); angles.push_back(-0.3); colors.push_back(Colorf(1.0, 0.0, 0.0, 1));
-    scales.push_back(1.05); offsets.push_back(0.0); angles.push_back(-0.3); colors.push_back(Colorf(0.0, 1.0, 0.0, 1));
-    scales.push_back(1.1); offsets.push_back(0.0); angles.push_back(-0.3); colors.push_back(Colorf(0.0, 0.0, 1.0, 1));
-
-    flare->add_flare(f4, scales, offsets, angles, colors);
-
-    flare->add_blind(shine);
-    flare->set_blind_falloff(5);
-    flare->set_flare_falloff(45);
-
-    NodePath search(sky);
-    NodePath sky_search = search.find("**/sun");
-    PT_Node light = sky_search.node();
-
-    flare->set_light_source(light);
-    flare_arc = new RenderRelation(light, flare, 10);
-    ColorBlendTransition *cb = new ColorBlendTransition(ColorBlendProperty::M_add);
-    flare_arc->set_transition(cb);
-
-    TextureApplyTransition *ta =
-      new TextureApplyTransition(TextureApplyProperty::M_decal);
-    flare_arc->set_transition(ta);
-
-    DepthTestTransition *dta =
-      new DepthTestTransition(DepthTestProperty::M_none);
-    flare_arc->set_transition(dta);
-  }
-  else {
-    remove_arc(flare_arc);
-  }
-
-  is_flare = !is_flare;
-}
-
-void demo_keys(EventHandler&) {
-  /*
-  event_handler.add_hook("mw-in-label2d", event_in_label2d);
-  event_handler.add_hook("mw-out-label2d", event_out_label2d);
-  */
-
-  event_handler.add_hook("h", event_h);
-  event_handler.add_hook("up", event_up);
-  event_handler.add_hook("down", event_down);
-  event_handler.add_hook("left", event_left);
-  event_handler.add_hook("right", event_right);
-  event_handler.add_hook("f1", event_fkey);
-  event_handler.add_hook("f2", event_fkey);
-  event_handler.add_hook("f3", event_fkey);
-  event_handler.add_hook("f4", event_fkey);
-  event_handler.add_hook("f5", event_fkey);
-  event_handler.add_hook("f6", event_fkey);
-  event_handler.add_hook("f7", event_fkey);
-  event_handler.add_hook("f8", event_fkey);
-  event_handler.add_hook("f9", event_fkey);
-  event_handler.add_hook("shift-f1", event_fkey);
-  event_handler.add_hook("shift-f2", event_fkey);
-  event_handler.add_hook("shift-f3", event_fkey);
-  event_handler.add_hook("shift-f4", event_fkey);
-  event_handler.add_hook("shift-f5", event_fkey);
-  event_handler.add_hook("shift-f6", event_fkey);
-  event_handler.add_hook("shift-f7", event_fkey);
-  event_handler.add_hook("shift-f8", event_fkey);
-  event_handler.add_hook("shift-f9", event_fkey);
-  event_handler.add_hook("shift-b", event_B);
-
-  event_handler.add_hook("shift-l", event_L);
-  event_handler.add_hook("k", event_k);
-  event_handler.add_hook("a", event_a);
-  event_handler.add_hook("v", event_v);
-}
-
-int main(int argc, char *argv[]) {
-  // We call init_libpanda() to be paranoid.  It's not supposed to be
-  // necessary, but it turns out that static init isn't dependable in
-  // all cases.
-  init_libpanda();
-
-  // If we're doing a static link, we should explicitly initialize some
-  // of our external libraries, or they may not get linked in.
-#ifdef LINK_ALL_STATIC
-  #ifdef HAVE_GL
-  init_libpandagl();
-  #endif
-  #ifdef HAVE_DX
-  init_libpandadx();
-  #endif
-  init_libpandaegg();
-#endif
-
-  define_keys = &demo_keys;
-  return framework_main(argc, argv);
-}

+ 2 - 4
panda/src/tform/trackball.cxx

@@ -486,8 +486,7 @@ reextract() {
   LMatrix4f m = _orig;
   if (!_rel_to.is_empty()) {
     NodePath root;
-    const LMatrix4f &rel_mat = root.get_mat(_rel_to);
-    m = _orig * rel_mat;
+    m = _orig * root.get_transform(_rel_to)->get_mat();
   }
 
   m.get_row3(_translation,3);
@@ -507,8 +506,7 @@ recompute() {
 
   if (!_rel_to.is_empty()) {
     NodePath root;
-    const LMatrix4f &rel_mat = _rel_to.get_mat(root);
-    _orig = _orig * rel_mat;
+    _orig = _orig * _rel_to.get_transform(root)->get_mat();
   }
 
   if (_invert) {