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
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimChannel::get_value_no_scale
|
||||
// Function: AnimChannel::get_value_no_scale_share
|
||||
// Access: Public, Virtual
|
||||
// Description: Returns the value associated with the current frame,
|
||||
// with no scale components. This only makes sense for
|
||||
// a matrix-type channel, although for fiddly technical
|
||||
// reasons the function exists for all channels.
|
||||
// with no scale or share components. This only makes
|
||||
// sense for a matrix-type channel, although for fiddly
|
||||
// technical reasons the function exists for all
|
||||
// channels.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class 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);
|
||||
}
|
||||
|
||||
@ -104,10 +105,60 @@ get_value_no_scale(int frame, ValueType &value) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class SwitchType>
|
||||
void AnimChannel<SwitchType>::
|
||||
get_scale(int, float scale[3]) {
|
||||
scale[0] = 1.0f;
|
||||
scale[1] = 1.0f;
|
||||
scale[2] = 1.0f;
|
||||
get_scale(int, LVecBase3f &scale) {
|
||||
nassertv(false);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// 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:
|
||||
virtual void get_value(int frame, ValueType &value)=0;
|
||||
|
||||
// These two functions only have meaning for matrix types.
|
||||
virtual void get_value_no_scale(int frame, ValueType &value);
|
||||
virtual void get_scale(int frame, float scale[3]);
|
||||
// The second parameter above should really by LVector3f instead of
|
||||
// float[3], but there seems to be a compiler bug in EGCS that
|
||||
// doesn't like that. So we have this kludge for now.
|
||||
// These transform-component methods only have meaning for matrix types.
|
||||
virtual void get_value_no_scale_shear(int frame, ValueType &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);
|
||||
|
||||
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
|
||||
// Description: Gets the value of the channel at the indicated frame,
|
||||
// without any scale information.
|
||||
// without any scale or shear information.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void AnimChannelMatrixDynamic::
|
||||
get_value_no_scale(int frame, LMatrix4f &mat) {
|
||||
if (_value->has_scale()) {
|
||||
get_value_no_scale_shear(int frame, LMatrix4f &mat) {
|
||||
if (_value->has_scale() || _value->has_shear()) {
|
||||
compose_matrix(mat, LVecBase3f(1.0f, 1.0f, 1.0f),
|
||||
_value->get_hpr(), _value->get_pos());
|
||||
} else {
|
||||
@ -101,11 +101,56 @@ get_value_no_scale(int frame, LMatrix4f &mat) {
|
||||
// Description: Gets the scale value at the indicated frame.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void AnimChannelMatrixDynamic::
|
||||
get_scale(int frame, float scale[3]) {
|
||||
const LVecBase3f &sc = _value->get_scale();
|
||||
scale[0] = sc[0];
|
||||
scale[1] = sc[1];
|
||||
scale[2] = sc[2];
|
||||
get_scale(int frame, LVecBase3f &scale) {
|
||||
scale = _value->get_scale();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// 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:
|
||||
virtual bool has_changed(int last_frame, int this_frame);
|
||||
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:
|
||||
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
|
||||
// Description: Gets the value of the channel at the indicated frame,
|
||||
// without any scale information.
|
||||
// without any scale or shear information.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void AnimChannelMatrixXfmTable::
|
||||
get_value_no_scale(int frame, LMatrix4f &mat) {
|
||||
get_value_no_scale_shear(int frame, LMatrix4f &mat) {
|
||||
float components[num_matrix_components];
|
||||
components[0] = 1.0f;
|
||||
components[1] = 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()) {
|
||||
components[i] = get_default_value(i);
|
||||
} else {
|
||||
@ -135,23 +138,99 @@ get_value_no_scale(int frame, LMatrix4f &mat) {
|
||||
// Description: Gets the scale value at the indicated frame.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void AnimChannelMatrixXfmTable::
|
||||
get_scale(int frame, float scale[3]) {
|
||||
get_scale(int frame, LVecBase3f &scale) {
|
||||
for (int i = 0; i < 3; i++) {
|
||||
if (_tables[i].empty()) {
|
||||
scale[i] = get_default_value(i);
|
||||
scale[i] = 1.0f;
|
||||
} else {
|
||||
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
|
||||
// Access: Public
|
||||
// Description: Assigns the indicated table. table_id is one of 'i',
|
||||
// 'j', 'k', for scale, 'h', 'p', 'r', for rotation, and
|
||||
// 'x', 'y', 'z', for translation. The new table must
|
||||
// have either zero, one, or get_num_frames() frames.
|
||||
// 'j', 'k', for scale, 'a', 'b', 'c' for shear, 'h',
|
||||
// 'p', 'r', for rotation, and 'x', 'y', 'z', for
|
||||
// translation. The new table must have either zero,
|
||||
// one, or get_num_frames() frames.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void AnimChannelMatrixXfmTable::
|
||||
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 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);
|
||||
|
||||
|
@ -70,7 +70,13 @@ get_blend_value(const PartBundle *root) {
|
||||
} else {
|
||||
// A blend of two or more values.
|
||||
|
||||
if (root->get_blend_type() == PartBundle::BT_linear) {
|
||||
switch (root->get_blend_type()) {
|
||||
case PartBundle::BT_single:
|
||||
// This one shouldn't be possible.
|
||||
nassertv(false);
|
||||
|
||||
case PartBundle::BT_linear:
|
||||
{
|
||||
// An ordinary, linear blend.
|
||||
_value = 0.0f;
|
||||
float net = 0.0f;
|
||||
@ -95,17 +101,20 @@ get_blend_value(const PartBundle *root) {
|
||||
|
||||
nassertv(net != 0.0f);
|
||||
_value /= net;
|
||||
}
|
||||
break;
|
||||
|
||||
} else if (root->get_blend_type() == PartBundle::BT_normalized_linear) {
|
||||
case PartBundle::BT_normalized_linear:
|
||||
{
|
||||
// A normalized linear blend. This means we do a linear blend
|
||||
// without scales, normalize the scale components of the
|
||||
// resulting matrix to eliminate artificially-introduced scales,
|
||||
// and then reapply the scales.
|
||||
|
||||
// Perhaps we should treat shear the same as a scale here?
|
||||
// without scales or shears, normalize the scale and shear
|
||||
// components of the resulting matrix to eliminate
|
||||
// artificially-introduced scales, and then reapply the
|
||||
// scales and shears.
|
||||
|
||||
_value = 0.0f;
|
||||
LVector3f scale(0.0f, 0.0f, 0.0f);
|
||||
LVecBase3f scale(0.0f, 0.0f, 0.0f);
|
||||
LVecBase3f shear(0.0f, 0.0f, 0.0f);
|
||||
float net = 0.0f;
|
||||
|
||||
PartBundle::ChannelBlend::const_iterator cbi;
|
||||
@ -120,25 +129,123 @@ get_blend_value(const PartBundle *root) {
|
||||
nassertv(channel != NULL);
|
||||
|
||||
ValueType v;
|
||||
channel->get_value_no_scale(control->get_frame(), v);
|
||||
LVector3f s;
|
||||
channel->get_scale(control->get_frame(), &s[0]);
|
||||
channel->get_value_no_scale_shear(control->get_frame(), v);
|
||||
LVecBase3f iscale, ishear;
|
||||
channel->get_scale(control->get_frame(), iscale);
|
||||
channel->get_shear(control->get_frame(), ishear);
|
||||
|
||||
_value += v * effect;
|
||||
scale += s * effect;
|
||||
scale += iscale * effect;
|
||||
shear += ishear * 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, shear, hpr, translate;
|
||||
decompose_matrix(_value, false_scale, shear, hpr, translate);
|
||||
LVector3f false_scale, false_shear, hpr, translate;
|
||||
decompose_matrix(_value, false_scale, false_shear, hpr, translate);
|
||||
compose_matrix(_value, scale, shear, hpr, translate);
|
||||
}
|
||||
break;
|
||||
|
||||
case PartBundle::BT_componentwise:
|
||||
{
|
||||
// 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;
|
||||
|
||||
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;
|
||||
|
||||
// There should be no need to normalize the quaternion,
|
||||
// assuming all of the input quaternions were already
|
||||
// normalized.
|
||||
|
||||
_value = LMatrix4f::scale_shear_mat(scale, shear) * quat;
|
||||
_value.set_row(3, pos);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "movingPart.h"
|
||||
#include "animChannel.h"
|
||||
#include "animChannelFixed.h"
|
||||
#include "cmath.h"
|
||||
|
||||
EXPORT_TEMPLATE_CLASS(EXPCL_PANDA, EXPTP_PANDA, MovingPart<ACMatrixSwitchType>);
|
||||
|
||||
|
@ -82,13 +82,22 @@ PUBLISHED:
|
||||
BT_linear,
|
||||
|
||||
// BT_normalized_linear is a compromise on BT_linear. The matrix
|
||||
// is blended linearly without the scale component, and the
|
||||
// blended scale component is applied separately. This keeps all
|
||||
// of the character's body parts in the correct size and shape.
|
||||
// However, if the hierarchy is disconnected, body parts can fly
|
||||
// off. It's essential the skeleton hierarchy be completely
|
||||
// connected to use this blend mode successully.
|
||||
// is blended linearly without the scale and shear components, and
|
||||
// the blended scale and shear components are applied separately.
|
||||
// This keeps all of the character's body parts in the correct
|
||||
// size and shape. However, if the hierarchy is disconnected,
|
||||
// body parts can fly off. It's essential the skeleton hierarchy
|
||||
// be completely connected to use this blend mode successully.
|
||||
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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user