소스 검색

egg-optchar -defpose

David Rose 17 년 전
부모
커밋
31d75582a3
37개의 변경된 파일1567개의 추가작업 그리고 1249개의 파일을 삭제
  1. 4 4
      panda/src/chan/config_chan.cxx
  2. 9 9
      panda/src/chan/movingPart.I
  3. 5 5
      panda/src/chan/movingPart.h
  4. 1 1
      panda/src/chan/movingPartBase.cxx
  5. 1 1
      panda/src/chan/movingPartBase.h
  6. 2 2
      panda/src/chan/movingPartMatrix.I
  7. 8 8
      panda/src/chan/movingPartMatrix.cxx
  8. 2 3
      panda/src/chan/movingPartMatrix.h
  9. 2 2
      panda/src/chan/movingPartScalar.I
  10. 2 2
      panda/src/chan/movingPartScalar.cxx
  11. 1 1
      panda/src/chan/movingPartScalar.h
  12. 4 2
      panda/src/chan/partBundle.cxx
  13. 2 2
      panda/src/char/characterJoint.cxx
  14. 1 1
      panda/src/char/characterJoint.h
  15. 2 0
      panda/src/char/jointVertexTransform.cxx
  16. 23 2
      panda/src/doc/eggSyntax.txt
  17. 55 0
      panda/src/egg/eggGroup.I
  18. 12 2
      panda/src/egg/eggGroup.cxx
  19. 11 0
      panda/src/egg/eggGroup.h
  20. 1 1
      panda/src/egg/eggTexture.cxx
  21. 2 2
      panda/src/egg/eggTransform.cxx
  22. 3 1
      panda/src/egg/eggTransform.h
  23. 388 388
      panda/src/egg/lexer.cxx.prebuilt
  24. 2 10
      panda/src/egg/lexer.lxx
  25. 739 720
      panda/src/egg/parser.cxx.prebuilt
  26. 61 63
      panda/src/egg/parser.h.prebuilt
  27. 41 15
      panda/src/egg/parser.yxx
  28. 19 2
      panda/src/egg2pg/characterMaker.cxx
  29. 1 0
      panda/src/gobj/transformBlend.cxx
  30. 94 0
      pandatool/src/egg-optchar/eggOptchar.cxx
  31. 3 0
      pandatool/src/egg-optchar/eggOptchar.h
  32. 31 0
      pandatool/src/eggcharbase/eggJointData.cxx
  33. 1 0
      pandatool/src/eggcharbase/eggJointData.h
  34. 21 0
      pandatool/src/eggcharbase/eggJointNodePointer.cxx
  35. 1 0
      pandatool/src/eggcharbase/eggJointNodePointer.h
  36. 11 0
      pandatool/src/eggcharbase/eggJointPointer.cxx
  37. 1 0
      pandatool/src/eggcharbase/eggJointPointer.h

+ 4 - 4
panda/src/chan/config_chan.cxx

@@ -90,10 +90,10 @@ PRC_DESC("Set this true to interpolate character animations between frames, "
 
 
 ConfigVariableBool restore_initial_pose
 ConfigVariableBool restore_initial_pose
 ("restore-initial-pose", true,
 ("restore-initial-pose", true,
-PRC_DESC("When this is true, stopping all animations on an Actor causes it "
-         "to return to its initial, unanimated pose.  When false, it retains "
-         "whatever its last-computed pose was (which may or may not be "
-         "the unanimated pose)."));
+PRC_DESC("When this is true, setting all control effects on an Actor to 0 "
+         "causes it to return to its default, unanimated pose.  When "
+         "false, it retains whatever its last-computed pose was "
+         "(which may or may not be the default pose)."));
 
 
 
 
 ConfigureFn(config_chan) {
 ConfigureFn(config_chan) {

+ 9 - 9
panda/src/chan/movingPart.I

@@ -38,7 +38,7 @@ INLINE MovingPart<SwitchType>::
 MovingPart(const MovingPart<SwitchType> &copy) :
 MovingPart(const MovingPart<SwitchType> &copy) :
   MovingPartBase(copy),
   MovingPartBase(copy),
   _value(copy._value),
   _value(copy._value),
-  _initial_value(copy._initial_value)
+  _default_value(copy._default_value)
 {
 {
 }
 }
 
 
@@ -50,10 +50,10 @@ MovingPart(const MovingPart<SwitchType> &copy) :
 template<class SwitchType>
 template<class SwitchType>
 INLINE MovingPart<SwitchType>::
 INLINE MovingPart<SwitchType>::
 MovingPart(PartGroup *parent, const string &name,
 MovingPart(PartGroup *parent, const string &name,
-           const ValueType &initial_value) :
+           const ValueType &default_value) :
   MovingPartBase(parent, name),
   MovingPartBase(parent, name),
-  _value(initial_value),
-  _initial_value(initial_value)
+  _value(default_value),
+  _default_value(default_value)
 {
 {
 }
 }
 
 
@@ -84,7 +84,7 @@ get_value_type() const {
 
 
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-//     Function: MovingPart::make_initial_channel
+//     Function: MovingPart::make_default_channel
 //       Access: Public, Virtual
 //       Access: Public, Virtual
 //  Description: Creates and returns a new AnimChannel that is not
 //  Description: Creates and returns a new AnimChannel that is not
 //               part of any hierarchy, but that returns the default
 //               part of any hierarchy, but that returns the default
@@ -92,8 +92,8 @@ get_value_type() const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 template<class SwitchType>
 template<class SwitchType>
 AnimChannelBase *MovingPart<SwitchType>::
 AnimChannelBase *MovingPart<SwitchType>::
-make_initial_channel() const {
-  return new AnimChannelFixed<SwitchType>(get_name(), _initial_value);
+make_default_channel() const {
+  return new AnimChannelFixed<SwitchType>(get_name(), _default_value);
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -119,7 +119,7 @@ void MovingPart<SwitchType>::
 write_datagram(BamWriter *manager, Datagram &me) {
 write_datagram(BamWriter *manager, Datagram &me) {
   MovingPartBase::write_datagram(manager, me);
   MovingPartBase::write_datagram(manager, me);
   SwitchType::write_datagram(me, _value);
   SwitchType::write_datagram(me, _value);
-  SwitchType::write_datagram(me, _initial_value);
+  SwitchType::write_datagram(me, _default_value);
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -135,7 +135,7 @@ void MovingPart<SwitchType>::
 fillin(DatagramIterator &scan, BamReader *manager) {
 fillin(DatagramIterator &scan, BamReader *manager) {
   MovingPartBase::fillin(scan, manager);
   MovingPartBase::fillin(scan, manager);
   SwitchType::read_datagram(scan, _value);
   SwitchType::read_datagram(scan, _value);
-  SwitchType::read_datagram(scan, _initial_value);
+  SwitchType::read_datagram(scan, _default_value);
 }
 }
 
 
 
 

+ 5 - 5
panda/src/chan/movingPart.h

@@ -37,14 +37,14 @@ protected:
 
 
 public:
 public:
   INLINE MovingPart(PartGroup *parent, const string &name,
   INLINE MovingPart(PartGroup *parent, const string &name,
-                    const ValueType &_initial_value);
+                    const ValueType &default_value);
 
 
   virtual TypeHandle get_value_type() const;
   virtual TypeHandle get_value_type() const;
-  virtual AnimChannelBase *make_initial_channel() const;
+  virtual AnimChannelBase *make_default_channel() const;
   virtual void output_value(ostream &out) const;
   virtual void output_value(ostream &out) const;
 
 
   ValueType _value;
   ValueType _value;
-  ValueType _initial_value;
+  ValueType _default_value;
 
 
 public:
 public:
   INLINE virtual void write_datagram(BamWriter* manager, Datagram &me);
   INLINE virtual void write_datagram(BamWriter* manager, Datagram &me);
@@ -65,8 +65,8 @@ PUBLISHED:
   INLINE ValueType get_value() const {
   INLINE ValueType get_value() const {
     return _value;
     return _value;
   }
   }
-  INLINE ValueType get_initial_value() const {
-    return _initial_value;
+  INLINE ValueType get_default_value() const {
+    return _default_value;
   }
   }
 public:
 public:
   static void init_type() {
   static void init_type() {

+ 1 - 1
panda/src/chan/movingPartBase.cxx

@@ -282,7 +282,7 @@ bind_hierarchy(AnimGroup *anim, int channel_index, int &joint_index,
       // If we're binding to the NULL anim, it means actually to create
       // If we're binding to the NULL anim, it means actually to create
       // a default AnimChannel that just returns the part's initial
       // a default AnimChannel that just returns the part's initial
       // value.
       // value.
-      _channels[channel_index] = make_initial_channel();
+      _channels[channel_index] = make_default_channel();
     } else {
     } else {
       _channels[channel_index] = DCAST(AnimChannelBase, anim);
       _channels[channel_index] = DCAST(AnimChannelBase, anim);
     }
     }

+ 1 - 1
panda/src/chan/movingPartBase.h

@@ -44,7 +44,7 @@ PUBLISHED:
 
 
 public:
 public:
   virtual TypeHandle get_value_type() const=0;
   virtual TypeHandle get_value_type() const=0;
-  virtual AnimChannelBase *make_initial_channel() const=0;
+  virtual AnimChannelBase *make_default_channel() const=0;
 
 
 PUBLISHED:
 PUBLISHED:
   virtual bool clear_forced_channel();
   virtual bool clear_forced_channel();

+ 2 - 2
panda/src/chan/movingPartMatrix.I

@@ -32,8 +32,8 @@ MovingPartMatrix(const MovingPartMatrix &copy) :
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE MovingPartMatrix::
 INLINE MovingPartMatrix::
 MovingPartMatrix(PartGroup *parent, const string &name,
 MovingPartMatrix(PartGroup *parent, const string &name,
-                 const LMatrix4f &initial_value)
-  : MovingPart<ACMatrixSwitchType>(parent, name, initial_value) {
+                 const LMatrix4f &default_value)
+  : MovingPart<ACMatrixSwitchType>(parent, name, default_value) {
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////

+ 8 - 8
panda/src/chan/movingPartMatrix.cxx

@@ -40,16 +40,16 @@ MovingPartMatrix::
 
 
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-//     Function: MovingPartMatrix::make_initial_channel
+//     Function: MovingPartMatrix::make_default_channel
 //       Access: Public, Virtual
 //       Access: Public, Virtual
 //  Description: Creates and returns a new AnimChannel that is not
 //  Description: Creates and returns a new AnimChannel that is not
 //               part of any hierarchy, but that returns the default
 //               part of any hierarchy, but that returns the default
 //               value associated with this part.
 //               value associated with this part.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 AnimChannelBase *MovingPartMatrix::
 AnimChannelBase *MovingPartMatrix::
-make_initial_channel() const {
+make_default_channel() const {
   LVecBase3f pos, hpr, scale, shear;
   LVecBase3f pos, hpr, scale, shear;
-  decompose_matrix(_initial_value, pos, hpr, scale, shear);
+  decompose_matrix(_default_value, pos, hpr, scale, shear);
   return new AnimChannelMatrixFixed(get_name(), pos, hpr, scale);
   return new AnimChannelMatrixFixed(get_name(), pos, hpr, scale);
 }
 }
 
 
@@ -76,7 +76,7 @@ get_blend_value(const PartBundle *root) {
   if (cdata->_blend.empty()) {
   if (cdata->_blend.empty()) {
     // No channel is bound; supply the default value.
     // No channel is bound; supply the default value.
     if (restore_initial_pose) {
     if (restore_initial_pose) {
-      _value = _initial_value;
+      _value = _default_value;
     }
     }
 
 
   } else if (_effective_control != (AnimControl *)NULL && 
   } else if (_effective_control != (AnimControl *)NULL && 
@@ -126,7 +126,7 @@ get_blend_value(const PartBundle *root) {
         
         
         if (net_effect == 0.0f) {
         if (net_effect == 0.0f) {
           if (restore_initial_pose) {
           if (restore_initial_pose) {
-            _value = _initial_value;
+            _value = _default_value;
           }
           }
         } else {
         } else {
           _value = net_value / net_effect;
           _value = net_value / net_effect;
@@ -194,7 +194,7 @@ get_blend_value(const PartBundle *root) {
         
         
         if (net_effect == 0.0f) {
         if (net_effect == 0.0f) {
           if (restore_initial_pose) {
           if (restore_initial_pose) {
-            _value = _initial_value;
+            _value = _default_value;
           }
           }
 
 
         } else {
         } else {
@@ -273,7 +273,7 @@ get_blend_value(const PartBundle *root) {
         
         
         if (net_effect == 0.0f) {
         if (net_effect == 0.0f) {
           if (restore_initial_pose) {
           if (restore_initial_pose) {
-            _value = _initial_value;
+            _value = _default_value;
           }
           }
 
 
         } else {
         } else {
@@ -352,7 +352,7 @@ get_blend_value(const PartBundle *root) {
         
         
         if (net_effect == 0.0f) {
         if (net_effect == 0.0f) {
           if (restore_initial_pose) {
           if (restore_initial_pose) {
-            _value = _initial_value;
+            _value = _default_value;
           }
           }
 
 
         } else {
         } else {

+ 2 - 3
panda/src/chan/movingPartMatrix.h

@@ -35,11 +35,10 @@ protected:
 
 
 public:
 public:
   INLINE MovingPartMatrix(PartGroup *parent, const string &name,
   INLINE MovingPartMatrix(PartGroup *parent, const string &name,
-                          const LMatrix4f &initial_value =
-                          LMatrix4f::ident_mat());
+                          const LMatrix4f &default_value);
   virtual ~MovingPartMatrix();
   virtual ~MovingPartMatrix();
 
 
-  virtual AnimChannelBase *make_initial_channel() const;
+  virtual AnimChannelBase *make_default_channel() const;
   virtual void get_blend_value(const PartBundle *root);
   virtual void get_blend_value(const PartBundle *root);
 
 
   virtual bool apply_freeze_matrix(const LVecBase3f &pos, const LVecBase3f &hpr, const LVecBase3f &scale);
   virtual bool apply_freeze_matrix(const LVecBase3f &pos, const LVecBase3f &hpr, const LVecBase3f &scale);

+ 2 - 2
panda/src/chan/movingPartScalar.I

@@ -32,8 +32,8 @@ MovingPartScalar(const MovingPartScalar &copy) :
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE MovingPartScalar::
 INLINE MovingPartScalar::
 MovingPartScalar(PartGroup *parent, const string &name,
 MovingPartScalar(PartGroup *parent, const string &name,
-                 const float &initial_value)
-  : MovingPart<ACScalarSwitchType>(parent, name, initial_value) {
+                 const float &default_value)
+  : MovingPart<ACScalarSwitchType>(parent, name, default_value) {
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////

+ 2 - 2
panda/src/chan/movingPartScalar.cxx

@@ -59,7 +59,7 @@ get_blend_value(const PartBundle *root) {
   if (cdata->_blend.empty()) {
   if (cdata->_blend.empty()) {
     // No channel is bound; supply the default value.
     // No channel is bound; supply the default value.
     if (restore_initial_pose) {
     if (restore_initial_pose) {
-      _value = _initial_value;
+      _value = _default_value;
     }
     }
 
 
   } else if (_effective_control != (AnimControl *)NULL &&
   } else if (_effective_control != (AnimControl *)NULL &&
@@ -105,7 +105,7 @@ get_blend_value(const PartBundle *root) {
 
 
     if (net == 0.0f) {
     if (net == 0.0f) {
       if (restore_initial_pose) {
       if (restore_initial_pose) {
-        _value = _initial_value;
+        _value = _default_value;
       }
       }
 
 
     } else {
     } else {

+ 1 - 1
panda/src/chan/movingPartScalar.h

@@ -34,7 +34,7 @@ protected:
 
 
 public:
 public:
   INLINE MovingPartScalar(PartGroup *parent, const string &name,
   INLINE MovingPartScalar(PartGroup *parent, const string &name,
-                          const float &initial_value = 0);
+                          const float &default_value = 0);
   virtual ~MovingPartScalar();
   virtual ~MovingPartScalar();
 
 
   virtual void get_blend_value(const PartBundle *root);
   virtual void get_blend_value(const PartBundle *root);

+ 4 - 2
panda/src/chan/partBundle.cxx

@@ -198,8 +198,8 @@ apply_transform(const TransformState *transform) {
 //  Description: Sets the control effect of all AnimControls to zero
 //  Description: Sets the control effect of all AnimControls to zero
 //               (but does not "stop" the AnimControls).  The
 //               (but does not "stop" the AnimControls).  The
 //               character will no longer be affected by any
 //               character will no longer be affected by any
-//               animation, and will return to its original Jesus
-//               pose.
+//               animation, and will return to its default
+//               pose (unless restore-initial-pose is false).
 //
 //
 //               The AnimControls which are no longer associated will
 //               The AnimControls which are no longer associated will
 //               not be using any CPU cycles, but they may still be in
 //               not be using any CPU cycles, but they may still be in
@@ -217,6 +217,7 @@ clear_control_effects() {
     cdataw->_blend.clear();
     cdataw->_blend.clear();
     cdataw->_net_blend = 0.0f;
     cdataw->_net_blend = 0.0f;
     cdataw->_anim_changed = true;
     cdataw->_anim_changed = true;
+    determine_effective_channels(cdata);
   }
   }
 }
 }
 
 
@@ -806,6 +807,7 @@ clear_and_stop_intersecting(AnimControl *control, CData *cdata) {
     cdata->_net_blend = new_net_blend;
     cdata->_net_blend = new_net_blend;
     cdata->_blend.swap(new_blend);
     cdata->_blend.swap(new_blend);
     cdata->_anim_changed = true;
     cdata->_anim_changed = true;
+    determine_effective_channels(cdata);
   }
   }
 }
 }
 
 

+ 2 - 2
panda/src/char/characterJoint.cxx

@@ -57,8 +57,8 @@ CharacterJoint(const CharacterJoint &copy) :
 CharacterJoint::
 CharacterJoint::
 CharacterJoint(Character *character,
 CharacterJoint(Character *character,
                PartBundle *root, PartGroup *parent, const string &name,
                PartBundle *root, PartGroup *parent, const string &name,
-               const LMatrix4f &initial_value) :
-  MovingPartMatrix(parent, name, initial_value),
+               const LMatrix4f &default_value) :
+  MovingPartMatrix(parent, name, default_value),
   _character(character)
   _character(character)
 {
 {
   Thread *current_thread = Thread::get_current_thread();
   Thread *current_thread = Thread::get_current_thread();

+ 1 - 1
panda/src/char/characterJoint.h

@@ -38,7 +38,7 @@ protected:
 PUBLISHED:
 PUBLISHED:
   CharacterJoint(Character *character,
   CharacterJoint(Character *character,
                  PartBundle *root, PartGroup *parent, const string &name,
                  PartBundle *root, PartGroup *parent, const string &name,
-                 const LMatrix4f &initial_value);
+                 const LMatrix4f &default_value);
   virtual ~CharacterJoint();
   virtual ~CharacterJoint();
 
 
 public:
 public:

+ 2 - 0
panda/src/char/jointVertexTransform.cxx

@@ -47,6 +47,7 @@ JointVertexTransform(CharacterJoint *joint) :
 {
 {
   // Tell the joint that we need to be informed when it moves.
   // Tell the joint that we need to be informed when it moves.
   _joint->_vertex_transforms.insert(this);
   _joint->_vertex_transforms.insert(this);
+  mark_modified(Thread::get_current_thread());
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -219,4 +220,5 @@ fillin(DatagramIterator &scan, BamReader *manager) {
 
 
   manager->read_pointer(scan);
   manager->read_pointer(scan);
   _matrix_stale = true;
   _matrix_stale = true;
+  mark_modified(Thread::get_current_thread());
 }
 }

+ 23 - 2
panda/src/doc/eggSyntax.txt

@@ -1508,6 +1508,26 @@ GROUPING ENTRIES
     may define either a 2-d or a 3-d transform when it appears within
     may define either a 2-d or a 3-d transform when it appears within
     the body of a <Texture>.  See <Texture>, above.
     the body of a <Texture>.  See <Texture>, above.
 
 
+  <DefaultPose> { transform-definition }
+
+    This defines an optional default pose transform, which might be a
+    different transform from that defined by the <Transform> entry,
+    above.  This makes sense only for a <Joint>.  See the <Joint>
+    description, below.
+
+    The default pose transform defines the transform the joint will
+    maintain in the absence of any animation being applied.  This is
+    different from the <Transform> entry, which defines the coordinate
+    space the joint must have in order to keep its vertices in their
+    (global space) position as given in the egg file.  If this is
+    different from the <Transform> entry, the joint's vertices will
+    *not* be in their egg file position at initial load.  If there is
+    no <DefaultPose> entry for a particular joint, the implicit
+    default-pose transform is the same as the <Transform> entry.
+
+    Normally, the <DefaultPose> entry, if any, is created by the
+    egg-optchar -defpose option.  Most other software has little
+    reason to specify an explicit <DefaultPose>.
 
 
   <VertexRef> { indices <Ref> { pool-name } }
   <VertexRef> { indices <Ref> { pool-name } }
 
 
@@ -1768,8 +1788,9 @@ ANIMATION STRUCTURE
 
 
   It is not necessary for every joint to have vertices at all.  Every
   It is not necessary for every joint to have vertices at all.  Every
   joint should include a transform entry, however, which defines the
   joint should include a transform entry, however, which defines the
-  initial, resting transform of the joint.  If a transform is omitted,
-  the identity transform is assumed.
+  initial, resting transform of the joint (but see also <DefaultPose>,
+  above).  If a transform is omitted, the identity transform is
+  assumed.
 
 
   Some of the vertex definitions may include morph entries, as
   Some of the vertex definitions may include morph entries, as
   described in MORPH DESCRIPTION ENTRIES, above.  These are meaningful
   described in MORPH DESCRIPTION ENTRIES, above.  These are meaningful

+ 55 - 0
panda/src/egg/eggGroup.I

@@ -904,6 +904,61 @@ clear_tag(const string &key) {
   _tag_data.erase(key);
   _tag_data.erase(key);
 }
 }
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: EggGroup::get_default_pose
+//       Access: Published
+//  Description: Returns a read-only accessor to the initial pose
+//               transform.  This is the <DefaultPose> entry for a
+//               Joint, and defines only the initial transform pose
+//               for the unanimated joint; it has nothing to do with
+//               the group's <Transform> entry, which defines the
+//               (eventual) space of the group's vertices.
+////////////////////////////////////////////////////////////////////
+INLINE const EggTransform &EggGroup::
+get_default_pose() const {
+  return _default_pose;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: EggGroup::modify_default_pose
+//       Access: Published
+//  Description: Returns a writable accessor to the initial pose
+//               transform.  This is the <DefaultPose> entry for a
+//               Joint, and defines only the initial transform pose
+//               for the unanimated joint; it has nothing to do with
+//               the group's <Transform> entry, which defines the
+//               (eventual) space of the group's vertices.
+////////////////////////////////////////////////////////////////////
+INLINE EggTransform &EggGroup::
+modify_default_pose() {
+  return _default_pose;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: EggGroup::set_default_pose
+//       Access: Published
+//  Description: Replaces the initial pose transform.  This is the
+//               <DefaultPose> entry for a Joint, and defines only the
+//               initial transform pose for the unanimated joint; it
+//               has nothing to do with the group's <Transform> entry,
+//               which defines the (eventual) space of the group's
+//               vertices.
+////////////////////////////////////////////////////////////////////
+INLINE void EggGroup::
+set_default_pose(const EggTransform &transform) {
+  _default_pose = transform;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: EggGroup::clear_default_pose
+//       Access: Published
+//  Description: Removes the initial pose transform.  See
+//               set_default_pose().
+////////////////////////////////////////////////////////////////////
+INLINE void EggGroup::
+clear_default_pose() {
+  _default_pose.clear_transform();
+}
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: EggGroup::tag_begin
 //     Function: EggGroup::tag_begin

+ 12 - 2
panda/src/egg/eggGroup.cxx

@@ -74,8 +74,8 @@ operator = (const EggGroup &copy) {
   _blend_operand_a = copy._blend_operand_a;
   _blend_operand_a = copy._blend_operand_a;
   _blend_operand_b = copy._blend_operand_b;
   _blend_operand_b = copy._blend_operand_b;
   _blend_color = copy._blend_color;
   _blend_color = copy._blend_color;
-
   _tag_data = copy._tag_data;
   _tag_data = copy._tag_data;
+  _default_pose = copy._default_pose;
 
 
   unref_all_vertices();
   unref_all_vertices();
   _vref = copy._vref;
   _vref = copy._vref;
@@ -219,7 +219,11 @@ write(ostream &out, int indent_level) const {
   write_switch_flags(out, indent_level + 2);
   write_switch_flags(out, indent_level + 2);
 
 
   if (has_transform()) {
   if (has_transform()) {
-    EggTransform::write(out, indent_level + 2);
+    EggTransform::write(out, indent_level + 2, "<Transform>");
+  }
+
+  if (get_group_type() == GT_joint && _default_pose.has_transform()) {
+    _default_pose.write(out, indent_level + 2, "<DefaultPose>");
   }
   }
 
 
   write_object_types(out, indent_level + 2);
   write_object_types(out, indent_level + 2);
@@ -1251,6 +1255,12 @@ r_transform(const LMatrix4d &mat, const LMatrix4d &inv,
 
 
     internal_set_transform(inv1 * get_transform3d() * mat);
     internal_set_transform(inv1 * get_transform3d() * mat);
 
 
+    if (_default_pose.has_transform()) {
+      LMatrix4d t = _default_pose.get_transform3d();
+      _default_pose.clear_transform();
+      _default_pose.add_matrix4(inv1 * t * mat);
+    }
+
     EggGroupNode::r_transform(mat1, inv1, to_cs);
     EggGroupNode::r_transform(mat1, inv1, to_cs);
   } else {
   } else {
     EggGroupNode::r_transform(mat, inv, to_cs);
     EggGroupNode::r_transform(mat, inv, to_cs);

+ 11 - 0
panda/src/egg/eggGroup.h

@@ -262,6 +262,11 @@ PUBLISHED:
   INLINE bool has_tag(const string &key) const;
   INLINE bool has_tag(const string &key) const;
   INLINE void clear_tag(const string &key);
   INLINE void clear_tag(const string &key);
 
 
+  INLINE const EggTransform &get_default_pose() const;
+  INLINE EggTransform &modify_default_pose();
+  INLINE void set_default_pose(const EggTransform &transform);
+  INLINE void clear_default_pose();
+
 public:
 public:
   INLINE TagData::const_iterator tag_begin() const;
   INLINE TagData::const_iterator tag_begin() const;
   INLINE TagData::const_iterator tag_end() const;
   INLINE TagData::const_iterator tag_end() const;
@@ -360,6 +365,12 @@ private:
   double _fps;
   double _fps;
   PT(EggSwitchCondition) _lod;
   PT(EggSwitchCondition) _lod;
   TagData _tag_data;
   TagData _tag_data;
+
+  // This is the <DefaultPose> entry for a <Joint>.  It is not the
+  // <Transform> entry (that is stored via inheritance, in the
+  // EggTransform class we inherit from).
+  EggTransform _default_pose;
+
   VertexRef _vref;
   VertexRef _vref;
 
 
   typedef pvector< PT(EggGroup) > GroupRefs;
   typedef pvector< PT(EggGroup) > GroupRefs;

+ 1 - 1
panda/src/egg/eggTexture.cxx

@@ -290,7 +290,7 @@ write(ostream &out, int indent_level) const {
   EggRenderMode::write(out, indent_level + 2);
   EggRenderMode::write(out, indent_level + 2);
 
 
   if (has_transform()) {
   if (has_transform()) {
-    EggTransform::write(out, indent_level + 2);
+    EggTransform::write(out, indent_level + 2, "<Transform>");
   }
   }
 
 
   indent(out, indent_level) << "}\n";
   indent(out, indent_level) << "}\n";

+ 2 - 2
panda/src/egg/eggTransform.cxx

@@ -230,8 +230,8 @@ add_uniform_scale(double scale) {
 //               format.
 //               format.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void EggTransform::
 void EggTransform::
-write(ostream &out, int indent_level) const {
-  indent(out, indent_level) << "<Transform> {\n";
+write(ostream &out, int indent_level, const string &label) const {
+  indent(out, indent_level) << label << " {\n";
 
 
   int num_components = get_num_components();
   int num_components = get_num_components();
   for (int i = 0; i < num_components; i++) {
   for (int i = 0; i < num_components; i++) {

+ 3 - 1
panda/src/egg/eggTransform.h

@@ -17,6 +17,7 @@
 
 
 #include "pandabase.h"
 #include "pandabase.h"
 #include "luse.h"
 #include "luse.h"
+#include "eggObject.h"
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //       Class : EggTransform
 //       Class : EggTransform
@@ -85,7 +86,8 @@ PUBLISHED:
   INLINE const LMatrix3d &get_component_mat3(int n) const;
   INLINE const LMatrix3d &get_component_mat3(int n) const;
   INLINE const LMatrix4d &get_component_mat4(int n) const;
   INLINE const LMatrix4d &get_component_mat4(int n) const;
 
 
-  void write(ostream &out, int indent_level) const;
+  void write(ostream &out, int indent_level,
+             const string &label) const;
 
 
 protected:
 protected:
   void internal_clear_transform();
   void internal_clear_transform();

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 388 - 388
panda/src/egg/lexer.cxx.prebuilt


+ 2 - 10
panda/src/egg/lexer.lxx

@@ -435,21 +435,13 @@ NUMERIC         ([+-]?(([0-9]+[.]?)|([0-9]*[.][0-9]+))([eE][+-]?[0-9]+)?)
   accept();
   accept();
   return EXTERNAL_FILE;
   return EXTERNAL_FILE;
 }
 }
-"<FLT_HEADER>" {
-  accept();
-  return FLIGHT;
-}
 "<GROUP>" {
 "<GROUP>" {
   accept();
   accept();
   return GROUP;
   return GROUP;
 }
 }
-"<HIP>" {
-  accept();
-  return HIP;
-}
-"<IN>" {
+"<DEFAULTPOSE>" {
   accept();
   accept();
-  return INTANGENT;
+  return DEFAULTPOSE;
 }
 }
 "<JOINT>" {
 "<JOINT>" {
   accept();
   accept();

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 739 - 720
panda/src/egg/parser.cxx.prebuilt


+ 61 - 63
panda/src/egg/parser.h.prebuilt

@@ -24,69 +24,67 @@
 #define	DTREF	280
 #define	DTREF	280
 #define	DYNAMICVERTEXPOOL	281
 #define	DYNAMICVERTEXPOOL	281
 #define	EXTERNAL_FILE	282
 #define	EXTERNAL_FILE	282
-#define	FLIGHT	283
-#define	GROUP	284
-#define	HIP	285
-#define	INTANGENT	286
-#define	JOINT	287
-#define	KNOTS	288
-#define	INCLUDE	289
-#define	INSTANCE	290
-#define	LINE	291
-#define	LOOP	292
-#define	MATERIAL	293
-#define	MATRIX3	294
-#define	MATRIX4	295
-#define	MODEL	296
-#define	MREF	297
-#define	NORMAL	298
-#define	NURBSCURVE	299
-#define	NURBSSURFACE	300
-#define	OBJECTTYPE	301
-#define	ORDER	302
-#define	OUTTANGENT	303
-#define	POINTLIGHT	304
-#define	POLYGON	305
-#define	REF	306
-#define	RGBA	307
-#define	ROTATE	308
-#define	ROTX	309
-#define	ROTY	310
-#define	ROTZ	311
-#define	SANIM	312
-#define	SCALAR	313
-#define	SCALE	314
-#define	SEQUENCE	315
-#define	SHADING	316
-#define	SWITCH	317
-#define	SWITCHCONDITION	318
-#define	TABLE	319
-#define	TABLE_V	320
-#define	TAG	321
-#define	TANGENT	322
-#define	TEXLIST	323
-#define	TEXTURE	324
-#define	TLENGTHS	325
-#define	TRANSFORM	326
-#define	TRANSLATE	327
-#define	TREF	328
-#define	TRIANGLEFAN	329
-#define	TRIANGLESTRIP	330
-#define	TRIM	331
-#define	TXT	332
-#define	UKNOTS	333
-#define	UV	334
-#define	VKNOTS	335
-#define	VERTEX	336
-#define	VERTEXANIM	337
-#define	VERTEXPOOL	338
-#define	VERTEXREF	339
-#define	XFMANIM	340
-#define	XFMSANIM	341
-#define	START_EGG	342
-#define	START_GROUP_BODY	343
-#define	START_TEXTURE_BODY	344
-#define	START_PRIMITIVE_BODY	345
+#define	GROUP	283
+#define	DEFAULTPOSE	284
+#define	JOINT	285
+#define	KNOTS	286
+#define	INCLUDE	287
+#define	INSTANCE	288
+#define	LINE	289
+#define	LOOP	290
+#define	MATERIAL	291
+#define	MATRIX3	292
+#define	MATRIX4	293
+#define	MODEL	294
+#define	MREF	295
+#define	NORMAL	296
+#define	NURBSCURVE	297
+#define	NURBSSURFACE	298
+#define	OBJECTTYPE	299
+#define	ORDER	300
+#define	OUTTANGENT	301
+#define	POINTLIGHT	302
+#define	POLYGON	303
+#define	REF	304
+#define	RGBA	305
+#define	ROTATE	306
+#define	ROTX	307
+#define	ROTY	308
+#define	ROTZ	309
+#define	SANIM	310
+#define	SCALAR	311
+#define	SCALE	312
+#define	SEQUENCE	313
+#define	SHADING	314
+#define	SWITCH	315
+#define	SWITCHCONDITION	316
+#define	TABLE	317
+#define	TABLE_V	318
+#define	TAG	319
+#define	TANGENT	320
+#define	TEXLIST	321
+#define	TEXTURE	322
+#define	TLENGTHS	323
+#define	TRANSFORM	324
+#define	TRANSLATE	325
+#define	TREF	326
+#define	TRIANGLEFAN	327
+#define	TRIANGLESTRIP	328
+#define	TRIM	329
+#define	TXT	330
+#define	UKNOTS	331
+#define	UV	332
+#define	VKNOTS	333
+#define	VERTEX	334
+#define	VERTEXANIM	335
+#define	VERTEXPOOL	336
+#define	VERTEXREF	337
+#define	XFMANIM	338
+#define	XFMSANIM	339
+#define	START_EGG	340
+#define	START_GROUP_BODY	341
+#define	START_TEXTURE_BODY	342
+#define	START_PRIMITIVE_BODY	343
 
 
 
 
 extern YYSTYPE eggyylval;
 extern YYSTYPE eggyylval;

+ 41 - 15
panda/src/egg/parser.yxx

@@ -33,6 +33,7 @@
 #include "eggExternalReference.h"
 #include "eggExternalReference.h"
 #include "eggData.h"
 #include "eggData.h"
 #include "eggAnimPreload.h"
 #include "eggAnimPreload.h"
+#include "eggTransform.h"
 #include "pt_EggTexture.h"
 #include "pt_EggTexture.h"
 #include "pt_EggMaterial.h"
 #include "pt_EggMaterial.h"
 
 
@@ -61,6 +62,9 @@
 typedef pvector< PT(EggObject) > EggStack;
 typedef pvector< PT(EggObject) > EggStack;
 static EggStack egg_stack;
 static EggStack egg_stack;
 
 
+// This is used just when parsing a <Transform> or <DefaultPose> entry.
+static EggTransform *egg_top_transform;
+
 // There's one "top-level" egg node, which is where we should parent
 // There's one "top-level" egg node, which is where we should parent
 // things (e.g. implicit textures) encountered in the egg file that
 // things (e.g. implicit textures) encountered in the egg file that
 // don't have an explicit place in the tree.  If this is NULL, such
 // don't have an explicit place in the tree.  If this is NULL, such
@@ -160,7 +164,7 @@ egg_cleanup_parser() {
 %token COORDSYSTEM CV DART
 %token COORDSYSTEM CV DART
 %token DNORMAL DRGBA DUV DXYZ DCS DISTANCE DTREF
 %token DNORMAL DRGBA DUV DXYZ DCS DISTANCE DTREF
 %token DYNAMICVERTEXPOOL EXTERNAL_FILE
 %token DYNAMICVERTEXPOOL EXTERNAL_FILE
-%token FLIGHT GROUP HIP INTANGENT
+%token GROUP DEFAULTPOSE 
 %token JOINT KNOTS INCLUDE
 %token JOINT KNOTS INCLUDE
 %token INSTANCE LINE LOOP MATERIAL MATRIX3 MATRIX4 MODEL MREF NORMAL
 %token INSTANCE LINE LOOP MATERIAL MATRIX3 MATRIX4 MODEL MREF NORMAL
 %token NURBSCURVE NURBSSURFACE OBJECTTYPE ORDER
 %token NURBSCURVE NURBSSURFACE OBJECTTYPE ORDER
@@ -1432,6 +1436,7 @@ group_body:
   group->set_texlist_flag(value!=0);
   group->set_texlist_flag(value!=0);
 }
 }
         | group_body transform
         | group_body transform
+        | group_body default_pose
         | group_body group_vertex_ref
         | group_body group_vertex_ref
         | group_body switchcondition
         | group_body switchcondition
         | group_body REF '{' group_name '}'
         | group_body REF '{' group_name '}'
@@ -1512,7 +1517,28 @@ collide_flags:
 transform:
 transform:
         TRANSFORM
         TRANSFORM
 {
 {
-  egg_stack.back()->as_transform()->clear_transform();
+  egg_top_transform = egg_stack.back()->as_transform();
+  egg_top_transform->clear_transform();
+}
+        '{' transform_body '}'
+        ;
+
+/*
+ * default_pose
+ *
+ * enter: TOS is an EggGroup
+ * exit: default_pose matrix has been set.
+ *
+ */
+default_pose:
+        DEFAULTPOSE
+{
+  EggGroup *group = DCAST(EggGroup, egg_stack.back());
+  if (group->get_group_type() != EggGroup::GT_joint) {
+    eggyywarning("Unexpected <DefaultPose> outside of <Joint>");
+  }
+  egg_top_transform = &group->modify_default_pose();
+  egg_top_transform->clear_transform();
 }
 }
         '{' transform_body '}'
         '{' transform_body '}'
         ;
         ;
@@ -1521,7 +1547,7 @@ transform:
 /*
 /*
  * transform_body
  * transform_body
  *
  *
- * enter: TOS is some kind of EggTransform.
+ * enter: egg_top_transform has been assigned.
  * exit: transform has been filled in.
  * exit: transform has been filled in.
  *
  *
  */
  */
@@ -1544,70 +1570,70 @@ transform_body:
 translate2d:
 translate2d:
         TRANSLATE '{' real real '}'
         TRANSLATE '{' real real '}'
 {
 {
-  egg_stack.back()->as_transform()->add_translate2d(LVector2d($3, $4));
+  egg_top_transform->add_translate2d(LVector2d($3, $4));
 }
 }
         ;
         ;
 
 
 translate3d:
 translate3d:
         TRANSLATE '{' real real real '}'
         TRANSLATE '{' real real real '}'
 {
 {
-  egg_stack.back()->as_transform()->add_translate3d(LVector3d($3, $4, $5));
+  egg_top_transform->add_translate3d(LVector3d($3, $4, $5));
 }
 }
         ;
         ;
 
 
 rotate2d:
 rotate2d:
         ROTATE '{' real '}'
         ROTATE '{' real '}'
 {
 {
-  egg_stack.back()->as_transform()->add_rotate2d($3);
+  egg_top_transform->add_rotate2d($3);
 }
 }
         ;
         ;
 
 
 rotx:
 rotx:
         ROTX '{' real '}'
         ROTX '{' real '}'
 {
 {
-  egg_stack.back()->as_transform()->add_rotx($3);
+  egg_top_transform->add_rotx($3);
 }
 }
         ;
         ;
 
 
 roty:
 roty:
         ROTY '{' real '}'
         ROTY '{' real '}'
 {
 {
-  egg_stack.back()->as_transform()->add_roty($3);
+  egg_top_transform->add_roty($3);
 }
 }
         ;
         ;
 
 
 rotz:
 rotz:
         ROTZ '{' real '}'
         ROTZ '{' real '}'
 {
 {
-  egg_stack.back()->as_transform()->add_rotz($3);
+  egg_top_transform->add_rotz($3);
 }
 }
         ;
         ;
 
 
 rotate3d:
 rotate3d:
         ROTATE '{' real real real real '}'
         ROTATE '{' real real real real '}'
 {
 {
-  egg_stack.back()->as_transform()->add_rotate3d($3, LVector3d($4, $5, $6));
+  egg_top_transform->add_rotate3d($3, LVector3d($4, $5, $6));
 }
 }
         ;
         ;
 
 
 scale2d:
 scale2d:
         SCALE '{' real real '}'
         SCALE '{' real real '}'
 {
 {
-  egg_stack.back()->as_transform()->add_scale2d(LVecBase2d($3, $4));
+  egg_top_transform->add_scale2d(LVecBase2d($3, $4));
 }
 }
         ;
         ;
 
 
 scale3d:
 scale3d:
         SCALE '{' real real real '}'
         SCALE '{' real real real '}'
 {
 {
-  egg_stack.back()->as_transform()->add_scale3d(LVecBase3d($3, $4, $5));
+  egg_top_transform->add_scale3d(LVecBase3d($3, $4, $5));
 }
 }
         ;
         ;
 
 
 uniform_scale:
 uniform_scale:
         SCALE '{' real '}'
         SCALE '{' real '}'
 {
 {
-  egg_stack.back()->as_transform()->add_uniform_scale($3);
+  egg_top_transform->add_uniform_scale($3);
 }
 }
         ;
         ;
 
 
@@ -1621,7 +1647,7 @@ matrix3_body:
           real real real
           real real real
           real real real
           real real real
 {
 {
-  egg_stack.back()->as_transform()->add_matrix3
+  egg_top_transform->add_matrix3
     (LMatrix3d($1, $2, $3,
     (LMatrix3d($1, $2, $3,
                $4, $5, $6,
                $4, $5, $6,
                $7, $8, $9));
                $7, $8, $9));
@@ -1639,7 +1665,7 @@ matrix4_body:
           real real real real 
           real real real real 
           real real real real 
           real real real real 
 {
 {
-  egg_stack.back()->as_transform()->add_matrix4
+  egg_top_transform->add_matrix4
     (LMatrix4d($1, $2, $3, $4,
     (LMatrix4d($1, $2, $3, $4,
                $5, $6, $7, $8,
                $5, $6, $7, $8,
                $9, $10, $11, $12,
                $9, $10, $11, $12,

+ 19 - 2
panda/src/egg2pg/characterMaker.cxx

@@ -224,17 +224,21 @@ egg_to_slider(const string &name) {
 CharacterJointBundle *CharacterMaker::
 CharacterJointBundle *CharacterMaker::
 make_bundle() {
 make_bundle() {
   build_joint_hierarchy(_egg_root, _skeleton_root, -1);
   build_joint_hierarchy(_egg_root, _skeleton_root, -1);
-
   make_geometry(_egg_root);
   make_geometry(_egg_root);
 
 
   _bundle->sort_descendants();
   _bundle->sort_descendants();
   parent_joint_nodes(_skeleton_root);
   parent_joint_nodes(_skeleton_root);
 
 
+  // Now call update() one more time, to ensure that all of the joints
+  // have their correct transform (since we might have modified the
+  // default transform after construction).
+  _bundle->force_update();
+
   return _bundle;
   return _bundle;
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-//     Function: CharacterMaker::build_hierarchy
+//     Function: CharacterMaker::build_joint_hierarchy
 //       Access: Private
 //       Access: Private
 //  Description:
 //  Description:
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -271,6 +275,9 @@ build_joint_hierarchy(EggNode *egg_node, PartGroup *part, int index) {
       // We need to get the transform of the joint, and then convert
       // We need to get the transform of the joint, and then convert
       // it to single-precision.
       // it to single-precision.
       LMatrix4d matd;
       LMatrix4d matd;
+
+      // First, we get the original, initial transform from the
+      // <Transform> entry.
       if (egg_group->has_transform()) {
       if (egg_group->has_transform()) {
         matd = egg_group->get_transform3d();
         matd = egg_group->get_transform3d();
       } else {
       } else {
@@ -285,6 +292,16 @@ build_joint_hierarchy(EggNode *egg_node, PartGroup *part, int index) {
       index = _parts.size();
       index = _parts.size();
       _parts.push_back(joint);
       _parts.push_back(joint);
 
 
+      // Now that we have computed _net_transform (which we need to
+      // convert the vertices), update the default transform from the
+      // <DefaultPose> entry.
+      if (egg_group->get_default_pose().has_transform()) {
+        matd = egg_group->get_default_pose().get_transform3d();
+        matf = LCAST(float, matd);
+        joint->_default_value = matf;
+        joint->_value = matf;
+      }
+
       if (egg_group->has_dcs_type()) {
       if (egg_group->has_dcs_type()) {
         // If the joint requested an explicit DCS, create a node for
         // If the joint requested an explicit DCS, create a node for
         // it.
         // it.

+ 1 - 0
panda/src/gobj/transformBlend.cxx

@@ -189,6 +189,7 @@ write(ostream &out, int indent_level) const {
     mat.write(out, indent_level + 4);
     mat.write(out, indent_level + 4);
   }
   }
   LMatrix4f blend;
   LMatrix4f blend;
+  update_blend(current_thread);
   get_blend(blend, current_thread);
   get_blend(blend, current_thread);
   indent(out, indent_level)
   indent(out, indent_level)
     << "Blended result =\n";
     << "Blended result =\n";

+ 94 - 0
pandatool/src/egg-optchar/eggOptchar.cxx

@@ -112,6 +112,16 @@ EggOptchar() {
      "objects parented to this node will not inherit its animation.",
      "objects parented to this node will not inherit its animation.",
      &EggOptchar::dispatch_flag_groups, NULL, &_flag_groups);
      &EggOptchar::dispatch_flag_groups, NULL, &_flag_groups);
 
 
+  add_option
+    ("defpose", "anim.egg,frame", 0,
+     "Specify the model's default pose.  The pose is taken "
+     "from the indicated frame of the named animation file (which must "
+     "also be named separately on the command line).  The "
+     "pose will be held by the model in "
+     "the absence of any animation, and need not be the same "
+     "pose in which the model was originally skinned.",
+     &EggOptchar::dispatch_string, NULL, &_defpose);
+
   add_option
   add_option
     ("preload", "", 0,
     ("preload", "", 0,
      "Add an <AnimPreload> entry for each animation to the model file(s).  "
      "Add an <AnimPreload> entry for each animation to the model file(s).  "
@@ -273,6 +283,13 @@ run() {
       do_preload();
       do_preload();
     }
     }
 
 
+    // Finally, set the default poses.  It's important not to do this
+    // until after we have adjusted all of the transforms for the
+    // various joints.
+    if (!_defpose.empty()) {
+      do_defpose();
+    }
+
     write_eggs();
     write_eggs();
   }
   }
 }
 }
@@ -1421,6 +1438,83 @@ do_preload() {
   }
   }
 }
 }
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: EggOptchar::do_defpose
+//       Access: Private
+//  Description: Sets the initial pose for the character(s).
+////////////////////////////////////////////////////////////////////
+void EggOptchar::
+do_defpose() {
+  // Split out the defpose parameter.
+  Filename egg_filename;
+  size_t comma = _defpose.find(',');
+  egg_filename = _defpose.substr(0, comma);
+
+  string frame_str;
+  if (comma != string::npos) {
+    frame_str = _defpose.substr(comma + 1);
+  }
+  frame_str = trim(frame_str);
+  int frame = 0;
+  if (!frame_str.empty()) {
+    if (!string_to_int(frame_str, frame)) {
+      nout << "Invalid integer in -defpose: " << frame_str << "\n";
+      return;
+    }
+  }
+
+  // Now find the named animation file in our egg list.
+  int egg_index = -1;
+  int num_eggs = _collection->get_num_eggs();
+  int i;
+
+  // First, look for an exact match.
+  for (i = 0; i < num_eggs && egg_index == -1; ++i) {
+    if (_collection->get_egg(i)->get_egg_filename() == egg_filename) {
+      egg_index = i;
+    }
+  }
+
+  // Then, look for an inexact match.
+  string egg_basename = egg_filename.get_basename_wo_extension();
+  for (i = 0; i < num_eggs && egg_index == -1; ++i) {
+    if (_collection->get_egg(i)->get_egg_filename().get_basename_wo_extension() == egg_basename) {
+      egg_index = i;
+    }
+  }
+
+  if (egg_index == -1) {
+    // No joy.
+    nout << "Egg file " << egg_filename << " named in -defpose, but does not appear on command line.\n";
+    return;
+  }
+
+  EggData *egg_data = _collection->get_egg(egg_index);
+
+  if (_collection->get_num_models(egg_index) == 0) {
+    nout << "Egg file " << egg_filename << " does not include any model or animation.\n";
+    return;
+  }
+
+  // Now get the first model (or animation) named by this egg file.
+  int mi = _collection->get_first_model_index(egg_index);
+  EggCharacterData *ch = _collection->get_character_by_model_index(mi);
+  EggJointData *root_joint = ch->get_root_joint();
+
+  int anim_index = -1;
+  for (i = 0; i < ch->get_num_models() && anim_index == -1; ++i) {
+    if (ch->get_egg_data(i) == egg_data) {
+      anim_index = i;
+    }
+  }
+
+  // This couldn't possibly fail, since we already checked this above.
+  nassertv(anim_index != -1);
+
+  // Now we can recursively apply the default pose to the hierarchy.
+  ch->get_root_joint()->apply_default_pose(anim_index, frame);
+}
+
 int main(int argc, char *argv[]) {
 int main(int argc, char *argv[]) {
   // A call to pystub() to force libpystub.so to be linked in.
   // A call to pystub() to force libpystub.so to be linked in.
   pystub();
   pystub();

+ 3 - 0
pandatool/src/egg-optchar/eggOptchar.h

@@ -78,6 +78,7 @@ private:
   void do_flag_groups(EggGroupNode *egg_group);
   void do_flag_groups(EggGroupNode *egg_group);
   void rename_primitives(EggGroupNode *egg_group, const string &name);
   void rename_primitives(EggGroupNode *egg_group, const string &name);
   void do_preload();
   void do_preload();
+  void do_defpose();
 
 
   bool _list_hierarchy;
   bool _list_hierarchy;
   bool _list_hierarchy_v;
   bool _list_hierarchy_v;
@@ -118,6 +119,8 @@ private:
   typedef pvector<FlagGroupsEntry> FlagGroups;
   typedef pvector<FlagGroupsEntry> FlagGroups;
   FlagGroups _flag_groups;
   FlagGroups _flag_groups;
 
 
+  string _defpose;
+
   bool _optimal_hierarchy;
   bool _optimal_hierarchy;
   double _vref_quantum;
   double _vref_quantum;
 };
 };

+ 31 - 0
pandatool/src/eggcharbase/eggJointData.cxx

@@ -411,6 +411,37 @@ quantize_channels(const string &components, double quantum) {
   }
   }
 }
 }
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: EggJointData::apply_default_pose
+//       Access: Public
+//  Description: Applies the pose from the indicated frame of the
+//               indicated source model_index as the initial pose for
+//               this joint, and does this recursively on all joints
+//               below.
+////////////////////////////////////////////////////////////////////
+void EggJointData::
+apply_default_pose(int source_model, int frame) {
+  if (has_model(source_model)) {
+    EggJointPointer *source_joint;
+    DCAST_INTO_V(source_joint, _back_pointers[source_model]);
+    BackPointers::iterator bpi;
+    for (bpi = _back_pointers.begin(); bpi != _back_pointers.end(); ++bpi) {
+      EggBackPointer *back = (*bpi);
+      if (back != (EggBackPointer *)NULL) {
+        EggJointPointer *joint;
+        DCAST_INTO_V(joint, back);
+        joint->apply_default_pose(source_joint, frame);
+      }
+    }
+  }
+
+  Children::iterator ci;
+  for (ci = _children.begin(); ci != _children.end(); ++ci) {
+    EggJointData *child = (*ci);
+    child->apply_default_pose(source_model, frame);
+  }
+}
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: EggJointData::add_back_pointer
 //     Function: EggJointData::add_back_pointer
 //       Access: Public, Virtual
 //       Access: Public, Virtual

+ 1 - 0
pandatool/src/eggcharbase/eggJointData.h

@@ -59,6 +59,7 @@ public:
   void expose(EggGroup::DCSType dcs_type = EggGroup::DC_default);
   void expose(EggGroup::DCSType dcs_type = EggGroup::DC_default);
   void zero_channels(const string &components);
   void zero_channels(const string &components);
   void quantize_channels(const string &components, double quantum);
   void quantize_channels(const string &components, double quantum);
+  void apply_default_pose(int source_model, int frame);
 
 
   virtual void add_back_pointer(int model_index, EggObject *egg_object);
   virtual void add_back_pointer(int model_index, EggObject *egg_object);
   virtual void write(ostream &out, int indent_level = 0) const;
   virtual void write(ostream &out, int indent_level = 0) const;

+ 21 - 0
pandatool/src/eggcharbase/eggJointNodePointer.cxx

@@ -178,6 +178,27 @@ expose(EggGroup::DCSType dcs_type) {
   }
   }
 }
 }
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: EggJointNodePointer::apply_default_pose
+//       Access: Public, Virtual
+//  Description: Applies the pose from the indicated frame of the
+//               indicated source joint as the initial pose for
+//               this joint.
+////////////////////////////////////////////////////////////////////
+void EggJointNodePointer::
+apply_default_pose(EggJointPointer *source_joint, int frame) {
+  if (_joint != (EggGroup *)NULL) {
+    LMatrix4d pose;
+    if (frame >= 0 && frame < source_joint->get_num_frames()) {
+      pose = source_joint->get_frame(frame);
+    } else {
+      pose = get_frame(0);
+    }
+    _joint->clear_default_pose();
+    _joint->modify_default_pose().add_matrix4(pose);
+  }
+}
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: EggJointNodePointer::has_vertices
 //     Function: EggJointNodePointer::has_vertices
 //       Access: Public, Virtual
 //       Access: Public, Virtual

+ 1 - 0
pandatool/src/eggcharbase/eggJointNodePointer.h

@@ -39,6 +39,7 @@ public:
 
 
   virtual bool do_rebuild(EggCharacterDb &db);
   virtual bool do_rebuild(EggCharacterDb &db);
   virtual void expose(EggGroup::DCSType dcs_type);
   virtual void expose(EggGroup::DCSType dcs_type);
+  virtual void apply_default_pose(EggJointPointer *source_joint, int frame);
 
 
   virtual bool has_vertices() const;
   virtual bool has_vertices() const;
 
 

+ 11 - 0
pandatool/src/eggcharbase/eggJointPointer.cxx

@@ -98,3 +98,14 @@ zero_channels(const string &) {
 void EggJointPointer::
 void EggJointPointer::
 quantize_channels(const string &, double) {
 quantize_channels(const string &, double) {
 }
 }
+
+////////////////////////////////////////////////////////////////////
+//     Function: EggJointPointer::apply_default_pose
+//       Access: Public, Virtual
+//  Description: Applies the pose from the indicated frame of the
+//               indicated source joint as the initial pose for
+//               this joint.
+////////////////////////////////////////////////////////////////////
+void EggJointPointer::
+apply_default_pose(EggJointPointer *source_joint, int frame) {
+}

+ 1 - 0
pandatool/src/eggcharbase/eggJointPointer.h

@@ -47,6 +47,7 @@ public:
   virtual void expose(EggGroup::DCSType dcs_type);
   virtual void expose(EggGroup::DCSType dcs_type);
   virtual void zero_channels(const string &components);
   virtual void zero_channels(const string &components);
   virtual void quantize_channels(const string &components, double quantum);
   virtual void quantize_channels(const string &components, double quantum);
+  virtual void apply_default_pose(EggJointPointer *source_joint, int frame);
 
 
   virtual EggJointPointer *make_new_joint(const string &name)=0;
   virtual EggJointPointer *make_new_joint(const string &name)=0;
 
 

이 변경점에서 너무 많은 파일들이 변경되어 몇몇 파일들은 표시되지 않았습니다.