Panda3D
 All Classes Functions Variables Enumerations
eggJointNodePointer.cxx
00001 // Filename: eggJointNodePointer.cxx
00002 // Created by:  drose (26Feb01)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 #include "eggJointNodePointer.h"
00016 
00017 #include "dcast.h"
00018 #include "eggObject.h"
00019 #include "eggGroup.h"
00020 #include "pointerTo.h"
00021 
00022 
00023 TypeHandle EggJointNodePointer::_type_handle;
00024 
00025 ////////////////////////////////////////////////////////////////////
00026 //     Function: EggJointNodePointer::Constructor
00027 //       Access: Public
00028 //  Description:
00029 ////////////////////////////////////////////////////////////////////
00030 EggJointNodePointer::
00031 EggJointNodePointer(EggObject *object) {
00032   _joint = DCAST(EggGroup, object);
00033 
00034   if (_joint != (EggGroup *)NULL && _joint->is_joint()) {
00035     // Quietly insist that the joint has a transform, for neatness.  If
00036     // it does not, give it the identity transform.
00037     if (!_joint->has_transform()) {
00038       _joint->set_transform3d(LMatrix4d::ident_mat());
00039     }
00040   }
00041 }
00042 
00043 ////////////////////////////////////////////////////////////////////
00044 //     Function: EggJointNodePointer::get_num_frames
00045 //       Access: Public, Virtual
00046 //  Description: Returns the number of frames of animation for this
00047 //               particular joint.
00048 //
00049 //               In the case of a EggJointNodePointer, which just
00050 //               stores a pointer to a <Joint> entry for a character
00051 //               model (not an animation table), there is always
00052 //               exactly one frame: the rest pose.
00053 ////////////////////////////////////////////////////////////////////
00054 int EggJointNodePointer::
00055 get_num_frames() const {
00056   return 1;
00057 }
00058 
00059 ////////////////////////////////////////////////////////////////////
00060 //     Function: EggJointNodePointer::get_frame
00061 //       Access: Public, Virtual
00062 //  Description: Returns the transform matrix corresponding to this
00063 //               joint position in the nth frame.
00064 //
00065 //               In the case of a EggJointNodePointer, which just
00066 //               stores a pointer to a <Joint> entry for a character
00067 //               model (not an animation table), there is always
00068 //               exactly one frame: the rest pose.
00069 ////////////////////////////////////////////////////////////////////
00070 LMatrix4d EggJointNodePointer::
00071 get_frame(int n) const {
00072   nassertr(n == 0, LMatrix4d::ident_mat());
00073   return _joint->get_transform3d();
00074 }
00075 
00076 ////////////////////////////////////////////////////////////////////
00077 //     Function: EggJointNodePointer::set_frame
00078 //       Access: Public, Virtual
00079 //  Description: Sets the transform matrix corresponding to this
00080 //               joint position in the nth frame.
00081 //
00082 //               In the case of a EggJointNodePointer, which just
00083 //               stores a pointer to a <Joint> entry for a character
00084 //               model (not an animation table), there is always
00085 //               exactly one frame: the rest pose.
00086 ////////////////////////////////////////////////////////////////////
00087 void EggJointNodePointer::
00088 set_frame(int n, const LMatrix4d &mat) {
00089   nassertv(n == 0);
00090   _joint->set_transform3d(mat);
00091 }
00092 
00093 ////////////////////////////////////////////////////////////////////
00094 //     Function: EggJointNodePointer::do_finish_reparent
00095 //       Access: Protected
00096 //  Description: Performs the actual reparenting operation
00097 //               by removing the node from its old parent and
00098 //               associating it with its new parent, if any.
00099 ////////////////////////////////////////////////////////////////////
00100 void EggJointNodePointer::
00101 do_finish_reparent(EggJointPointer *new_parent) {
00102   if (new_parent == (EggJointPointer *)NULL) {
00103     // No new parent; unparent the joint.
00104     EggGroupNode *egg_parent = _joint->get_parent();
00105     if (egg_parent != (EggGroupNode *)NULL) {
00106       egg_parent->remove_child(_joint.p());
00107       egg_parent->steal_children(*_joint);
00108     }
00109 
00110   } else {
00111     // Reparent the joint to its new parent (implicitly unparenting it
00112     // from its previous parent).
00113     EggJointNodePointer *new_node = DCAST(EggJointNodePointer, new_parent);
00114     if (new_node->_joint != _joint->get_parent()) {
00115       new_node->_joint->add_child(_joint.p());
00116     }
00117   }
00118 }
00119 
00120 ////////////////////////////////////////////////////////////////////
00121 //     Function: EggJointNodePointer::move_vertices_to
00122 //       Access: Public, Virtual
00123 //  Description: Moves the vertices assigned to this joint into the
00124 //               other joint (which should be of the same type).
00125 ////////////////////////////////////////////////////////////////////
00126 void EggJointNodePointer::
00127 move_vertices_to(EggJointPointer *new_joint) {
00128   if (new_joint == (EggJointPointer *)NULL) {
00129     _joint->unref_all_vertices();
00130 
00131   } else {
00132     EggJointNodePointer *new_node;
00133     DCAST_INTO_V(new_node, new_joint);
00134 
00135     new_node->_joint->steal_vrefs(_joint);
00136   }
00137 }
00138 
00139 ////////////////////////////////////////////////////////////////////
00140 //     Function: EggJointNodePointer::do_rebuild
00141 //       Access: Public, Virtual
00142 //  Description: Rebuilds the entire table all at once, based on the
00143 //               frames added by repeated calls to add_rebuild_frame()
00144 //               since the last call to begin_rebuild().
00145 //
00146 //               Until do_rebuild() is called, the animation table is
00147 //               not changed.
00148 //
00149 //               The return value is true if all frames are
00150 //               acceptable, or false if there is some problem.
00151 ////////////////////////////////////////////////////////////////////
00152 bool EggJointNodePointer::
00153 do_rebuild(EggCharacterDb &db) {
00154   LMatrix4d mat;
00155   if (!db.get_matrix(this, EggCharacterDb::TT_rebuild_frame, 0, mat)) {
00156     // No rebuild frame; this is OK.
00157     return true;
00158   }
00159 
00160   _joint->set_transform3d(mat);
00161 
00162   // We shouldn't have a frame 1.
00163   nassertr(!db.get_matrix(this, EggCharacterDb::TT_rebuild_frame, 1, mat), false);
00164   
00165   return true;
00166 }
00167 
00168 ////////////////////////////////////////////////////////////////////
00169 //     Function: EggJointNodePointer::expose
00170 //       Access: Public, Virtual
00171 //  Description: Flags the joint with the indicated DCS flag so that
00172 //               it will be loaded as a separate node in the player.
00173 ////////////////////////////////////////////////////////////////////
00174 void EggJointNodePointer::
00175 expose(EggGroup::DCSType dcs_type) {
00176   if (_joint != (EggGroup *)NULL) {
00177     _joint->set_dcs_type(dcs_type);
00178   }
00179 }
00180 
00181 ////////////////////////////////////////////////////////////////////
00182 //     Function: EggJointNodePointer::apply_default_pose
00183 //       Access: Public, Virtual
00184 //  Description: Applies the pose from the indicated frame of the
00185 //               indicated source joint as the initial pose for
00186 //               this joint.
00187 ////////////////////////////////////////////////////////////////////
00188 void EggJointNodePointer::
00189 apply_default_pose(EggJointPointer *source_joint, int frame) {
00190   if (_joint != (EggGroup *)NULL) {
00191     LMatrix4d pose;
00192     if (frame >= 0 && frame < source_joint->get_num_frames()) {
00193       pose = source_joint->get_frame(frame);
00194     } else {
00195       pose = get_frame(0);
00196     }
00197     _joint->clear_default_pose();
00198     _joint->modify_default_pose().add_matrix4(pose);
00199   }
00200 }
00201 
00202 ////////////////////////////////////////////////////////////////////
00203 //     Function: EggJointNodePointer::has_vertices
00204 //       Access: Public, Virtual
00205 //  Description: Returns true if there are any vertices referenced by
00206 //               the node this points to, false otherwise.  For
00207 //               certain kinds of back pointers (e.g. table animation
00208 //               entries), this is always false.
00209 ////////////////////////////////////////////////////////////////////
00210 bool EggJointNodePointer::
00211 has_vertices() const {
00212   if (_joint != (EggGroup *)NULL) {
00213     return (_joint->vref_size() != 0) || _joint->joint_has_primitives();
00214   }
00215 
00216   return false;
00217 }
00218 
00219 ////////////////////////////////////////////////////////////////////
00220 //     Function: EggJointNodePointer::make_new_joint
00221 //       Access: Public, Virtual
00222 //  Description: Creates a new child of the current joint in the
00223 //               egg data, and returns a pointer to it.
00224 ////////////////////////////////////////////////////////////////////
00225 EggJointPointer *EggJointNodePointer::
00226 make_new_joint(const string &name) {
00227   EggGroup *new_joint = new EggGroup(name);
00228   new_joint->set_group_type(EggGroup::GT_joint);
00229   _joint->add_child(new_joint);
00230   return new EggJointNodePointer(new_joint);
00231 }
00232 
00233 ////////////////////////////////////////////////////////////////////
00234 //     Function: EggJointNodePointer::set_name
00235 //       Access: Public, Virtual
00236 //  Description: Applies the indicated name change to the egg file.
00237 ////////////////////////////////////////////////////////////////////
00238 void EggJointNodePointer::
00239 set_name(const string &name) {
00240   _joint->set_name(name);
00241 }
 All Classes Functions Variables Enumerations