mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 10:54:24 -04:00
Remove shear from BT_normalized_linear, add BT_componentwise and BT_componentwise_quat
This commit is contained in:
parent
a998cf46cd
commit
34c1491fbb
@ -82,16 +82,17 @@ get_value(int, TYPENAME AnimChannel<SwitchType>::ValueType &) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: AnimChannel::get_value_no_scale
|
// Function: AnimChannel::get_value_no_scale_share
|
||||||
// Access: Public, Virtual
|
// Access: Public, Virtual
|
||||||
// Description: Returns the value associated with the current frame,
|
// Description: Returns the value associated with the current frame,
|
||||||
// with no scale components. This only makes sense for
|
// with no scale or share components. This only makes
|
||||||
// a matrix-type channel, although for fiddly technical
|
// sense for a matrix-type channel, although for fiddly
|
||||||
// reasons the function exists for all channels.
|
// technical reasons the function exists for all
|
||||||
|
// channels.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
template<class SwitchType>
|
template<class SwitchType>
|
||||||
void AnimChannel<SwitchType>::
|
void AnimChannel<SwitchType>::
|
||||||
get_value_no_scale(int frame, ValueType &value) {
|
get_value_no_scale_shear(int frame, ValueType &value) {
|
||||||
get_value(frame, value);
|
get_value(frame, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,10 +105,60 @@ get_value_no_scale(int frame, ValueType &value) {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
template<class SwitchType>
|
template<class SwitchType>
|
||||||
void AnimChannel<SwitchType>::
|
void AnimChannel<SwitchType>::
|
||||||
get_scale(int, float scale[3]) {
|
get_scale(int, LVecBase3f &scale) {
|
||||||
scale[0] = 1.0f;
|
nassertv(false);
|
||||||
scale[1] = 1.0f;
|
}
|
||||||
scale[2] = 1.0f;
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: AnimChannel::get_hpr
|
||||||
|
// Access: Public, Virtual
|
||||||
|
// Description: Returns the h, p, and r components associated
|
||||||
|
// with the current frame. As above, this only makes
|
||||||
|
// sense for a matrix-type channel.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
template<class SwitchType>
|
||||||
|
void AnimChannel<SwitchType>::
|
||||||
|
get_hpr(int, LVecBase3f &hpr) {
|
||||||
|
nassertv(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: AnimChannel::get_quat
|
||||||
|
// Access: Public, Virtual
|
||||||
|
// Description: Returns the rotation component associated with the
|
||||||
|
// current frame, expressed as a quaternion. As above,
|
||||||
|
// this only makes sense for a matrix-type channel.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
template<class SwitchType>
|
||||||
|
void AnimChannel<SwitchType>::
|
||||||
|
get_quat(int, LQuaternionf &quat) {
|
||||||
|
nassertv(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: AnimChannel::get_pos
|
||||||
|
// Access: Public, Virtual
|
||||||
|
// Description: Returns the x, y, and z translation components
|
||||||
|
// associated with the current frame. As above, this
|
||||||
|
// only makes sense for a matrix-type channel.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
template<class SwitchType>
|
||||||
|
void AnimChannel<SwitchType>::
|
||||||
|
get_pos(int, LVecBase3f &pos) {
|
||||||
|
nassertv(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: AnimChannel::get_shear
|
||||||
|
// Access: Public, Virtual
|
||||||
|
// Description: Returns the a, b, and c shear components associated
|
||||||
|
// with the current frame. As above, this only makes
|
||||||
|
// sense for a matrix-type channel.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
template<class SwitchType>
|
||||||
|
void AnimChannel<SwitchType>::
|
||||||
|
get_shear(int, LVecBase3f &shear) {
|
||||||
|
nassertv(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -47,12 +47,13 @@ public:
|
|||||||
PUBLISHED:
|
PUBLISHED:
|
||||||
virtual void get_value(int frame, ValueType &value)=0;
|
virtual void get_value(int frame, ValueType &value)=0;
|
||||||
|
|
||||||
// These two functions only have meaning for matrix types.
|
// These transform-component methods only have meaning for matrix types.
|
||||||
virtual void get_value_no_scale(int frame, ValueType &value);
|
virtual void get_value_no_scale_shear(int frame, ValueType &value);
|
||||||
virtual void get_scale(int frame, float scale[3]);
|
virtual void get_scale(int frame, LVecBase3f &scale);
|
||||||
// The second parameter above should really by LVector3f instead of
|
virtual void get_hpr(int frame, LVecBase3f &hpr);
|
||||||
// float[3], but there seems to be a compiler bug in EGCS that
|
virtual void get_quat(int frame, LQuaternionf &quat);
|
||||||
// doesn't like that. So we have this kludge for now.
|
virtual void get_pos(int frame, LVecBase3f &pos);
|
||||||
|
virtual void get_shear(int frame, LVecBase3f &shear);
|
||||||
|
|
||||||
virtual TypeHandle get_value_type() const;
|
virtual TypeHandle get_value_type() const;
|
||||||
|
|
||||||
|
@ -80,14 +80,14 @@ get_value(int, LMatrix4f &mat) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: AnimChannelMatrixDynamic::get_value_no_scale
|
// Function: AnimChannelMatrixDynamic::get_value_no_scale_shear
|
||||||
// Access: Public, Virtual
|
// Access: Public, Virtual
|
||||||
// Description: Gets the value of the channel at the indicated frame,
|
// Description: Gets the value of the channel at the indicated frame,
|
||||||
// without any scale information.
|
// without any scale or shear information.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void AnimChannelMatrixDynamic::
|
void AnimChannelMatrixDynamic::
|
||||||
get_value_no_scale(int frame, LMatrix4f &mat) {
|
get_value_no_scale_shear(int frame, LMatrix4f &mat) {
|
||||||
if (_value->has_scale()) {
|
if (_value->has_scale() || _value->has_shear()) {
|
||||||
compose_matrix(mat, LVecBase3f(1.0f, 1.0f, 1.0f),
|
compose_matrix(mat, LVecBase3f(1.0f, 1.0f, 1.0f),
|
||||||
_value->get_hpr(), _value->get_pos());
|
_value->get_hpr(), _value->get_pos());
|
||||||
} else {
|
} else {
|
||||||
@ -101,11 +101,56 @@ get_value_no_scale(int frame, LMatrix4f &mat) {
|
|||||||
// Description: Gets the scale value at the indicated frame.
|
// Description: Gets the scale value at the indicated frame.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void AnimChannelMatrixDynamic::
|
void AnimChannelMatrixDynamic::
|
||||||
get_scale(int frame, float scale[3]) {
|
get_scale(int frame, LVecBase3f &scale) {
|
||||||
const LVecBase3f &sc = _value->get_scale();
|
scale = _value->get_scale();
|
||||||
scale[0] = sc[0];
|
}
|
||||||
scale[1] = sc[1];
|
|
||||||
scale[2] = sc[2];
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: AnimChannelMatrixDynamic::get_hpr
|
||||||
|
// Access: Public, Virtual
|
||||||
|
// Description: Returns the h, p, and r components associated
|
||||||
|
// with the current frame. As above, this only makes
|
||||||
|
// sense for a matrix-type channel.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void AnimChannelMatrixDynamic::
|
||||||
|
get_hpr(int, LVecBase3f &hpr) {
|
||||||
|
hpr = _value->get_hpr();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: AnimChannelMatrixDynamic::get_quat
|
||||||
|
// Access: Public, Virtual
|
||||||
|
// Description: Returns the rotation component associated with the
|
||||||
|
// current frame, expressed as a quaternion. As above,
|
||||||
|
// this only makes sense for a matrix-type channel.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void AnimChannelMatrixDynamic::
|
||||||
|
get_quat(int, LQuaternionf &quat) {
|
||||||
|
quat = _value->get_quat();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: AnimChannelMatrixDynamic::get_pos
|
||||||
|
// Access: Public, Virtual
|
||||||
|
// Description: Returns the x, y, and z translation components
|
||||||
|
// associated with the current frame. As above, this
|
||||||
|
// only makes sense for a matrix-type channel.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void AnimChannelMatrixDynamic::
|
||||||
|
get_pos(int, LVecBase3f &pos) {
|
||||||
|
pos = _value->get_pos();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: AnimChannelMatrixDynamic::get_shear
|
||||||
|
// Access: Public, Virtual
|
||||||
|
// Description: Returns the a, b, and c shear components associated
|
||||||
|
// with the current frame. As above, this only makes
|
||||||
|
// sense for a matrix-type channel.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void AnimChannelMatrixDynamic::
|
||||||
|
get_shear(int, LVecBase3f &shear) {
|
||||||
|
shear = _value->get_shear();
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
@ -48,8 +48,13 @@ protected:
|
|||||||
public:
|
public:
|
||||||
virtual bool has_changed(int last_frame, int this_frame);
|
virtual bool has_changed(int last_frame, int this_frame);
|
||||||
virtual void get_value(int frame, LMatrix4f &mat);
|
virtual void get_value(int frame, LMatrix4f &mat);
|
||||||
virtual void get_value_no_scale(int frame, LMatrix4f &value);
|
|
||||||
virtual void get_scale(int frame, float scale[3]);
|
virtual void get_value_no_scale_shear(int frame, LMatrix4f &value);
|
||||||
|
virtual void get_scale(int frame, LVecBase3f &scale);
|
||||||
|
virtual void get_hpr(int frame, LVecBase3f &hpr);
|
||||||
|
virtual void get_quat(int frame, LQuaternionf &quat);
|
||||||
|
virtual void get_pos(int frame, LVecBase3f &pos);
|
||||||
|
virtual void get_shear(int frame, LVecBase3f &shear);
|
||||||
|
|
||||||
PUBLISHED:
|
PUBLISHED:
|
||||||
void set_value(const LMatrix4f &value);
|
void set_value(const LMatrix4f &value);
|
||||||
|
@ -106,19 +106,22 @@ get_value(int frame, LMatrix4f &mat) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: AnimChannelMatrixXfmTable::get_value_no_scale
|
// Function: AnimChannelMatrixXfmTable::get_value_no_scale_shear
|
||||||
// Access: Public, Virtual
|
// Access: Public, Virtual
|
||||||
// Description: Gets the value of the channel at the indicated frame,
|
// Description: Gets the value of the channel at the indicated frame,
|
||||||
// without any scale information.
|
// without any scale or shear information.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void AnimChannelMatrixXfmTable::
|
void AnimChannelMatrixXfmTable::
|
||||||
get_value_no_scale(int frame, LMatrix4f &mat) {
|
get_value_no_scale_shear(int frame, LMatrix4f &mat) {
|
||||||
float components[num_matrix_components];
|
float components[num_matrix_components];
|
||||||
components[0] = 1.0f;
|
components[0] = 1.0f;
|
||||||
components[1] = 1.0f;
|
components[1] = 1.0f;
|
||||||
components[2] = 1.0f;
|
components[2] = 1.0f;
|
||||||
|
components[3] = 0.0f;
|
||||||
|
components[4] = 0.0f;
|
||||||
|
components[5] = 0.0f;
|
||||||
|
|
||||||
for (int i = 3; i < num_matrix_components; i++) {
|
for (int i = 6; i < num_matrix_components; i++) {
|
||||||
if (_tables[i].empty()) {
|
if (_tables[i].empty()) {
|
||||||
components[i] = get_default_value(i);
|
components[i] = get_default_value(i);
|
||||||
} else {
|
} else {
|
||||||
@ -135,23 +138,99 @@ get_value_no_scale(int frame, LMatrix4f &mat) {
|
|||||||
// Description: Gets the scale value at the indicated frame.
|
// Description: Gets the scale value at the indicated frame.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void AnimChannelMatrixXfmTable::
|
void AnimChannelMatrixXfmTable::
|
||||||
get_scale(int frame, float scale[3]) {
|
get_scale(int frame, LVecBase3f &scale) {
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
if (_tables[i].empty()) {
|
if (_tables[i].empty()) {
|
||||||
scale[i] = get_default_value(i);
|
scale[i] = 1.0f;
|
||||||
} else {
|
} else {
|
||||||
scale[i] = _tables[i][frame % _tables[i].size()];
|
scale[i] = _tables[i][frame % _tables[i].size()];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: AnimChannelMatrixXfmTable::get_hpr
|
||||||
|
// Access: Public, Virtual
|
||||||
|
// Description: Returns the h, p, and r components associated
|
||||||
|
// with the current frame. As above, this only makes
|
||||||
|
// sense for a matrix-type channel.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void AnimChannelMatrixXfmTable::
|
||||||
|
get_hpr(int frame, LVecBase3f &hpr) {
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
if (_tables[i + 6].empty()) {
|
||||||
|
hpr[i] = 0.0f;
|
||||||
|
} else {
|
||||||
|
hpr[i] = _tables[i + 6][frame % _tables[i + 6].size()];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: AnimChannelMatrixXfmTable::get_quat
|
||||||
|
// Access: Public, Virtual
|
||||||
|
// Description: Returns the rotation component associated with the
|
||||||
|
// current frame, expressed as a quaternion. As above,
|
||||||
|
// this only makes sense for a matrix-type channel.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void AnimChannelMatrixXfmTable::
|
||||||
|
get_quat(int frame, LQuaternionf &quat) {
|
||||||
|
LVecBase3f hpr;
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
if (_tables[i + 6].empty()) {
|
||||||
|
hpr[i] = 0.0f;
|
||||||
|
} else {
|
||||||
|
hpr[i] = _tables[i + 6][frame % _tables[i + 6].size()];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
quat.set_hpr(hpr);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: AnimChannelMatrixXfmTable::get_pos
|
||||||
|
// Access: Public, Virtual
|
||||||
|
// Description: Returns the x, y, and z translation components
|
||||||
|
// associated with the current frame. As above, this
|
||||||
|
// only makes sense for a matrix-type channel.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void AnimChannelMatrixXfmTable::
|
||||||
|
get_pos(int frame, LVecBase3f &pos) {
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
if (_tables[i + 9].empty()) {
|
||||||
|
pos[i] = 0.0f;
|
||||||
|
} else {
|
||||||
|
pos[i] = _tables[i + 9][frame % _tables[i + 9].size()];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: AnimChannelMatrixXfmTable::get_shear
|
||||||
|
// Access: Public, Virtual
|
||||||
|
// Description: Returns the a, b, and c shear components associated
|
||||||
|
// with the current frame. As above, this only makes
|
||||||
|
// sense for a matrix-type channel.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void AnimChannelMatrixXfmTable::
|
||||||
|
get_shear(int frame, LVecBase3f &shear) {
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
if (_tables[i + 3].empty()) {
|
||||||
|
shear[i] = 0.0f;
|
||||||
|
} else {
|
||||||
|
shear[i] = _tables[i + 3][frame % _tables[i + 3].size()];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: AnimChannelMatrixXfmTable::set_table
|
// Function: AnimChannelMatrixXfmTable::set_table
|
||||||
// Access: Public
|
// Access: Public
|
||||||
// Description: Assigns the indicated table. table_id is one of 'i',
|
// Description: Assigns the indicated table. table_id is one of 'i',
|
||||||
// 'j', 'k', for scale, 'h', 'p', 'r', for rotation, and
|
// 'j', 'k', for scale, 'a', 'b', 'c' for shear, 'h',
|
||||||
// 'x', 'y', 'z', for translation. The new table must
|
// 'p', 'r', for rotation, and 'x', 'y', 'z', for
|
||||||
// have either zero, one, or get_num_frames() frames.
|
// translation. The new table must have either zero,
|
||||||
|
// one, or get_num_frames() frames.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void AnimChannelMatrixXfmTable::
|
void AnimChannelMatrixXfmTable::
|
||||||
set_table(char table_id, const CPTA_float &table) {
|
set_table(char table_id, const CPTA_float &table) {
|
||||||
|
@ -47,8 +47,13 @@ public:
|
|||||||
|
|
||||||
virtual bool has_changed(int last_frame, int this_frame);
|
virtual bool has_changed(int last_frame, int this_frame);
|
||||||
virtual void get_value(int frame, LMatrix4f &mat);
|
virtual void get_value(int frame, LMatrix4f &mat);
|
||||||
virtual void get_value_no_scale(int frame, LMatrix4f &value);
|
|
||||||
virtual void get_scale(int frame, float scale[3]);
|
virtual void get_value_no_scale_shear(int frame, LMatrix4f &value);
|
||||||
|
virtual void get_scale(int frame, LVecBase3f &scale);
|
||||||
|
virtual void get_hpr(int frame, LVecBase3f &hpr);
|
||||||
|
virtual void get_quat(int frame, LQuaternionf &quat);
|
||||||
|
virtual void get_pos(int frame, LVecBase3f &pos);
|
||||||
|
virtual void get_shear(int frame, LVecBase3f &shear);
|
||||||
|
|
||||||
static INLINE bool is_valid_id(char table_id);
|
static INLINE bool is_valid_id(char table_id);
|
||||||
|
|
||||||
|
@ -70,74 +70,181 @@ get_blend_value(const PartBundle *root) {
|
|||||||
} else {
|
} else {
|
||||||
// A blend of two or more values.
|
// A blend of two or more values.
|
||||||
|
|
||||||
if (root->get_blend_type() == PartBundle::BT_linear) {
|
switch (root->get_blend_type()) {
|
||||||
// An ordinary, linear blend.
|
case PartBundle::BT_single:
|
||||||
_value = 0.0f;
|
// This one shouldn't be possible.
|
||||||
float net = 0.0f;
|
nassertv(false);
|
||||||
|
|
||||||
PartBundle::ChannelBlend::const_iterator cbi;
|
case PartBundle::BT_linear:
|
||||||
for (cbi = blend.begin(); cbi != blend.end(); ++cbi) {
|
{
|
||||||
AnimControl *control = (*cbi).first;
|
// An ordinary, linear blend.
|
||||||
float effect = (*cbi).second;
|
_value = 0.0f;
|
||||||
nassertv(effect != 0.0f);
|
float net = 0.0f;
|
||||||
|
|
||||||
int channel_index = control->get_channel_index();
|
PartBundle::ChannelBlend::const_iterator cbi;
|
||||||
nassertv(channel_index >= 0 && channel_index < (int)_channels.size());
|
for (cbi = blend.begin(); cbi != blend.end(); ++cbi) {
|
||||||
ChannelType *channel = DCAST(ChannelType, _channels[channel_index]);
|
AnimControl *control = (*cbi).first;
|
||||||
nassertv(channel != NULL);
|
float effect = (*cbi).second;
|
||||||
|
nassertv(effect != 0.0f);
|
||||||
ValueType v;
|
|
||||||
channel->get_value(control->get_frame(), v);
|
int channel_index = control->get_channel_index();
|
||||||
|
nassertv(channel_index >= 0 && channel_index < (int)_channels.size());
|
||||||
_value += v * effect;
|
ChannelType *channel = DCAST(ChannelType, _channels[channel_index]);
|
||||||
net += effect;
|
nassertv(channel != NULL);
|
||||||
|
|
||||||
|
ValueType v;
|
||||||
|
channel->get_value(control->get_frame(), v);
|
||||||
|
|
||||||
|
_value += v * effect;
|
||||||
|
net += effect;
|
||||||
|
}
|
||||||
|
|
||||||
|
nassertv(net != 0.0f);
|
||||||
|
_value /= net;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
nassertv(net != 0.0f);
|
case PartBundle::BT_normalized_linear:
|
||||||
_value /= net;
|
{
|
||||||
|
// A normalized linear blend. This means we do a linear blend
|
||||||
} else if (root->get_blend_type() == PartBundle::BT_normalized_linear) {
|
// without scales or shears, normalize the scale and shear
|
||||||
// A normalized linear blend. This means we do a linear blend
|
// components of the resulting matrix to eliminate
|
||||||
// without scales, normalize the scale components of the
|
// artificially-introduced scales, and then reapply the
|
||||||
// resulting matrix to eliminate artificially-introduced scales,
|
// scales and shears.
|
||||||
// and then reapply the scales.
|
|
||||||
|
_value = 0.0f;
|
||||||
// Perhaps we should treat shear the same as a scale here?
|
LVecBase3f scale(0.0f, 0.0f, 0.0f);
|
||||||
|
LVecBase3f shear(0.0f, 0.0f, 0.0f);
|
||||||
_value = 0.0f;
|
float net = 0.0f;
|
||||||
LVector3f scale(0.0f, 0.0f, 0.0f);
|
|
||||||
float net = 0.0f;
|
PartBundle::ChannelBlend::const_iterator cbi;
|
||||||
|
for (cbi = blend.begin(); cbi != blend.end(); ++cbi) {
|
||||||
PartBundle::ChannelBlend::const_iterator cbi;
|
AnimControl *control = (*cbi).first;
|
||||||
for (cbi = blend.begin(); cbi != blend.end(); ++cbi) {
|
float effect = (*cbi).second;
|
||||||
AnimControl *control = (*cbi).first;
|
nassertv(effect != 0.0f);
|
||||||
float effect = (*cbi).second;
|
|
||||||
nassertv(effect != 0.0f);
|
int channel_index = control->get_channel_index();
|
||||||
|
nassertv(channel_index >= 0 && channel_index < (int)_channels.size());
|
||||||
int channel_index = control->get_channel_index();
|
ChannelType *channel = DCAST(ChannelType, _channels[channel_index]);
|
||||||
nassertv(channel_index >= 0 && channel_index < (int)_channels.size());
|
nassertv(channel != NULL);
|
||||||
ChannelType *channel = DCAST(ChannelType, _channels[channel_index]);
|
|
||||||
nassertv(channel != NULL);
|
ValueType v;
|
||||||
|
channel->get_value_no_scale_shear(control->get_frame(), v);
|
||||||
ValueType v;
|
LVecBase3f iscale, ishear;
|
||||||
channel->get_value_no_scale(control->get_frame(), v);
|
channel->get_scale(control->get_frame(), iscale);
|
||||||
LVector3f s;
|
channel->get_shear(control->get_frame(), ishear);
|
||||||
channel->get_scale(control->get_frame(), &s[0]);
|
|
||||||
|
_value += v * effect;
|
||||||
_value += v * effect;
|
scale += iscale * effect;
|
||||||
scale += s * effect;
|
shear += ishear * effect;
|
||||||
net += effect;
|
net += effect;
|
||||||
|
}
|
||||||
|
|
||||||
|
nassertv(net != 0.0f);
|
||||||
|
_value /= net;
|
||||||
|
scale /= net;
|
||||||
|
shear /= net;
|
||||||
|
|
||||||
|
// Now rebuild the matrix with the correct scale values.
|
||||||
|
|
||||||
|
LVector3f false_scale, false_shear, hpr, translate;
|
||||||
|
decompose_matrix(_value, false_scale, false_shear, hpr, translate);
|
||||||
|
compose_matrix(_value, scale, shear, hpr, translate);
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
nassertv(net != 0.0f);
|
case PartBundle::BT_componentwise:
|
||||||
_value /= net;
|
{
|
||||||
scale /= net;
|
// Componentwise linear, including componentwise H, P, and R.
|
||||||
|
LVecBase3f scale(0.0f, 0.0f, 0.0f);
|
||||||
|
LVecBase3f hpr(0.0f, 0.0f, 0.0f);
|
||||||
|
LVecBase3f pos(0.0f, 0.0f, 0.0f);
|
||||||
|
LVecBase3f shear(0.0f, 0.0f, 0.0f);
|
||||||
|
float net = 0.0f;
|
||||||
|
|
||||||
|
PartBundle::ChannelBlend::const_iterator cbi;
|
||||||
|
for (cbi = blend.begin(); cbi != blend.end(); ++cbi) {
|
||||||
|
AnimControl *control = (*cbi).first;
|
||||||
|
float effect = (*cbi).second;
|
||||||
|
nassertv(effect != 0.0f);
|
||||||
|
|
||||||
|
int channel_index = control->get_channel_index();
|
||||||
|
nassertv(channel_index >= 0 && channel_index < (int)_channels.size());
|
||||||
|
ChannelType *channel = DCAST(ChannelType, _channels[channel_index]);
|
||||||
|
nassertv(channel != NULL);
|
||||||
|
|
||||||
|
LVecBase3f iscale, ihpr, ipos, ishear;
|
||||||
|
channel->get_scale(control->get_frame(), iscale);
|
||||||
|
channel->get_hpr(control->get_frame(), ihpr);
|
||||||
|
channel->get_pos(control->get_frame(), ipos);
|
||||||
|
channel->get_shear(control->get_frame(), ishear);
|
||||||
|
|
||||||
|
scale += iscale * effect;
|
||||||
|
hpr += ihpr * effect;
|
||||||
|
pos += ipos * effect;
|
||||||
|
shear += ishear * effect;
|
||||||
|
net += effect;
|
||||||
|
}
|
||||||
|
|
||||||
|
nassertv(net != 0.0f);
|
||||||
|
scale /= net;
|
||||||
|
hpr /= net;
|
||||||
|
pos /= net;
|
||||||
|
shear /= net;
|
||||||
|
|
||||||
|
compose_matrix(_value, scale, shear, hpr, pos);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
// Now rebuild the matrix with the correct scale values.
|
case PartBundle::BT_componentwise_quat:
|
||||||
|
{
|
||||||
|
// Componentwise linear, except for rotation, which is a
|
||||||
|
// quaternion.
|
||||||
|
LVecBase3f scale(0.0f, 0.0f, 0.0f);
|
||||||
|
LQuaternionf quat(0.0f, 0.0f, 0.0f, 0.0f);
|
||||||
|
LVecBase3f pos(0.0f, 0.0f, 0.0f);
|
||||||
|
LVecBase3f shear(0.0f, 0.0f, 0.0f);
|
||||||
|
float net = 0.0f;
|
||||||
|
|
||||||
|
PartBundle::ChannelBlend::const_iterator cbi;
|
||||||
|
for (cbi = blend.begin(); cbi != blend.end(); ++cbi) {
|
||||||
|
AnimControl *control = (*cbi).first;
|
||||||
|
float effect = (*cbi).second;
|
||||||
|
nassertv(effect != 0.0f);
|
||||||
|
|
||||||
|
int channel_index = control->get_channel_index();
|
||||||
|
nassertv(channel_index >= 0 && channel_index < (int)_channels.size());
|
||||||
|
ChannelType *channel = DCAST(ChannelType, _channels[channel_index]);
|
||||||
|
nassertv(channel != NULL);
|
||||||
|
|
||||||
|
LVecBase3f iscale, ipos, ishear;
|
||||||
|
LQuaternionf iquat;
|
||||||
|
channel->get_scale(control->get_frame(), iscale);
|
||||||
|
channel->get_quat(control->get_frame(), iquat);
|
||||||
|
channel->get_pos(control->get_frame(), ipos);
|
||||||
|
channel->get_shear(control->get_frame(), ishear);
|
||||||
|
|
||||||
|
scale += iscale * effect;
|
||||||
|
quat += iquat * effect;
|
||||||
|
pos += ipos * effect;
|
||||||
|
shear += ishear * effect;
|
||||||
|
net += effect;
|
||||||
|
}
|
||||||
|
|
||||||
|
nassertv(net != 0.0f);
|
||||||
|
scale /= net;
|
||||||
|
quat /= net;
|
||||||
|
pos /= net;
|
||||||
|
shear /= net;
|
||||||
|
|
||||||
LVector3f false_scale, shear, hpr, translate;
|
// There should be no need to normalize the quaternion,
|
||||||
decompose_matrix(_value, false_scale, shear, hpr, translate);
|
// assuming all of the input quaternions were already
|
||||||
compose_matrix(_value, scale, shear, hpr, translate);
|
// normalized.
|
||||||
|
|
||||||
|
_value = LMatrix4f::scale_shear_mat(scale, shear) * quat;
|
||||||
|
_value.set_row(3, pos);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include "movingPart.h"
|
#include "movingPart.h"
|
||||||
#include "animChannel.h"
|
#include "animChannel.h"
|
||||||
#include "animChannelFixed.h"
|
#include "animChannelFixed.h"
|
||||||
|
#include "cmath.h"
|
||||||
|
|
||||||
EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, MovingPart<ACMatrixSwitchType>);
|
EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, MovingPart<ACMatrixSwitchType>);
|
||||||
|
|
||||||
|
@ -82,13 +82,22 @@ PUBLISHED:
|
|||||||
BT_linear,
|
BT_linear,
|
||||||
|
|
||||||
// BT_normalized_linear is a compromise on BT_linear. The matrix
|
// BT_normalized_linear is a compromise on BT_linear. The matrix
|
||||||
// is blended linearly without the scale component, and the
|
// is blended linearly without the scale and shear components, and
|
||||||
// blended scale component is applied separately. This keeps all
|
// the blended scale and shear components are applied separately.
|
||||||
// of the character's body parts in the correct size and shape.
|
// This keeps all of the character's body parts in the correct
|
||||||
// However, if the hierarchy is disconnected, body parts can fly
|
// size and shape. However, if the hierarchy is disconnected,
|
||||||
// off. It's essential the skeleton hierarchy be completely
|
// body parts can fly off. It's essential the skeleton hierarchy
|
||||||
// connected to use this blend mode successully.
|
// be completely connected to use this blend mode successully.
|
||||||
BT_normalized_linear,
|
BT_normalized_linear,
|
||||||
|
|
||||||
|
// BT_componentwise linearly blends all components separately,
|
||||||
|
// including H, P, and R, and recomposes the matrix.
|
||||||
|
BT_componentwise,
|
||||||
|
|
||||||
|
// BT_componentwise_quat linearly blends all components
|
||||||
|
// separately, except for rotation which is blended as a
|
||||||
|
// quaternion.
|
||||||
|
BT_componentwise_quat,
|
||||||
};
|
};
|
||||||
|
|
||||||
void set_blend_type(BlendType bt);
|
void set_blend_type(BlendType bt);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user