bone original pose

This commit is contained in:
yangxiao 2014-06-19 12:01:03 +08:00
parent 9eaff7465d
commit 4db0bea73f
5 changed files with 88 additions and 60 deletions

View File

@ -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)

View File

@ -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"];

View File

@ -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;
}

View File

@ -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);
}
////////////////////////////////////////////////////////////////////////

View File

@ -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;
};