mirror of https://github.com/axmolengine/axmol.git
bone original pose
This commit is contained in:
parent
9eaff7465d
commit
4db0bea73f
|
@ -77,7 +77,7 @@ void Animate3D::startWithTarget(Node *target)
|
|||
|
||||
_boneCurves.clear();
|
||||
auto skin = sprite->getSkin();
|
||||
for (unsigned int i = 0; i < skin->getBoneCount(); i++) {
|
||||
for (unsigned int i = 0; i < skin->getSkinBoneCount(); i++) {
|
||||
auto bone = skin->getBoneByIndex(i);
|
||||
auto curve = _animation->getBoneCurveByName(bone->getName());
|
||||
if (curve)
|
||||
|
|
|
@ -187,7 +187,7 @@ bool Bundle3D::loadSkinData(const std::string& id, SkinData* skindata)
|
|||
{
|
||||
const rapidjson::Value& skin_data_bone = skin_data_bones[i];
|
||||
std::string name = skin_data_bone["node"].GetString();
|
||||
skindata->boneNames.push_back(name);
|
||||
skindata->skinBoneNames.push_back(name);
|
||||
|
||||
Mat4 mat_bind_pos;
|
||||
const rapidjson::Value& bind_pos = skin_data_bone["bindshape"];
|
||||
|
|
|
@ -80,29 +80,40 @@ public:
|
|||
|
||||
struct SkinData
|
||||
{
|
||||
std::vector<std::string> boneNames;
|
||||
std::vector<Mat4> inverseBindPoseMatrices; //bind pose of bone
|
||||
std::vector<Mat4> boneOriginMatrices; // original bone transform
|
||||
std::vector<std::string> skinBoneNames; //skin bones affect skin
|
||||
std::vector<std::string> nodeBoneNames; //node bones don't affect skin, all bones [skinBone, nodeBone]
|
||||
std::vector<Mat4> inverseBindPoseMatrices; //bind pose of skin bone, only for skin bone
|
||||
std::vector<Mat4> skinBoneOriginMatrices; // original bone transform, for skin bone
|
||||
std::vector<Mat4> nodeBoneOriginMatrices; // original bone transform, for node bone
|
||||
|
||||
//bone child info, both skinbone and node bone
|
||||
std::map<int, std::vector<int> > boneChild;//key parent, value child
|
||||
int rootBoneIndex;
|
||||
void resetData()
|
||||
{
|
||||
boneNames.clear();
|
||||
skinBoneNames.clear();
|
||||
nodeBoneNames.clear();
|
||||
inverseBindPoseMatrices.clear();
|
||||
skinBoneOriginMatrices.clear();
|
||||
nodeBoneOriginMatrices.clear();
|
||||
boneChild.clear();
|
||||
rootBoneIndex = -1;
|
||||
}
|
||||
|
||||
int getBoneNameIndex(const std::string& name)const
|
||||
{
|
||||
std::vector<std::string>::const_iterator iter = boneNames.begin();
|
||||
for (int i = 0; iter != boneNames.end(); ++iter, ++i)
|
||||
int i = 0;
|
||||
for (auto iter : skinBoneNames)
|
||||
{
|
||||
if ((*iter) == name)
|
||||
{
|
||||
if ((iter) == name)
|
||||
return i;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
for(auto iter : nodeBoneNames)
|
||||
{
|
||||
if (iter == name)
|
||||
return i;
|
||||
i++;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -301,11 +301,17 @@ MeshSkin* MeshSkin::create(const std::string& filename, const std::string& name)
|
|||
|
||||
bool MeshSkin::initFromSkinData(const SkinData& skindata)
|
||||
{
|
||||
setBoneCount((int)skindata.boneNames.size());
|
||||
for (size_t i = 0; i < skindata.boneNames.size(); i++) {
|
||||
auto bone = Bone::create(skindata.boneNames[i]);
|
||||
ssize_t i = 0;
|
||||
for (; i < skindata.skinBoneNames.size(); i++) {
|
||||
auto bone = Bone::create(skindata.skinBoneNames[i]);
|
||||
bone->_invBindPose = skindata.inverseBindPoseMatrices[i];
|
||||
addBone(bone);
|
||||
//bone->setOriPose(skindata.skinBoneOriginMatrices[i]);
|
||||
addSkinBone(bone);
|
||||
}
|
||||
for (i = 0; i < skindata.nodeBoneNames.size(); i++) {
|
||||
auto bone = Bone::create(skindata.nodeBoneNames[i]);
|
||||
//bone->setOriPose(skindata.nodeBoneOriginMatrices[i]);
|
||||
addNodeBone(bone);
|
||||
}
|
||||
for (auto it : skindata.boneChild) {
|
||||
auto parent = getBoneByIndex(it.first);
|
||||
|
@ -317,22 +323,36 @@ bool MeshSkin::initFromSkinData(const SkinData& skindata)
|
|||
}
|
||||
|
||||
setRootBone(getBoneByIndex(skindata.rootBoneIndex));
|
||||
_rootBone->resetPose();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned int MeshSkin::getBoneCount() const
|
||||
ssize_t MeshSkin::getSkinBoneCount() const
|
||||
{
|
||||
return _bones.size();
|
||||
return _skinBones.size();
|
||||
}
|
||||
|
||||
//get bone
|
||||
Bone* MeshSkin::getBoneByIndex(unsigned int index) const
|
||||
{
|
||||
return _bones.at(index);
|
||||
if (index < _skinBones.size())
|
||||
return _skinBones.at(index);
|
||||
index -= _skinBones.size();
|
||||
if (index < _nodeBones.size())
|
||||
return _nodeBones.at(index);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
Bone* MeshSkin::getBoneByName(const std::string& id) const
|
||||
{
|
||||
for (auto it : _bones) {
|
||||
//search from skin bones
|
||||
for (auto it : _skinBones) {
|
||||
if (it->getName() == id)
|
||||
return it;
|
||||
}
|
||||
//search from node bones
|
||||
for (auto it : _nodeBones) {
|
||||
if (it->getName() == id )
|
||||
return it;
|
||||
}
|
||||
|
@ -350,32 +370,16 @@ void MeshSkin::setRootBone(Bone* joint)
|
|||
_rootBone = joint;
|
||||
}
|
||||
|
||||
void MeshSkin::setBoneCount(int boneCount)
|
||||
int MeshSkin::getBoneIndex(Bone* bone) const
|
||||
{
|
||||
removeAllBones();
|
||||
|
||||
// Resize the joints vector and initialize to NULL
|
||||
_bones.reserve(boneCount);
|
||||
|
||||
// Rebuild the matrix palette. Each matrix is 3 rows of Vec4.
|
||||
CC_SAFE_DELETE_ARRAY(_matrixPalette);
|
||||
|
||||
if (boneCount > 0)
|
||||
{
|
||||
_matrixPalette = new Vec4[boneCount * PALETTE_ROWS];
|
||||
for (unsigned int i = 0; i < boneCount * PALETTE_ROWS; i+=PALETTE_ROWS)
|
||||
{
|
||||
_matrixPalette[i+0].set(1.0f, 0.0f, 0.0f, 0.0f);
|
||||
_matrixPalette[i+1].set(0.0f, 1.0f, 0.0f, 0.0f);
|
||||
_matrixPalette[i+2].set(0.0f, 0.0f, 1.0f, 0.0f);
|
||||
}
|
||||
int i = 0;
|
||||
for (; i < _skinBones.size(); i++) {
|
||||
if (_skinBones.at(i) == bone)
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
int MeshSkin::getBoneIndex(Bone* joint) const
|
||||
{
|
||||
for (auto i = 0; i < _bones.size(); i++) {
|
||||
if (_bones.at(i) == joint)
|
||||
int index = 0;
|
||||
for (; index < _nodeBones.size(); index++, i++) {
|
||||
if (_nodeBones.at(index) == bone)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
|
@ -386,8 +390,12 @@ Vec4* MeshSkin::getMatrixPalette()
|
|||
{
|
||||
updateBoneMatrix();
|
||||
|
||||
if (_matrixPalette == nullptr)
|
||||
{
|
||||
_matrixPalette = new Vec4[_skinBones.size() * PALETTE_ROWS];
|
||||
}
|
||||
int i = 0;
|
||||
for (auto it : _bones )
|
||||
for (auto it : _skinBones )
|
||||
{
|
||||
it->updateJointMatrix(&_matrixPalette[i++ * PALETTE_ROWS]);
|
||||
}
|
||||
|
@ -395,10 +403,9 @@ Vec4* MeshSkin::getMatrixPalette()
|
|||
return _matrixPalette;
|
||||
}
|
||||
|
||||
//getBoneCount() * 3
|
||||
unsigned int MeshSkin::getMatrixPaletteSize() const
|
||||
ssize_t MeshSkin::getMatrixPaletteSize() const
|
||||
{
|
||||
return _bones.size() * PALETTE_ROWS;
|
||||
return _skinBones.size() * PALETTE_ROWS;
|
||||
}
|
||||
|
||||
//refresh bone world matrix
|
||||
|
@ -410,14 +417,20 @@ void MeshSkin::updateBoneMatrix()
|
|||
|
||||
void MeshSkin::removeAllBones()
|
||||
{
|
||||
_bones.clear();
|
||||
_skinBones.clear();
|
||||
_nodeBones.clear();
|
||||
CC_SAFE_DELETE_ARRAY(_matrixPalette);
|
||||
CC_SAFE_RELEASE(_rootBone);
|
||||
}
|
||||
|
||||
void MeshSkin::addBone(Bone* bone)
|
||||
void MeshSkin::addSkinBone(Bone* bone)
|
||||
{
|
||||
_bones.pushBack(bone);
|
||||
_skinBones.pushBack(bone);
|
||||
}
|
||||
|
||||
void MeshSkin::addNodeBone(Bone* bone)
|
||||
{
|
||||
_nodeBones.pushBack(bone);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -159,6 +159,8 @@ protected:
|
|||
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
class MeshSkin: public Ref
|
||||
{
|
||||
|
@ -167,9 +169,7 @@ public:
|
|||
//create a new meshskin if do not want to share meshskin
|
||||
static MeshSkin* create(const std::string& filename, const std::string& name);
|
||||
|
||||
unsigned int getBoneCount() const;
|
||||
|
||||
void setBoneCount(int boneCount);
|
||||
ssize_t getSkinBoneCount() const;
|
||||
|
||||
//get bone
|
||||
Bone* getBoneByIndex(unsigned int index) const;
|
||||
|
@ -177,15 +177,15 @@ public:
|
|||
|
||||
//get & set root bone
|
||||
Bone* getRootBone() const;
|
||||
void setRootBone(Bone* joint);
|
||||
void setRootBone(Bone* bone);
|
||||
|
||||
int getBoneIndex(Bone* joint) const;
|
||||
int getBoneIndex(Bone* bone) const;
|
||||
|
||||
//compute matrix palette used by gpu skin
|
||||
Vec4* getMatrixPalette();
|
||||
|
||||
//getBoneCount() * 3
|
||||
unsigned int getMatrixPaletteSize() const;
|
||||
//getSkinBoneCount() * 3
|
||||
ssize_t getMatrixPaletteSize() const;
|
||||
|
||||
//refresh bone world matrix
|
||||
void updateBoneMatrix();
|
||||
|
@ -200,17 +200,21 @@ CC_CONSTRUCTOR_ACCESS:
|
|||
|
||||
void removeAllBones();
|
||||
|
||||
void addBone(Bone* bone);
|
||||
void addSkinBone(Bone* bone);
|
||||
|
||||
void addNodeBone(Bone* bone);
|
||||
|
||||
protected:
|
||||
|
||||
Vector<Bone*> _bones;
|
||||
Vector<Bone*> _skinBones; // bones with skin
|
||||
Vector<Bone*> _nodeBones; //bones without skin, only used to compute transform of children
|
||||
|
||||
Bone* _rootBone;
|
||||
|
||||
// Pointer to the array of palette matrices.
|
||||
// This array is passed to the vertex shader as a uniform.
|
||||
// Each 4x3 row-wise matrix is represented as 3 Vec4's.
|
||||
// The number of Vec4's is (_joints.size() * 3).
|
||||
// The number of Vec4's is (_skinBones.size() * 3).
|
||||
Vec4* _matrixPalette;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue