Browse Source

add source_geometry option

David Rose 24 years ago
parent
commit
41e725daf7

+ 1 - 1
panda/src/grutil/Sources.pp

@@ -4,7 +4,7 @@
 #begin lib_target
 #begin lib_target
   #define TARGET grutil
   #define TARGET grutil
   #define LOCAL_LIBS \
   #define LOCAL_LIBS \
-    sgraph gobj linmath putil
+    sgraphutil sgattrib sgraph gobj linmath putil
 
 
   #define SOURCES \
   #define SOURCES \
     cardMaker.I cardMaker.cxx cardMaker.h \
     cardMaker.I cardMaker.cxx cardMaker.h \

+ 53 - 0
panda/src/grutil/cardMaker.I

@@ -81,3 +81,56 @@ INLINE void CardMaker::
 set_frame(const LVecBase4f &frame) {
 set_frame(const LVecBase4f &frame) {
   _frame = frame;
   _frame = frame;
 }
 }
+
+////////////////////////////////////////////////////////////////////
+//     Function: CardMaker::set_color
+//       Access: Public
+//  Description: Sets the color of the card.
+////////////////////////////////////////////////////////////////////
+INLINE void CardMaker::
+set_color(float r, float g, float b, float a) {
+  set_color(LVecBase4f(r, g, b, a));
+} 
+
+////////////////////////////////////////////////////////////////////
+//     Function: CardMaker::set_color
+//       Access: Public
+//  Description: Sets the color of the card.
+////////////////////////////////////////////////////////////////////
+INLINE void CardMaker::
+set_color(const LVecBase4f &color) {
+  _color = color;
+  _has_color = true;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: CardMaker::set_source_geometry
+//       Access: Published
+//  Description: Sets a node that will be copied (and scaled and
+//               translated) to generate the frame, instead of
+//               generating a new polygon.  The node may contain
+//               arbitrary geometry that describes a flat polygon
+//               contained within the indicated left, right, bottom,
+//               top frame.
+//
+//               When generate() is called, the geometry in this node
+//               will be scaled and translated appropriately to give
+//               it the size and aspect ratio specified by
+//               set_frame().
+////////////////////////////////////////////////////////////////////
+INLINE void CardMaker::
+set_source_geometry(Node *node, const LVecBase4f &frame) {
+  _source_geometry = node;
+  _source_frame = frame;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: CardMaker::clear_source_geometry
+//       Access: Published
+//  Description: Removes the node specified by an earlier call to
+//               set_source_geometry().
+////////////////////////////////////////////////////////////////////
+INLINE void CardMaker::
+clear_source_geometry() {
+  _source_geometry = (Node *)NULL;
+}

+ 68 - 1
panda/src/grutil/cardMaker.cxx

@@ -19,6 +19,10 @@
 #include "cardMaker.h"
 #include "cardMaker.h"
 #include "geomNode.h"
 #include "geomNode.h"
 #include "geomTristrip.h"
 #include "geomTristrip.h"
+#include "renderRelation.h"
+#include "transformTransition.h"
+#include "colorTransition.h"
+#include "sceneGraphReducer.h"
 
 
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -32,6 +36,10 @@ reset() {
   _ll.set(0.0, 0.0);
   _ll.set(0.0, 0.0);
   _ur.set(1.0, 1.0);
   _ur.set(1.0, 1.0);
   _frame.set(0.0, 1.0, 0.0, 1.0);
   _frame.set(0.0, 1.0, 0.0, 1.0);
+  _has_color = false;
+  _color.set(1.0, 1.0, 1.0, 1.0);
+  _source_geometry = (Node *)NULL;
+  _source_frame.set(0.0, 0.0, 0.0, 0.0);
 }
 }
 
 
 
 
@@ -43,6 +51,10 @@ reset() {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 PT_Node CardMaker::
 PT_Node CardMaker::
 generate() {
 generate() {
+  if (_source_geometry != (Node *)NULL) {
+    return rescale_source_geometry();
+  }
+
   PT(GeomNode) gnode = new GeomNode("card");
   PT(GeomNode) gnode = new GeomNode("card");
   Geom *geom = new GeomTristrip;
   Geom *geom = new GeomTristrip;
   gnode->add_geom(geom);
   gnode->add_geom(geom);
@@ -67,7 +79,7 @@ generate() {
   geom->set_coords(verts, G_PER_VERTEX);
   geom->set_coords(verts, G_PER_VERTEX);
 
 
   PTA_Colorf colors;
   PTA_Colorf colors;
-  colors.push_back(Colorf(1.0, 1.0, 1.0, 1.0));
+  colors.push_back(_color);
   geom->set_colors(colors, G_OVERALL);
   geom->set_colors(colors, G_OVERALL);
 
 
   if (_has_uvs) {
   if (_has_uvs) {
@@ -81,3 +93,58 @@ generate() {
   
   
   return gnode.p();
   return gnode.p();
 }
 }
+
+////////////////////////////////////////////////////////////////////
+//     Function: CardMaker::rescale_source_geometry
+//       Access: Private
+//  Description: Generates the card by rescaling the source geometry
+//               appropriately.
+////////////////////////////////////////////////////////////////////
+PT_Node CardMaker::
+rescale_source_geometry() {
+  PT_Node root = new NamedNode;
+  NodeRelation *root_arc = 
+    new RenderRelation(root, _source_geometry->copy_subgraph(RenderRelation::get_class_type()));
+
+  // Determine the translate and scale appropriate for our geometry.
+  float geom_center_x = (_source_frame[0] + _source_frame[1]) / 2.0;
+  float geom_center_y = (_source_frame[2] + _source_frame[3]) / 2.0;
+
+  float frame_center_x = (_frame[0] + _frame[1]) / 2.0;
+  float frame_center_y = (_frame[2] + _frame[3]) / 2.0;
+
+  float scale_x = 
+    (_frame[1] - _frame[0]) / (_source_frame[1] - _source_frame[0]);
+  float scale_y = 
+    (_frame[3] - _frame[2]) / (_source_frame[3] - _source_frame[2]);
+
+  LVector3f trans = LVector3f::rfu(frame_center_x - geom_center_x, 0.0, 
+                                   frame_center_y - geom_center_y);
+  LVector3f scale = LVector3f::rfu(scale_x, 1.0, scale_y);
+
+  LMatrix4f mat = 
+    LMatrix4f::translate_mat(trans) *
+    LMatrix4f::scale_mat(scale);
+
+  root_arc->set_transition(new TransformTransition(mat));
+
+  if (_has_color) {
+    root_arc->set_transition(new ColorTransition(_color));
+  }
+
+  // Now flatten out the geometry as much as we can.
+  SceneGraphReducer reducer;
+  reducer.apply_transitions(root_arc);
+  reducer.flatten(root, true);
+
+  if (root->get_num_children(RenderRelation::get_class_type()) == 1) {
+    // If we ended up with only one child, and no transitions on the
+    // arc to it, return that child.
+    NodeRelation *arc = root->get_child(RenderRelation::get_class_type(), 0);
+    if (!arc->has_any_transition()) {
+      return arc->get_child();
+    }
+  }
+
+  return root;
+}

+ 14 - 0
panda/src/grutil/cardMaker.h

@@ -42,12 +42,26 @@ PUBLISHED:
   INLINE void set_frame(float left, float right, float bottom, float top);
   INLINE void set_frame(float left, float right, float bottom, float top);
   INLINE void set_frame(const LVecBase4f &frame);
   INLINE void set_frame(const LVecBase4f &frame);
 
 
+  INLINE void set_color(float r, float g, float b, float a);
+  INLINE void set_color(const Colorf &color);
+
+  INLINE void set_source_geometry(Node *node, const LVecBase4f &frame);
+  INLINE void clear_source_geometry();
+
   PT_Node generate();
   PT_Node generate();
 
 
 private:
 private:
+  PT_Node rescale_source_geometry();
+
   bool _has_uvs;
   bool _has_uvs;
   TexCoordf _ll, _ur;
   TexCoordf _ll, _ur;
   LVecBase4f _frame;
   LVecBase4f _frame;
+
+  bool _has_color;
+  Colorf _color;
+
+  PT_Node _source_geometry;
+  LVecBase4f _source_frame;
 };
 };
 
 
 #include "cardMaker.I"
 #include "cardMaker.I"