a functional cleanup

This commit is contained in:
Julien Valentin 2017-09-01 01:43:00 +02:00
parent 5aa96727e9
commit dee9dc2164
3 changed files with 68 additions and 60 deletions

View File

@ -145,7 +145,7 @@ struct MyRigTransformHardware : public osgAnimation::RigTransformHardware
ss << "boneWeight" << i; ss << "boneWeight" << i;
program->addBindAttribLocation(ss.str(), attribIndex + i); program->addBindAttribLocation(ss.str(), attribIndex + i);
if(getVertexAttrib(i)->getNumElements()!=_nbVertexes) if(getVertexAttrib(i)->getNumElements()!=_nbVertices)
OSG_WARN << "getVertexAttrib== " << getVertexAttrib(i)->getNumElements() << std::endl; OSG_WARN << "getVertexAttrib== " << getVertexAttrib(i)->getNumElements() << std::endl;
rig.setVertexAttribArray(attribIndex + i, getVertexAttrib(i)); rig.setVertexAttribArray(attribIndex + i, getVertexAttrib(i));
OSG_INFO << "set vertex attrib " << ss.str() << std::endl; OSG_INFO << "set vertex attrib " << ss.str() << std::endl;

View File

@ -54,7 +54,7 @@ namespace osgAnimation
unsigned int getNumVertexAttrib() const {return _boneWeightAttribArrays.size();} unsigned int getNumVertexAttrib() const {return _boneWeightAttribArrays.size();}
const unsigned int &getNumBonesPerVertex() const{ return _bonesPerVertex; } const unsigned int &getNumBonesPerVertex() const{ return _bonesPerVertex; }
const unsigned int &getNumVertexes() const { return _nbVertexes; } const unsigned int &getNumVertexes() const { return _nbVertices; }
const BoneNamePaletteIndex& getBoneNameToPalette(){ return _boneNameToPalette; } const BoneNamePaletteIndex& getBoneNameToPalette(){ return _boneNameToPalette; }
const BonePalette& getBonePalette() { return _bonePalette; } const BonePalette& getBonePalette() { return _bonePalette; }
@ -71,7 +71,7 @@ namespace osgAnimation
protected: protected:
unsigned int _bonesPerVertex; unsigned int _bonesPerVertex;
unsigned int _nbVertexes; unsigned int _nbVertices;
BonePalette _bonePalette; BonePalette _bonePalette;
BoneNamePaletteIndex _boneNameToPalette; BoneNamePaletteIndex _boneNameToPalette;

View File

