Panda3D
eggJointNodePointer.cxx
Go to the documentation of this file.
1 /**
2  * PANDA 3D SOFTWARE
3  * Copyright (c) Carnegie Mellon University. All rights reserved.
4  *
5  * All use of this software is subject to the terms of the revised BSD
6  * license. You should have received a copy of this license along
7  * with this source code in a file named "LICENSE."
8  *
9  * @file eggJointNodePointer.cxx
10  * @author drose
11  * @date 2001-02-26
12  */
13 
14 #include "eggJointNodePointer.h"
15 
16 #include "dcast.h"
17 #include "eggCharacterDb.h"
18 #include "eggGroup.h"
19 #include "eggObject.h"
20 #include "pointerTo.h"
21 
22 
23 TypeHandle EggJointNodePointer::_type_handle;
24 
25 /**
26  *
27  */
28 EggJointNodePointer::
29 EggJointNodePointer(EggObject *object) {
30  _joint = DCAST(EggGroup, object);
31 
32  if (_joint != nullptr && _joint->is_joint()) {
33  // Quietly insist that the joint has a transform, for neatness. If it
34  // does not, give it the identity transform.
35  if (!_joint->has_transform()) {
36  _joint->set_transform3d(LMatrix4d::ident_mat());
37  }
38  }
39 }
40 
41 /**
42  * Returns the number of frames of animation for this particular joint.
43  *
44  * In the case of a EggJointNodePointer, which just stores a pointer to a
45  * <Joint> entry for a character model (not an animation table), there is
46  * always exactly one frame: the rest pose.
47  */
49 get_num_frames() const {
50  return 1;
51 }
52 
53 /**
54  * Returns the transform matrix corresponding to this joint position in the
55  * nth frame.
56  *
57  * In the case of a EggJointNodePointer, which just stores a pointer to a
58  * <Joint> entry for a character model (not an animation table), there is
59  * always exactly one frame: the rest pose.
60  */
61 LMatrix4d EggJointNodePointer::
62 get_frame(int n) const {
63  nassertr(n == 0, LMatrix4d::ident_mat());
64  return _joint->get_transform3d();
65 }
66 
67 /**
68  * Sets the transform matrix corresponding to this joint position in the nth
69  * frame.
70  *
71  * In the case of a EggJointNodePointer, which just stores a pointer to a
72  * <Joint> entry for a character model (not an animation table), there is
73  * always exactly one frame: the rest pose.
74  */
76 set_frame(int n, const LMatrix4d &mat) {
77  nassertv(n == 0);
78  _joint->set_transform3d(mat);
79 }
80 
81 /**
82  * Performs the actual reparenting operation by removing the node from its old
83  * parent and associating it with its new parent, if any.
84  */
87  if (new_parent == nullptr) {
88  // No new parent; unparent the joint.
89  EggGroupNode *egg_parent = _joint->get_parent();
90  if (egg_parent != nullptr) {
91  egg_parent->remove_child(_joint.p());
92  egg_parent->steal_children(*_joint);
93  }
94 
95  } else {
96  // Reparent the joint to its new parent (implicitly unparenting it from
97  // its previous parent).
98  EggJointNodePointer *new_node = DCAST(EggJointNodePointer, new_parent);
99  if (new_node->_joint != _joint->get_parent()) {
100  new_node->_joint->add_child(_joint.p());
101  }
102  }
103 }
104 
105 /**
106  * Moves the vertices assigned to this joint into the other joint (which
107  * should be of the same type).
108  */
111  if (new_joint == nullptr) {
112  _joint->unref_all_vertices();
113 
114  } else {
115  EggJointNodePointer *new_node;
116  DCAST_INTO_V(new_node, new_joint);
117 
118  new_node->_joint->steal_vrefs(_joint);
119  }
120 }
121 
122 /**
123  * Rebuilds the entire table all at once, based on the frames added by
124  * repeated calls to add_rebuild_frame() since the last call to
125  * begin_rebuild().
126  *
127  * Until do_rebuild() is called, the animation table is not changed.
128  *
129  * The return value is true if all frames are acceptable, or false if there is
130  * some problem.
131  */
134  LMatrix4d mat;
135  if (!db.get_matrix(this, EggCharacterDb::TT_rebuild_frame, 0, mat)) {
136  // No rebuild frame; this is OK.
137  return true;
138  }
139 
140  _joint->set_transform3d(mat);
141 
142  // We shouldn't have a frame 1.
143  nassertr(!db.get_matrix(this, EggCharacterDb::TT_rebuild_frame, 1, mat), false);
144 
145  return true;
146 }
147 
148 /**
149  * Flags the joint with the indicated DCS flag so that it will be loaded as a
150  * separate node in the player.
151  */
153 expose(EggGroup::DCSType dcs_type) {
154  if (_joint != nullptr) {
155  _joint->set_dcs_type(dcs_type);
156  }
157 }
158 
159 /**
160  * Applies the pose from the indicated frame of the indicated source joint as
161  * the initial pose for this joint.
162  */
164 apply_default_pose(EggJointPointer *source_joint, int frame) {
165  if (_joint != nullptr) {
166  LMatrix4d pose;
167  if (frame >= 0 && frame < source_joint->get_num_frames()) {
168  pose = source_joint->get_frame(frame);
169  } else {
170  pose = get_frame(0);
171  }
172  _joint->clear_default_pose();
173  _joint->modify_default_pose().add_matrix4(pose);
174  }
175 }
176 
177 /**
178  * Returns true if there are any vertices referenced by the node this points
179  * to, false otherwise. For certain kinds of back pointers (e.g. table
180  * animation entries), this is always false.
181  */
183 has_vertices() const {
184  if (_joint != nullptr) {
185  return (_joint->vref_size() != 0) || _joint->joint_has_primitives();
186  }
187 
188  return false;
189 }
190 
191 /**
192  * Creates a new child of the current joint in the egg data, and returns a
193  * pointer to it.
194  */
196 make_new_joint(const std::string &name) {
197  EggGroup *new_joint = new EggGroup(name);
198  new_joint->set_group_type(EggGroup::GT_joint);
199  _joint->add_child(new_joint);
200  return new EggJointNodePointer(new_joint);
201 }
202 
203 /**
204  * Applies the indicated name change to the egg file.
205  */
207 set_name(const std::string &name) {
208  _joint->set_name(name);
209 }
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual void set_name(const std::string &name)
Applies the indicated name change to the egg file.
virtual LMatrix4d get_frame(int n) const
Returns the transform matrix corresponding to this joint position in the nth frame.
A base class for nodes in the hierarchy that are not leaf nodes.
Definition: eggGroupNode.h:46
virtual EggJointPointer * make_new_joint(const std::string &name)
Creates a new child of the current joint in the egg data, and returns a pointer to it.
virtual void apply_default_pose(EggJointPointer *source_joint, int frame)
Applies the pose from the indicated frame of the indicated source joint as the initial pose for this ...
virtual void move_vertices_to(EggJointPointer *new_joint)
Moves the vertices assigned to this joint into the other joint (which should be of the same type).
virtual bool has_vertices() const
Returns true if there are any vertices referenced by the node this points to, false otherwise.
virtual bool do_rebuild(EggCharacterDb &db)
Rebuilds the entire table all at once, based on the frames added by repeated calls to add_rebuild_fra...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual void do_finish_reparent(EggJointPointer *new_parent)
Performs the actual reparenting operation by removing the node from its old parent and associating it...
The main glue of the egg hierarchy, this corresponds to the <Group>, <Instance>, and <Joint> type nod...
Definition: eggGroup.h:34
This stores a pointer back to a <Joint> node.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This class is used during joint optimization or restructuring to store the table of interim joint com...
virtual int get_num_frames() const
Returns the number of frames of animation for this particular joint.
void steal_children(EggGroupNode &other)
Moves all the children from the other node to this one.
virtual void expose(EggGroup::DCSType dcs_type)
Flags the joint with the indicated DCS flag so that it will be loaded as a separate node in the playe...
This is a base class for EggJointNodePointer and EggMatrixTablePointer.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
The highest-level base class in the egg directory.
Definition: eggObject.h:29
bool get_matrix(const EggJointPointer *joint, TableType type, int frame, LMatrix4d &mat) const
Looks up the data for the indicated joint, type, and frame, and fills it in result (and returns true)...
virtual void set_frame(int n, const LMatrix4d &mat)
Sets the transform matrix corresponding to this joint position in the nth frame.