mirror of
https://github.com/panda3d/panda3d.git
synced 2026-04-19 05:01:03 -05:00
egg-optchar -defpose
This commit is contained in:
@@ -90,10 +90,10 @@ PRC_DESC("Set this true to interpolate character animations between frames, "
|
||||
|
||||
ConfigVariableBool restore_initial_pose
|
||||
("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) {
|
||||
|
||||
@@ -38,7 +38,7 @@ INLINE MovingPart<SwitchType>::
|
||||
MovingPart(const MovingPart<SwitchType> ©) :
|
||||
MovingPartBase(copy),
|
||||
_value(copy._value),
|
||||
_initial_value(copy._initial_value)
|
||||
_default_value(copy._default_value)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -50,10 +50,10 @@ MovingPart(const MovingPart<SwitchType> ©) :
|
||||
template<class SwitchType>
|
||||
INLINE MovingPart<SwitchType>::
|
||||
MovingPart(PartGroup *parent, const string &name,
|
||||
const ValueType &initial_value) :
|
||||
const ValueType &default_value) :
|
||||
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
|
||||
// Description: Creates and returns a new AnimChannel that is not
|
||||
// part of any hierarchy, but that returns the default
|
||||
@@ -92,8 +92,8 @@ get_value_type() const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class 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) {
|
||||
MovingPartBase::write_datagram(manager, me);
|
||||
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) {
|
||||
MovingPartBase::fillin(scan, manager);
|
||||
SwitchType::read_datagram(scan, _value);
|
||||
SwitchType::read_datagram(scan, _initial_value);
|
||||
SwitchType::read_datagram(scan, _default_value);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -37,14 +37,14 @@ protected:
|
||||
|
||||
public:
|
||||
INLINE MovingPart(PartGroup *parent, const string &name,
|
||||
const ValueType &_initial_value);
|
||||
const ValueType &default_value);
|
||||
|
||||
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;
|
||||
|
||||
ValueType _value;
|
||||
ValueType _initial_value;
|
||||
ValueType _default_value;
|
||||
|
||||
public:
|
||||
INLINE virtual void write_datagram(BamWriter* manager, Datagram &me);
|
||||
@@ -65,8 +65,8 @@ PUBLISHED:
|
||||
INLINE ValueType get_value() const {
|
||||
return _value;
|
||||
}
|
||||
INLINE ValueType get_initial_value() const {
|
||||
return _initial_value;
|
||||
INLINE ValueType get_default_value() const {
|
||||
return _default_value;
|
||||
}
|
||||
public:
|
||||
static void init_type() {
|
||||
|
||||
@@ -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
|
||||
// a default AnimChannel that just returns the part's initial
|
||||
// value.
|
||||
_channels[channel_index] = make_initial_channel();
|
||||
_channels[channel_index] = make_default_channel();
|
||||
} else {
|
||||
_channels[channel_index] = DCAST(AnimChannelBase, anim);
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ PUBLISHED:
|
||||
|
||||
public:
|
||||
virtual TypeHandle get_value_type() const=0;
|
||||
virtual AnimChannelBase *make_initial_channel() const=0;
|
||||
virtual AnimChannelBase *make_default_channel() const=0;
|
||||
|
||||
PUBLISHED:
|
||||
virtual bool clear_forced_channel();
|
||||
|
||||
@@ -32,8 +32,8 @@ MovingPartMatrix(const MovingPartMatrix ©) :
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE MovingPartMatrix::
|
||||
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) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -40,16 +40,16 @@ MovingPartMatrix::
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MovingPartMatrix::make_initial_channel
|
||||
// Function: MovingPartMatrix::make_default_channel
|
||||
// Access: Public, Virtual
|
||||
// Description: Creates and returns a new AnimChannel that is not
|
||||
// part of any hierarchy, but that returns the default
|
||||
// value associated with this part.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
AnimChannelBase *MovingPartMatrix::
|
||||
make_initial_channel() const {
|
||||
make_default_channel() const {
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ get_blend_value(const PartBundle *root) {
|
||||
if (cdata->_blend.empty()) {
|
||||
// No channel is bound; supply the default value.
|
||||
if (restore_initial_pose) {
|
||||
_value = _initial_value;
|
||||
_value = _default_value;
|
||||
}
|
||||
|
||||
} else if (_effective_control != (AnimControl *)NULL &&
|
||||
@@ -126,7 +126,7 @@ get_blend_value(const PartBundle *root) {
|
||||
|
||||
if (net_effect == 0.0f) {
|
||||
if (restore_initial_pose) {
|
||||
_value = _initial_value;
|
||||
_value = _default_value;
|
||||
}
|
||||
} else {
|
||||
_value = net_value / net_effect;
|
||||
@@ -194,7 +194,7 @@ get_blend_value(const PartBundle *root) {
|
||||
|
||||
if (net_effect == 0.0f) {
|
||||
if (restore_initial_pose) {
|
||||
_value = _initial_value;
|
||||
_value = _default_value;
|
||||
}
|
||||
|
||||
} else {
|
||||
@@ -273,7 +273,7 @@ get_blend_value(const PartBundle *root) {
|
||||
|
||||
if (net_effect == 0.0f) {
|
||||
if (restore_initial_pose) {
|
||||
_value = _initial_value;
|
||||
_value = _default_value;
|
||||
}
|
||||
|
||||
} else {
|
||||
@@ -352,7 +352,7 @@ get_blend_value(const PartBundle *root) {
|
||||
|
||||
if (net_effect == 0.0f) {
|
||||
if (restore_initial_pose) {
|
||||
_value = _initial_value;
|
||||
_value = _default_value;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
@@ -35,11 +35,10 @@ protected:
|
||||
|
||||
public:
|
||||
INLINE MovingPartMatrix(PartGroup *parent, const string &name,
|
||||
const LMatrix4f &initial_value =
|
||||
LMatrix4f::ident_mat());
|
||||
const LMatrix4f &default_value);
|
||||
virtual ~MovingPartMatrix();
|
||||
|
||||
virtual AnimChannelBase *make_initial_channel() const;
|
||||
virtual AnimChannelBase *make_default_channel() const;
|
||||
virtual void get_blend_value(const PartBundle *root);
|
||||
|
||||
virtual bool apply_freeze_matrix(const LVecBase3f &pos, const LVecBase3f &hpr, const LVecBase3f &scale);
|
||||
|
||||
@@ -32,8 +32,8 @@ MovingPartScalar(const MovingPartScalar ©) :
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE MovingPartScalar::
|
||||
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) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -59,7 +59,7 @@ get_blend_value(const PartBundle *root) {
|
||||
if (cdata->_blend.empty()) {
|
||||
// No channel is bound; supply the default value.
|
||||
if (restore_initial_pose) {
|
||||
_value = _initial_value;
|
||||
_value = _default_value;
|
||||
}
|
||||
|
||||
} else if (_effective_control != (AnimControl *)NULL &&
|
||||
@@ -105,7 +105,7 @@ get_blend_value(const PartBundle *root) {
|
||||
|
||||
if (net == 0.0f) {
|
||||
if (restore_initial_pose) {
|
||||
_value = _initial_value;
|
||||
_value = _default_value;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
@@ -34,7 +34,7 @@ protected:
|
||||
|
||||
public:
|
||||
INLINE MovingPartScalar(PartGroup *parent, const string &name,
|
||||
const float &initial_value = 0);
|
||||
const float &default_value = 0);
|
||||
virtual ~MovingPartScalar();
|
||||
|
||||
virtual void get_blend_value(const PartBundle *root);
|
||||
|
||||
@@ -198,8 +198,8 @@ apply_transform(const TransformState *transform) {
|
||||
// Description: Sets the control effect of all AnimControls to zero
|
||||
// (but does not "stop" the AnimControls). The
|
||||
// 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
|
||||
// not be using any CPU cycles, but they may still be in
|
||||
@@ -217,6 +217,7 @@ clear_control_effects() {
|
||||
cdataw->_blend.clear();
|
||||
cdataw->_net_blend = 0.0f;
|
||||
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->_blend.swap(new_blend);
|
||||
cdata->_anim_changed = true;
|
||||
determine_effective_channels(cdata);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -57,8 +57,8 @@ CharacterJoint(const CharacterJoint ©) :
|
||||
CharacterJoint::
|
||||
CharacterJoint(Character *character,
|
||||
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)
|
||||
{
|
||||
Thread *current_thread = Thread::get_current_thread();
|
||||
|
||||
@@ -38,7 +38,7 @@ protected:
|
||||
PUBLISHED:
|
||||
CharacterJoint(Character *character,
|
||||
PartBundle *root, PartGroup *parent, const string &name,
|
||||
const LMatrix4f &initial_value);
|
||||
const LMatrix4f &default_value);
|
||||
virtual ~CharacterJoint();
|
||||
|
||||
public:
|
||||
|
||||
@@ -47,6 +47,7 @@ JointVertexTransform(CharacterJoint *joint) :
|
||||
{
|
||||
// Tell the joint that we need to be informed when it moves.
|
||||
_joint->_vertex_transforms.insert(this);
|
||||
mark_modified(Thread::get_current_thread());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@@ -219,4 +220,5 @@ fillin(DatagramIterator &scan, BamReader *manager) {
|
||||
|
||||
manager->read_pointer(scan);
|
||||
_matrix_stale = true;
|
||||
mark_modified(Thread::get_current_thread());
|
||||
}
|
||||
|
||||
@@ -1508,6 +1508,26 @@ GROUPING ENTRIES
|
||||
may define either a 2-d or a 3-d transform when it appears within
|
||||
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 } }
|
||||
|
||||
@@ -1768,8 +1788,9 @@ ANIMATION STRUCTURE
|
||||
|
||||
It is not necessary for every joint to have vertices at all. Every
|
||||
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
|
||||
described in MORPH DESCRIPTION ENTRIES, above. These are meaningful
|
||||
|
||||
@@ -904,6 +904,61 @@ clear_tag(const string &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
|
||||
|
||||
@@ -74,8 +74,8 @@ operator = (const EggGroup ©) {
|
||||
_blend_operand_a = copy._blend_operand_a;
|
||||
_blend_operand_b = copy._blend_operand_b;
|
||||
_blend_color = copy._blend_color;
|
||||
|
||||
_tag_data = copy._tag_data;
|
||||
_default_pose = copy._default_pose;
|
||||
|
||||
unref_all_vertices();
|
||||
_vref = copy._vref;
|
||||
@@ -219,7 +219,11 @@ write(ostream &out, int indent_level) const {
|
||||
write_switch_flags(out, indent_level + 2);
|
||||
|
||||
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);
|
||||
@@ -1251,6 +1255,12 @@ r_transform(const LMatrix4d &mat, const LMatrix4d &inv,
|
||||
|
||||
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);
|
||||
} else {
|
||||
EggGroupNode::r_transform(mat, inv, to_cs);
|
||||
|
||||
@@ -262,6 +262,11 @@ PUBLISHED:
|
||||
INLINE bool has_tag(const string &key) const;
|
||||
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:
|
||||
INLINE TagData::const_iterator tag_begin() const;
|
||||
INLINE TagData::const_iterator tag_end() const;
|
||||
@@ -360,6 +365,12 @@ private:
|
||||
double _fps;
|
||||
PT(EggSwitchCondition) _lod;
|
||||
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;
|
||||
|
||||
typedef pvector< PT(EggGroup) > GroupRefs;
|
||||
|
||||
@@ -290,7 +290,7 @@ write(ostream &out, int indent_level) const {
|
||||
EggRenderMode::write(out, indent_level + 2);
|
||||
|
||||
if (has_transform()) {
|
||||
EggTransform::write(out, indent_level + 2);
|
||||
EggTransform::write(out, indent_level + 2, "<Transform>");
|
||||
}
|
||||
|
||||
indent(out, indent_level) << "}\n";
|
||||
|
||||
@@ -230,8 +230,8 @@ add_uniform_scale(double scale) {
|
||||
// format.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
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();
|
||||
for (int i = 0; i < num_components; i++) {
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
#include "pandabase.h"
|
||||
#include "luse.h"
|
||||
#include "eggObject.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : EggTransform
|
||||
@@ -85,7 +86,8 @@ PUBLISHED:
|
||||
INLINE const LMatrix3d &get_component_mat3(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:
|
||||
void internal_clear_transform();
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -435,21 +435,13 @@ NUMERIC ([+-]?(([0-9]+[.]?)|([0-9]*[.][0-9]+))([eE][+-]?[0-9]+)?)
|
||||
accept();
|
||||
return EXTERNAL_FILE;
|
||||
}
|
||||
"<FLT_HEADER>" {
|
||||
accept();
|
||||
return FLIGHT;
|
||||
}
|
||||
"<GROUP>" {
|
||||
accept();
|
||||
return GROUP;
|
||||
}
|
||||
"<HIP>" {
|
||||
"<DEFAULTPOSE>" {
|
||||
accept();
|
||||
return HIP;
|
||||
}
|
||||
"<IN>" {
|
||||
accept();
|
||||
return INTANGENT;
|
||||
return DEFAULTPOSE;
|
||||
}
|
||||
"<JOINT>" {
|
||||
accept();
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -24,69 +24,67 @@
|
||||
#define DTREF 280
|
||||
#define DYNAMICVERTEXPOOL 281
|
||||
#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;
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include "eggExternalReference.h"
|
||||
#include "eggData.h"
|
||||
#include "eggAnimPreload.h"
|
||||
#include "eggTransform.h"
|
||||
#include "pt_EggTexture.h"
|
||||
#include "pt_EggMaterial.h"
|
||||
|
||||
@@ -61,6 +62,9 @@
|
||||
typedef pvector< PT(EggObject) > EggStack;
|
||||
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
|
||||
// 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
|
||||
@@ -160,7 +164,7 @@ egg_cleanup_parser() {
|
||||
%token COORDSYSTEM CV DART
|
||||
%token DNORMAL DRGBA DUV DXYZ DCS DISTANCE DTREF
|
||||
%token DYNAMICVERTEXPOOL EXTERNAL_FILE
|
||||
%token FLIGHT GROUP HIP INTANGENT
|
||||
%token GROUP DEFAULTPOSE
|
||||
%token JOINT KNOTS INCLUDE
|
||||
%token INSTANCE LINE LOOP MATERIAL MATRIX3 MATRIX4 MODEL MREF NORMAL
|
||||
%token NURBSCURVE NURBSSURFACE OBJECTTYPE ORDER
|
||||
@@ -1432,6 +1436,7 @@ group_body:
|
||||
group->set_texlist_flag(value!=0);
|
||||
}
|
||||
| group_body transform
|
||||
| group_body default_pose
|
||||
| group_body group_vertex_ref
|
||||
| group_body switchcondition
|
||||
| group_body REF '{' group_name '}'
|
||||
@@ -1512,7 +1517,28 @@ collide_flags:
|
||||
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 '}'
|
||||
;
|
||||
@@ -1521,7 +1547,7 @@ transform:
|
||||
/*
|
||||
* transform_body
|
||||
*
|
||||
* enter: TOS is some kind of EggTransform.
|
||||
* enter: egg_top_transform has been assigned.
|
||||
* exit: transform has been filled in.
|
||||
*
|
||||
*/
|
||||
@@ -1544,70 +1570,70 @@ transform_body:
|
||||
translate2d:
|
||||
TRANSLATE '{' real real '}'
|
||||
{
|
||||
egg_stack.back()->as_transform()->add_translate2d(LVector2d($3, $4));
|
||||
egg_top_transform->add_translate2d(LVector2d($3, $4));
|
||||
}
|
||||
;
|
||||
|
||||
translate3d:
|
||||
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:
|
||||
ROTATE '{' real '}'
|
||||
{
|
||||
egg_stack.back()->as_transform()->add_rotate2d($3);
|
||||
egg_top_transform->add_rotate2d($3);
|
||||
}
|
||||
;
|
||||
|
||||
rotx:
|
||||
ROTX '{' real '}'
|
||||
{
|
||||
egg_stack.back()->as_transform()->add_rotx($3);
|
||||
egg_top_transform->add_rotx($3);
|
||||
}
|
||||
;
|
||||
|
||||
roty:
|
||||
ROTY '{' real '}'
|
||||
{
|
||||
egg_stack.back()->as_transform()->add_roty($3);
|
||||
egg_top_transform->add_roty($3);
|
||||
}
|
||||
;
|
||||
|
||||
rotz:
|
||||
ROTZ '{' real '}'
|
||||
{
|
||||
egg_stack.back()->as_transform()->add_rotz($3);
|
||||
egg_top_transform->add_rotz($3);
|
||||
}
|
||||
;
|
||||
|
||||
rotate3d:
|
||||
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:
|
||||
SCALE '{' real real '}'
|
||||
{
|
||||
egg_stack.back()->as_transform()->add_scale2d(LVecBase2d($3, $4));
|
||||
egg_top_transform->add_scale2d(LVecBase2d($3, $4));
|
||||
}
|
||||
;
|
||||
|
||||
scale3d:
|
||||
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:
|
||||
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
|
||||
{
|
||||
egg_stack.back()->as_transform()->add_matrix3
|
||||
egg_top_transform->add_matrix3
|
||||
(LMatrix3d($1, $2, $3,
|
||||
$4, $5, $6,
|
||||
$7, $8, $9));
|
||||
@@ -1639,7 +1665,7 @@ matrix4_body:
|
||||
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,
|
||||
$5, $6, $7, $8,
|
||||
$9, $10, $11, $12,
|
||||
|
||||
@@ -224,17 +224,21 @@ egg_to_slider(const string &name) {
|
||||
CharacterJointBundle *CharacterMaker::
|
||||
make_bundle() {
|
||||
build_joint_hierarchy(_egg_root, _skeleton_root, -1);
|
||||
|
||||
make_geometry(_egg_root);
|
||||
|
||||
_bundle->sort_descendants();
|
||||
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;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CharacterMaker::build_hierarchy
|
||||
// Function: CharacterMaker::build_joint_hierarchy
|
||||
// Access: Private
|
||||
// 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
|
||||
// it to single-precision.
|
||||
LMatrix4d matd;
|
||||
|
||||
// First, we get the original, initial transform from the
|
||||
// <Transform> entry.
|
||||
if (egg_group->has_transform()) {
|
||||
matd = egg_group->get_transform3d();
|
||||
} else {
|
||||
@@ -285,6 +292,16 @@ build_joint_hierarchy(EggNode *egg_node, PartGroup *part, int index) {
|
||||
index = _parts.size();
|
||||
_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 the joint requested an explicit DCS, create a node for
|
||||
// it.
|
||||
|
||||
@@ -189,6 +189,7 @@ write(ostream &out, int indent_level) const {
|
||||
mat.write(out, indent_level + 4);
|
||||
}
|
||||
LMatrix4f blend;
|
||||
update_blend(current_thread);
|
||||
get_blend(blend, current_thread);
|
||||
indent(out, indent_level)
|
||||
<< "Blended result =\n";
|
||||
|
||||
@@ -112,6 +112,16 @@ EggOptchar() {
|
||||
"objects parented to this node will not inherit its animation.",
|
||||
&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
|
||||
("preload", "", 0,
|
||||
"Add an <AnimPreload> entry for each animation to the model file(s). "
|
||||
@@ -273,6 +283,13 @@ run() {
|
||||
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();
|
||||
}
|
||||
}
|
||||
@@ -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[]) {
|
||||
// A call to pystub() to force libpystub.so to be linked in.
|
||||
pystub();
|
||||
|
||||
@@ -78,6 +78,7 @@ private:
|
||||
void do_flag_groups(EggGroupNode *egg_group);
|
||||
void rename_primitives(EggGroupNode *egg_group, const string &name);
|
||||
void do_preload();
|
||||
void do_defpose();
|
||||
|
||||
bool _list_hierarchy;
|
||||
bool _list_hierarchy_v;
|
||||
@@ -118,6 +119,8 @@ private:
|
||||
typedef pvector<FlagGroupsEntry> FlagGroups;
|
||||
FlagGroups _flag_groups;
|
||||
|
||||
string _defpose;
|
||||
|
||||
bool _optimal_hierarchy;
|
||||
double _vref_quantum;
|
||||
};
|
||||
|
||||
@@ -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
|
||||
// Access: Public, Virtual
|
||||
|
||||
@@ -59,6 +59,7 @@ public:
|
||||
void expose(EggGroup::DCSType dcs_type = EggGroup::DC_default);
|
||||
void zero_channels(const string &components);
|
||||
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 write(ostream &out, int indent_level = 0) const;
|
||||
|
||||
@@ -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
|
||||
// Access: Public, Virtual
|
||||
|
||||
@@ -39,6 +39,7 @@ public:
|
||||
|
||||
virtual bool do_rebuild(EggCharacterDb &db);
|
||||
virtual void expose(EggGroup::DCSType dcs_type);
|
||||
virtual void apply_default_pose(EggJointPointer *source_joint, int frame);
|
||||
|
||||
virtual bool has_vertices() const;
|
||||
|
||||
|
||||
@@ -98,3 +98,14 @@ zero_channels(const string &) {
|
||||
void EggJointPointer::
|
||||
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) {
|
||||
}
|
||||
|
||||
@@ -47,6 +47,7 @@ public:
|
||||
virtual void expose(EggGroup::DCSType dcs_type);
|
||||
virtual void zero_channels(const string &components);
|
||||
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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user