@ -24,7 +24,7 @@ using namespace osgAnimation;
RigTransformHardware::RigTransformHardware(): RigTransformHardware::RigTransformHardware():
_bonesPerVertex (0), _bonesPerVertex (0),
_nbVertexes (0), _nbVertices (0),
_needInit (true), _needInit (true),
_minAttribIndex(DEFAULT_FIRST_VERTATTRIB_TARGETTED) _minAttribIndex(DEFAULT_FIRST_VERTATTRIB_TARGETTED)
{} {}
@ -32,7 +32,7 @@ RigTransformHardware::RigTransformHardware():
RigTransformHardware::RigTransformHardware(const RigTransformHardware& rth, const osg::CopyOp& copyop): RigTransformHardware::RigTransformHardware(const RigTransformHardware& rth, const osg::CopyOp& copyop):
RigTransform(rth, copyop), RigTransform(rth, copyop),
_bonesPerVertex(rth._bonesPerVertex), _bonesPerVertex(rth._bonesPerVertex),
_nbVertexes(rth._nbVertexes), _nbVertices(rth._nbVertices),
_bonePalette(rth._bonePalette), _bonePalette(rth._bonePalette),
_boneNameToPalette(rth._boneNameToPalette), _boneNameToPalette(rth._boneNameToPalette),
_boneWeightAttribArrays(rth._boneWeightAttribArrays), _boneWeightAttribArrays(rth._boneWeightAttribArrays),
@ -74,46 +74,75 @@ void RigTransformHardware::computeMatrixPaletteUniform(const osg::Matrix& transf
// //
typedef std::vector<std::vector<VertexIndexWeight> > PerVertexInfList; typedef std::vector<std::vector<VertexIndexWeight> > PerVertexInfList;
void createVertexAttribList(const RigTransformHardware& rig,
const PerVertexInfList & perVertexInfluences, ///create normalized a set of Vertex Attribs given a PerVertexInfList and return the max num bone per vertex
RigTransformHardware::BoneWeightAttribList& boneWeightAttribArrays) unsigned int createVertexAttribList(const PerVertexInfList & perVertexInfluences,
{ RigTransformHardware::BoneWeightAttribList& boneWeightAttribArrays){
unsigned int nbVertices = rig.getNumVertexes(); short boneIndexInVec4;
unsigned int maxbonepervertex = rig.getNumBonesPerVertex(); unsigned int vertid = 0,
unsigned int nbArray = static_cast<unsigned int>(ceilf( ((float)maxbonepervertex) * 0.5f)); boneIndexInList;
IndexWeightList::size_type maxBonePerVertex = 0;
///build vertex attrib arrays
//get maxBonePerVertex
for(PerVertexInfList::const_iterator vertinfit = perVertexInfluences.begin(); vertinfit != perVertexInfluences.end(); ++vertinfit)
maxBonePerVertex = osg::maximum(maxBonePerVertex, vertinfit->size());
OSG_INFO << "RigTransformHardware::createVertexAttribList maximum number of bone per vertex is " << maxBonePerVertex << std::endl;
unsigned int nbArray = static_cast<unsigned int>(ceilf( ((float)maxBonePerVertex) * 0.5f));
if (!nbArray) if (!nbArray)
return ; return 0;
///create vertex attrib arrays
boneWeightAttribArrays.resize(nbArray); boneWeightAttribArrays.resize(nbArray);
for (unsigned int i = 0; i < nbArray; i++) for(unsigned int j=0; j< nbArray; ++j)
{ {
osg::ref_ptr<osg::Vec4Array> array = new osg::Vec4Array(osg::Array::BIND_PER_VERTEX); boneWeightAttribArrays[j] = new osg::Vec4Array(osg::Array::BIND_PER_VERTEX);
boneWeightAttribArrays[i] = array; boneWeightAttribArrays[j]->resize(perVertexInfluences.size());
array->resize( nbVertices); }
for (unsigned int j = 0; j < nbVertices; j++)
///populate vertex attrib arrays
for(PerVertexInfList::const_iterator vertinfit=perVertexInfluences.begin(); vertinfit != perVertexInfluences.end(); ++vertinfit,++vertid)
{
//sum for normalization
float sum=0;
for(IndexWeightList::const_iterator iwit = vertinfit->begin(); iwit != vertinfit->end(); ++iwit)
sum+=iwit->second;
if(sum< 1e-4)
{ {
for (unsigned int b = 0; b < 2; b++) OSG_WARN << "RigTransformHardware::buildPalette Warning: vertex with zero sum weights: " <<vertid<< std::endl;
return false;
}
else
{
sum=1.0f/sum;
for (unsigned int j = 0; j < nbArray; ++j)
{ {
// the granularity is 2 so if we have only one bone osg::Vec4& dest=(* boneWeightAttribArrays[j])[vertid];
// it's convenient to init the second with a weight 0 for (unsigned int b = 0; b < 2; ++b)
unsigned int boneIndexInList = i*2 + b;
unsigned int boneIndexInVec4 = b*2;
if (boneIndexInList < perVertexInfluences[j].size())
{ {
float boneIndex = static_cast<float>(perVertexInfluences[j][boneIndexInList].getIndex()); boneIndexInVec4 = b*2;
float boneWeight = perVertexInfluences[j][boneIndexInList].getWeight(); boneIndexInList = j*2 + b;
// fill the vec4 if (boneIndexInList < (*vertinfit).size())
(*array)[j][0 + boneIndexInVec4] = boneIndex; {
(*array)[j][1 + boneIndexInVec4] = boneWeight; float boneIndex = static_cast<float>((*vertinfit)[boneIndexInList].getIndex());
}else{ ///normalization here
(*array)[j][0 + boneIndexInVec4] = 0; float boneWeight = (*vertinfit)[boneIndexInList].getWeight()*sum;
(*array)[j][1 + boneIndexInVec4] = 0; dest[0 + boneIndexInVec4] = boneIndex;
dest[1 + boneIndexInVec4] = boneWeight;
}
else
{
dest[0 + boneIndexInVec4] = 0;
dest[1 + boneIndexInVec4] = 0;
}
} }
} }
} }
} }
return; return maxBonePerVertex;
} }
bool RigTransformHardware::prepareData(RigGeometry& rig) bool RigTransformHardware::prepareData(RigGeometry& rig)
@ -155,11 +184,12 @@ bool RigTransformHardware::prepareData(RigGeometry& rig)
return true; return true;
} }
bool RigTransformHardware::buildPalette(const BoneMap&boneMap,const RigGeometry&rig) bool RigTransformHardware::buildPalette(const BoneMap&boneMap,const RigGeometry&rig)
{ {
typedef std::map<std::string, int> BoneNameCountMap; typedef std::map<std::string, int> BoneNameCountMap;
_nbVertexes = rig.getVertexArray()->getNumElements(); _nbVertices = rig.getVertexArray()->getNumElements();
_boneWeightAttribArrays.resize(0); _boneWeightAttribArrays.resize(0);
_bonePalette.clear(); _bonePalette.clear();
_boneNameToPalette.clear(); _boneNameToPalette.clear();
@ -172,7 +202,7 @@ bool RigTransformHardware::buildPalette(const BoneMap&boneMap,const RigGeometry&
// init temp vertex attribute data // init temp vertex attribute data
std::vector<IndexWeightList > perVertexInfluences; std::vector<IndexWeightList > perVertexInfluences;
perVertexInfluences.resize(_nbVertexes); perVertexInfluences.resize(_nbVertices);
unsigned int paletteindex; unsigned int paletteindex;
for (VertexInfluenceMap::const_iterator boneinflistit = vertexInfluenceMap.begin(); for (VertexInfluenceMap::const_iterator boneinflistit = vertexInfluenceMap.begin();
@ -205,7 +235,7 @@ bool RigTransformHardware::buildPalette(const BoneMap&boneMap,const RigGeometry&
const VertexIndexWeight& iw = *infit; const VertexIndexWeight& iw = *infit;
const unsigned int &index = iw.getIndex(); const unsigned int &index = iw.getIndex();
const float &weight = iw.getWeight(); const float &weight = iw.getWeight();
IndexWeightList & iwlist=perVertexInfluences[index]; IndexWeightList & iwlist = perVertexInfluences[index];
if(fabs(weight) > 1e-4) // don't use bone with weight too small if(fabs(weight) > 1e-4) // don't use bone with weight too small
{ {
@ -228,34 +258,12 @@ bool RigTransformHardware::buildPalette(const BoneMap&boneMap,const RigGeometry&
} }
///normalize and get maxBonePerVertex
unsigned int vertid=0;
for(PerVertexInfList::iterator vertinfit=perVertexInfluences.begin(); vertinfit != perVertexInfluences.end(); ++vertinfit,++vertid)
{
maxBonePerVertex = osg::maximum(maxBonePerVertex, vertinfit->size());
float sum=0;
for(IndexWeightList::iterator iwit = vertinfit->begin(); iwit != vertinfit->end(); ++iwit)
sum+=iwit->second;
if(sum< 1e-4) if( (_bonesPerVertex = createVertexAttribList(perVertexInfluences, _boneWeightAttribArrays) ) < 1 )
{ return false;
OSG_WARN << "RigTransformHardware::buildPalette Warning: vertex with zero sum weights: " <<vertid<< std::endl;
}
else
{
sum=1.0f/sum;
for(IndexWeightList::iterator iwit=vertinfit->begin(); iwit!=vertinfit->end(); ++iwit)
iwit->second*=sum;
}
}
OSG_INFO << "RigTransformHardware::buildPalette maximum number of bone per vertex is " << maxBonePerVertex << std::endl;
_uniformMatrixPalette = new osg::Uniform(osg::Uniform::FLOAT_MAT4, "matrixPalette", _bonePalette.size()); _uniformMatrixPalette = new osg::Uniform(osg::Uniform::FLOAT_MAT4, "matrixPalette", _bonePalette.size());
_bonesPerVertex = maxBonePerVertex;
createVertexAttribList(*this,perVertexInfluences,this->_boneWeightAttribArrays);
_needInit = true; _needInit = true;
return true; return true;