mirror of https://github.com/axmolengine/axmol.git
two animate3d the same time
This commit is contained in:
parent
247734e2e0
commit
ff6ef1140d
|
@ -101,7 +101,8 @@ void Animate3D::update(float t)
|
||||||
{
|
{
|
||||||
if (_target)
|
if (_target)
|
||||||
{
|
{
|
||||||
float dst[4];
|
float transDst[3], rotDst[4], scaleDst[3];
|
||||||
|
float* trans = nullptr, *rot = nullptr, *scale = nullptr;
|
||||||
if (_playBack)
|
if (_playBack)
|
||||||
t = 1 - t;
|
t = 1 - t;
|
||||||
|
|
||||||
|
@ -110,19 +111,20 @@ void Animate3D::update(float t)
|
||||||
auto curve = it.second;
|
auto curve = it.second;
|
||||||
if (curve->translateCurve)
|
if (curve->translateCurve)
|
||||||
{
|
{
|
||||||
curve->translateCurve->evaluate(t, dst, Linear);
|
curve->translateCurve->evaluate(t, transDst, Linear);
|
||||||
bone->setAnimationValueTranslation(dst);
|
trans = &transDst[0];
|
||||||
}
|
}
|
||||||
if (curve->rotCurve)
|
if (curve->rotCurve)
|
||||||
{
|
{
|
||||||
curve->rotCurve->evaluate(t, dst, QuatSlerp);
|
curve->rotCurve->evaluate(t, rotDst, QuatSlerp);
|
||||||
bone->setAnimationValueRotation(dst);
|
rot = &rotDst[0];
|
||||||
}
|
}
|
||||||
if (curve->scaleCurve)
|
if (curve->scaleCurve)
|
||||||
{
|
{
|
||||||
curve->scaleCurve->evaluate(t, dst, Linear);
|
curve->scaleCurve->evaluate(t, scaleDst, Linear);
|
||||||
bone->setAnimationValueScale(dst);
|
scale = &scaleDst[0];
|
||||||
}
|
}
|
||||||
|
bone->setAnimationValue(trans, rot, scale, _weight);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,6 +132,7 @@ void Animate3D::update(float t)
|
||||||
|
|
||||||
Animate3D::Animate3D()
|
Animate3D::Animate3D()
|
||||||
: _speed(1)
|
: _speed(1)
|
||||||
|
, _weight(1.f)
|
||||||
, _animation(nullptr)
|
, _animation(nullptr)
|
||||||
, _playBack(false)
|
, _playBack(false)
|
||||||
{
|
{
|
||||||
|
|
|
@ -70,6 +70,7 @@ protected:
|
||||||
Animation3D* _animation;
|
Animation3D* _animation;
|
||||||
|
|
||||||
float _speed;
|
float _speed;
|
||||||
|
float _weight;
|
||||||
bool _playBack;
|
bool _playBack;
|
||||||
std::map<Bone*, Animation3D::Curve*> _boneCurves; //weak ref
|
std::map<Bone*, Animation3D::Curve*> _boneCurves; //weak ref
|
||||||
};
|
};
|
||||||
|
|
|
@ -159,6 +159,10 @@ bool Bundle3D::loadAnimationData(const std::string& id, Animation3DData* animati
|
||||||
Quaternion::createFromAxisAngle(Vec3(1.f, 0.f, 0.f), MATH_DEG_TO_RAD(270), &quat);
|
Quaternion::createFromAxisAngle(Vec3(1.f, 0.f, 0.f), MATH_DEG_TO_RAD(270), &quat);
|
||||||
animationdata->_rotationKeys[boneName].push_back(Animation3DData::QuatKey(keytime1[3], quat));
|
animationdata->_rotationKeys[boneName].push_back(Animation3DData::QuatKey(keytime1[3], quat));
|
||||||
|
|
||||||
|
animationdata->_translationKeys[boneName].push_back(Animation3DData::Vec3Key(keytime1[0], Vec3(0.0f, 0.0f, 0.0f)));
|
||||||
|
animationdata->_translationKeys[boneName].push_back(Animation3DData::Vec3Key(keytime1[1], Vec3(0.0f, 20.0f, 0.0f)));
|
||||||
|
animationdata->_translationKeys[boneName].push_back(Animation3DData::Vec3Key(keytime1[2], Vec3(20.0f, 0.0f, 0.0f)));
|
||||||
|
animationdata->_translationKeys[boneName].push_back(Animation3DData::Vec3Key(keytime1[3], Vec3(0.0f, 0.0f, 20.0f)));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,35 +84,49 @@ const Mat4& Bone::getWorldMat()
|
||||||
return _world;
|
return _world;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
///**
|
||||||
* Set AnimationValue. set to its transform
|
// * Set AnimationValue. set to its transform
|
||||||
*/
|
// */
|
||||||
void Bone::setAnimationValueTranslation(float* value, float weight)
|
//void Bone::setAnimationValueTranslation(float* value, float weight)
|
||||||
|
//{
|
||||||
|
// static const int bytes = 3 * sizeof(float);
|
||||||
|
// if (memcmp(&_localTranslate.x, value, bytes) != 0)
|
||||||
|
// {
|
||||||
|
// _dirtyFlag |= Dirty_Translate;
|
||||||
|
// _localTranslate.set(value);
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
//void Bone::setAnimationValueRotation(float* value, float weight)
|
||||||
|
//{
|
||||||
|
// static const int bytes = 4 * sizeof(float);
|
||||||
|
// if (memcmp(&_localRot.x, value, bytes) != 0)
|
||||||
|
// {
|
||||||
|
// _dirtyFlag |= Dirty_Rotation;
|
||||||
|
// _localRot.set(value);
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
//void Bone::setAnimationValueScale(float* value, float weight)
|
||||||
|
//{
|
||||||
|
// static const int bytes = 3 * sizeof(float);
|
||||||
|
// if (memcmp(&_localScale.x, value, bytes) != 0)
|
||||||
|
// {
|
||||||
|
// _dirtyFlag |= Dirty_Scale;
|
||||||
|
// _localScale.set(value);
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
void Bone::setAnimationValue(float* trans, float* rot, float* scale, float weight)
|
||||||
{
|
{
|
||||||
static const int bytes = 3 * sizeof(float);
|
BoneBlendState state;
|
||||||
if (memcmp(&_localTranslate.x, value, bytes) != 0)
|
if (trans)
|
||||||
{
|
state.localTranslate.set(trans);
|
||||||
_dirtyFlag |= Dirty_Translate;
|
if (rot)
|
||||||
_localTranslate.set(value);
|
state.localRot.set(rot);
|
||||||
}
|
if (scale)
|
||||||
}
|
state.localScale.set(scale);
|
||||||
void Bone::setAnimationValueRotation(float* value, float weight)
|
state.weight = weight;
|
||||||
{
|
|
||||||
static const int bytes = 4 * sizeof(float);
|
_blendStates.push_back(state);
|
||||||
if (memcmp(&_localRot.x, value, bytes) != 0)
|
|
||||||
{
|
|
||||||
_dirtyFlag |= Dirty_Rotation;
|
|
||||||
_localRot.set(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void Bone::setAnimationValueScale(float* value, float weight)
|
|
||||||
{
|
|
||||||
static const int bytes = 3 * sizeof(float);
|
|
||||||
if (memcmp(&_localScale.x, value, bytes) != 0)
|
|
||||||
{
|
|
||||||
_dirtyFlag |= Dirty_Scale;
|
|
||||||
_localScale.set(value);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -199,25 +213,97 @@ Bone::~Bone()
|
||||||
|
|
||||||
void Bone::updateLocalMat()
|
void Bone::updateLocalMat()
|
||||||
{
|
{
|
||||||
if (_dirtyFlag & Dirty_Translate)
|
// if (_dirtyFlag & Dirty_Translate)
|
||||||
|
// {
|
||||||
|
// Mat4::createTranslation(_localTranslate, &_local);
|
||||||
|
// if (_dirtyFlag & Dirty_Rotation)
|
||||||
|
// _local.rotate(_localRot);
|
||||||
|
// if (_dirtyFlag & Dirty_Scale)
|
||||||
|
// _local.scale(_localScale);
|
||||||
|
// }
|
||||||
|
// else if (_dirtyFlag & Dirty_Rotation)
|
||||||
|
// {
|
||||||
|
// Mat4::createRotation(_localRot, &_local);
|
||||||
|
// if (_dirtyFlag & Dirty_Scale)
|
||||||
|
// _local.scale(_localScale);
|
||||||
|
// }
|
||||||
|
// else if (_dirtyFlag & Dirty_Scale)
|
||||||
|
// {
|
||||||
|
// Mat4::createScale(_localScale, &_local);
|
||||||
|
// }
|
||||||
|
// _dirtyFlag = 0;
|
||||||
|
|
||||||
|
Vec3 translate(0.f, 0.f, 0.f), scale(0.f, 0.f, 0.f);
|
||||||
|
Quaternion quat(0.f, 0.f, 0.f, 0.f);
|
||||||
|
if (_blendStates.size())
|
||||||
{
|
{
|
||||||
Mat4::createTranslation(_localTranslate, &_local);
|
|
||||||
if (_dirtyFlag & Dirty_Rotation)
|
|
||||||
_local.rotate(_localRot);
|
float total = 0.f;
|
||||||
if (_dirtyFlag & Dirty_Scale)
|
for (auto it: _blendStates) {
|
||||||
_local.scale(_localScale);
|
total += it.weight;
|
||||||
}
|
}
|
||||||
else if (_dirtyFlag & Dirty_Rotation)
|
if (total)
|
||||||
{
|
{
|
||||||
Mat4::createRotation(_localRot, &_local);
|
if (_blendStates.size() == 1)
|
||||||
if (_dirtyFlag & Dirty_Scale)
|
|
||||||
_local.scale(_localScale);
|
|
||||||
}
|
|
||||||
else if (_dirtyFlag & Dirty_Scale)
|
|
||||||
{
|
{
|
||||||
Mat4::createScale(_localScale, &_local);
|
translate = _blendStates[0].localTranslate;
|
||||||
|
scale = _blendStates[0].localScale;
|
||||||
|
quat = _blendStates[0].localRot;
|
||||||
}
|
}
|
||||||
_dirtyFlag = 0;
|
else
|
||||||
|
{
|
||||||
|
float invTotal = 1.f / total;
|
||||||
|
for (auto it : _blendStates) {
|
||||||
|
float weight = (it.weight * invTotal);
|
||||||
|
translate += it.localTranslate * weight;
|
||||||
|
if (!it.localScale.isZero())
|
||||||
|
{
|
||||||
|
scale.x *= it.localScale.x * weight;
|
||||||
|
scale.y *= it.localScale.y * weight;
|
||||||
|
scale.z *= it.localScale.z * weight;
|
||||||
|
}
|
||||||
|
if (!it.localRot.isZero())
|
||||||
|
{
|
||||||
|
if (!quat.isZero())
|
||||||
|
{
|
||||||
|
Quaternion& q = _blendStates[0].localRot;
|
||||||
|
if (q.x * quat.x + q.y * quat.y + q.z * quat.z + q.w * quat.w < 0)
|
||||||
|
weight = -weight;
|
||||||
|
}
|
||||||
|
quat = Quaternion(it.localRot.x * weight + quat.x, it.localRot.y * weight + quat.y, it.localRot.z * weight + quat.z, it.localRot.w * weight + quat.w);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool hasTrans = !translate.isZero();
|
||||||
|
bool hasRot = !quat.isZero();
|
||||||
|
bool hasScale = !scale.isZero();
|
||||||
|
|
||||||
|
if (hasTrans)
|
||||||
|
{
|
||||||
|
Mat4::createTranslation(translate, &_local);
|
||||||
|
if (hasRot)
|
||||||
|
_local.rotate(quat);
|
||||||
|
if (hasScale)
|
||||||
|
_local.scale(scale);
|
||||||
|
}
|
||||||
|
else if (hasRot)
|
||||||
|
{
|
||||||
|
Mat4::createRotation(quat, &_local);
|
||||||
|
if (hasScale)
|
||||||
|
_local.scale(scale);
|
||||||
|
}
|
||||||
|
else if (hasScale)
|
||||||
|
{
|
||||||
|
Mat4::createScale(scale, &_local);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
_local.setIdentity();
|
||||||
|
|
||||||
|
_blendStates.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Bone::clearBlendState()
|
void Bone::clearBlendState()
|
||||||
|
@ -269,7 +355,7 @@ MeshSkin* MeshSkin::create(const std::string& filename, const std::string& name)
|
||||||
{
|
{
|
||||||
auto skin = new MeshSkin();
|
auto skin = new MeshSkin();
|
||||||
skin->_bindShape = skindata.bindShape;
|
skin->_bindShape = skindata.bindShape;
|
||||||
skin->setBoneCount(skindata.boneNames.size());
|
skin->setBoneCount((int)skindata.boneNames.size());
|
||||||
for (size_t i = 0; i < skindata.boneNames.size(); i++) {
|
for (size_t i = 0; i < skindata.boneNames.size(); i++) {
|
||||||
auto bone = Bone::create(skindata.boneNames[i]);
|
auto bone = Bone::create(skindata.boneNames[i]);
|
||||||
bone->_bindPose = skindata.inverseBindPoseMatrices[i];
|
bone->_bindPose = skindata.inverseBindPoseMatrices[i];
|
||||||
|
|
|
@ -59,12 +59,14 @@ public:
|
||||||
|
|
||||||
const std::string& getName() const { return _name; }
|
const std::string& getName() const { return _name; }
|
||||||
|
|
||||||
/**
|
// /**
|
||||||
* Set AnimationValue. set to its transform
|
// * Set AnimationValue. set to its transform
|
||||||
*/
|
// */
|
||||||
void setAnimationValueTranslation(float* value, float weight = 1.0f);
|
// void setAnimationValueTranslation(float* value, float weight = 1.0f);
|
||||||
void setAnimationValueRotation(float* value, float weight = 1.0f);
|
// void setAnimationValueRotation(float* value, float weight = 1.0f);
|
||||||
void setAnimationValueScale(float* value, float weight = 1.0f);
|
// void setAnimationValueScale(float* value, float weight = 1.0f);
|
||||||
|
|
||||||
|
void setAnimationValue(float* trans, float* rot, float* scale, float weight = 1.0f);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates C3DBone.
|
* Creates C3DBone.
|
||||||
|
@ -135,16 +137,6 @@ protected:
|
||||||
*/
|
*/
|
||||||
Mat4 _bindPose;
|
Mat4 _bindPose;
|
||||||
|
|
||||||
// /**
|
|
||||||
// * Flag used to mark if the Joint's matrix is dirty.
|
|
||||||
// */
|
|
||||||
// bool _jointMatrixDirty;
|
|
||||||
//
|
|
||||||
// /**
|
|
||||||
// * The number of MeshSkin's influencing the Joint.
|
|
||||||
// */
|
|
||||||
// unsigned int _skinCount;
|
|
||||||
|
|
||||||
Bone* _parent;
|
Bone* _parent;
|
||||||
|
|
||||||
Vector<Bone*> _children;
|
Vector<Bone*> _children;
|
||||||
|
@ -155,9 +147,7 @@ protected:
|
||||||
Mat4 _local;
|
Mat4 _local;
|
||||||
|
|
||||||
std::vector<BoneBlendState> _blendStates;
|
std::vector<BoneBlendState> _blendStates;
|
||||||
Vec3 _localTranslate;
|
|
||||||
Quaternion _localRot;
|
|
||||||
Vec3 _localScale;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
Loading…
Reference in New Issue