@@ -145,7 +145,7 @@ struct MyRigTransformHardware : public osgAnimation::RigTransformHardware
|
||||
ss << "boneWeight" << 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;
|
||||
rig.setVertexAttribArray(attribIndex + i, getVertexAttrib(i));
|
||||
OSG_INFO << "set vertex attrib " << ss.str() << std::endl;
|
||||
|
||||
@@ -54,7 +54,7 @@ namespace osgAnimation
|
||||
unsigned int getNumVertexAttrib() const {return _boneWeightAttribArrays.size();}
|
||||
|
||||
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 BonePalette& getBonePalette() { return _bonePalette; }
|
||||
@@ -65,13 +65,13 @@ namespace osgAnimation
|
||||
// update rig if needed
|
||||
virtual void operator()(RigGeometry&);
|
||||
|
||||
// init animations data
|
||||
// init/reset animations data
|
||||
virtual bool prepareData(RigGeometry& );
|
||||
|
||||
protected:
|
||||
|
||||
unsigned int _bonesPerVertex;
|
||||
unsigned int _nbVertexes;
|
||||
unsigned int _nbVertices;
|
||||
|
||||
BonePalette _bonePalette;
|
||||
BoneNamePaletteIndex _boneNameToPalette;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/* -*-c++-*-
|
||||
* Copyright (C) 2008 Cedric Pinson <cedric.pinson@plopbyte.net>
|
||||
* Copyright (C) 2017 Julien Valentin <mp3butcher@hotmail.com>
|
||||
*
|
||||
* This library is open source and may be redistributed and/or modified under
|
||||
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
||||
@@ -24,26 +25,14 @@
|
||||
namespace osgAnimation
|
||||
{
|
||||
// first is bonename, and second the weight
|
||||
struct BoneWeight: public std::pair<std::string, float>
|
||||
{
|
||||
BoneWeight( std::string f,float s):
|
||||
std::pair<std::string,float>(f,s){}
|
||||
inline const std::string& getBoneName()const{return first;}
|
||||
inline void setBoneName(const std::string&s){first=s;}
|
||||
inline const float &getWeight()const{return second;}
|
||||
inline void setWeight(float i){second=i;}
|
||||
};
|
||||
typedef std::pair<std::string, float> BoneWeight;
|
||||
// first is vertex index, and second the weight
|
||||
struct VertexIndexWeight: public std::pair<unsigned int, float>
|
||||
{
|
||||
VertexIndexWeight( unsigned int f = 0xffffffff,float s = 0.0f): std::pair<unsigned int,float>(f,s){}
|
||||
inline const unsigned int& getIndex()const{return first;}
|
||||
inline void setIndex(unsigned int i){first=i;}
|
||||
inline const float &getWeight()const{return second;}
|
||||
inline void setWeight(float i){second=i;}
|
||||
};
|
||||
typedef std::pair<unsigned int, float> VertexIndexWeight;
|
||||
// list of IndexWeight
|
||||
typedef std::vector<VertexIndexWeight> IndexWeightList;
|
||||
// list of IndexWeight
|
||||
typedef std::vector<BoneWeight> BoneWeightList;
|
||||
// list of Index
|
||||
typedef std::vector<unsigned int> IndexList;
|
||||
|
||||
//Bone influence list
|
||||
|
||||
@@ -23,7 +23,9 @@
|
||||
|
||||
using namespace osgAnimation;
|
||||
|
||||
MorphTransformHardware::MorphTransformHardware():_needInit(true),_reservedTextureUnit(DEFAULTMORPHTEXTUREUNIT)
|
||||
MorphTransformHardware::MorphTransformHardware():
|
||||
_needInit(true),
|
||||
_reservedTextureUnit(DEFAULTMORPHTEXTUREUNIT)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -47,22 +49,22 @@ bool MorphTransformHardware::init(MorphGeometry& morphGeometry)
|
||||
///(blender osgexport doesn't set sources so assume morphgeom arrays are sources)
|
||||
if(pos)
|
||||
{
|
||||
pos->setDataVariance(osg::Object::STATIC);
|
||||
///check if source is setted correctly
|
||||
if (!vertexSource|| vertexSource->size() != pos->size())
|
||||
{
|
||||
vertexSource =(static_cast<osg::Vec3Array*>( pos->clone(osg::CopyOp::DEEP_COPY_ARRAYS)));//osg::Vec3Array(pos->begin(),pos->end());
|
||||
pos->setDataVariance(osg::Object::DYNAMIC);
|
||||
vertexSource =(static_cast<osg::Vec3Array*>( pos->clone(osg::CopyOp::DEEP_COPY_ARRAYS)));
|
||||
}
|
||||
osg::Vec3Array* normal = dynamic_cast<osg::Vec3Array*>(morphGeometry.getNormalArray());
|
||||
bool normalmorphable = morphGeometry.getMorphNormals() && normal;
|
||||
bool normalmorphable = morphGeometry.getMorphNormals() && normal&&(normal->getBinding()==osg::Array::BIND_PER_VERTEX);
|
||||
if(!normalmorphable) {
|
||||
OSG_WARN << "MorphTransformHardware::morph geometry "<<morphGeometry.getName()<<" without normal morphing not supported! " << std::endl;
|
||||
OSG_WARN << "MorphTransformHardware::morph geometry "<<morphGeometry.getName()<<" without per vertex normal : HWmorphing not supported! " << std::endl;
|
||||
return false;
|
||||
}
|
||||
normal->setDataVariance(osg::Object::STATIC);
|
||||
if (normalmorphable && (!normalSource || normalSource->size() != normal->size()))
|
||||
{
|
||||
normalSource =(static_cast<osg::Vec3Array*>( normal->clone(osg::CopyOp::DEEP_COPY_ARRAYS)));//osg::Vec3Array(normal->begin(),normal->end());
|
||||
normal->setDataVariance(osg::Object::DYNAMIC);
|
||||
normalSource =(static_cast<osg::Vec3Array*>( normal->clone(osg::CopyOp::DEEP_COPY_ARRAYS)));
|
||||
}
|
||||
}
|
||||
///end check
|
||||
@@ -98,7 +100,7 @@ bool MorphTransformHardware::init(MorphGeometry& morphGeometry)
|
||||
|
||||
//create TBO Texture handle
|
||||
osg::Uniform * morphTBOHandle=new osg::Uniform(osg::Uniform::SAMPLER_BUFFER,"morphTargets");
|
||||
morphTBOHandle->set(_reservedTextureUnit);
|
||||
morphTBOHandle->set((int)_reservedTextureUnit);
|
||||
|
||||
//create dynamic uniform for morphtargets animation weights
|
||||
_uniformTargetsWeight=new osg::Uniform(osg::Uniform::FLOAT,"morphWeights",morphlist.size());
|
||||
@@ -139,7 +141,6 @@ bool MorphTransformHardware::init(MorphGeometry& morphGeometry)
|
||||
std::size_t start = str.find(toreplace);
|
||||
if (std::string::npos == start){
|
||||
///perhaps remanance from previous init (if saved after init) so reload shader
|
||||
|
||||
vertexshader = osg::Shader::readShaderFile(osg::Shader::VERTEX,"morphing.vert");
|
||||
if (!vertexshader.valid()) {
|
||||
OSG_WARN << "RigTransformHardware can't load VertexShader" << std::endl;
|
||||
|
||||
@@ -23,7 +23,6 @@ using namespace osgAnimation;
|
||||
|
||||
bool MorphTransformSoftware::init(MorphGeometry& morphGeometry){
|
||||
|
||||
|
||||
morphGeometry.setDataVariance(osg::Object::DYNAMIC);
|
||||
osg::Vec3Array* pos = dynamic_cast<osg::Vec3Array*>(morphGeometry.getVertexArray());
|
||||
osg::Vec3Array * vertexSource = (morphGeometry.getVertexSource());
|
||||
|
||||
@@ -21,17 +21,18 @@
|
||||
using namespace osgAnimation;
|
||||
|
||||
#define DEFAULT_FIRST_VERTATTRIB_TARGETTED 11
|
||||
|
||||
RigTransformHardware::RigTransformHardware():
|
||||
_bonesPerVertex (0),
|
||||
_nbVertexes (0),
|
||||
_nbVertices (0),
|
||||
_needInit (true),
|
||||
_minAttribIndex(DEFAULT_FIRST_VERTATTRIB_TARGETTED)
|
||||
{}
|
||||
{}
|
||||
|
||||
RigTransformHardware::RigTransformHardware(const RigTransformHardware& rth, const osg::CopyOp& copyop):
|
||||
RigTransform(rth, copyop),
|
||||
_bonesPerVertex(rth._bonesPerVertex),
|
||||
_nbVertexes(rth._nbVertexes),
|
||||
_nbVertices(rth._nbVertices),
|
||||
_bonePalette(rth._bonePalette),
|
||||
_boneNameToPalette(rth._boneNameToPalette),
|
||||
_boneWeightAttribArrays(rth._boneWeightAttribArrays),
|
||||
@@ -51,7 +52,7 @@ osg::Vec4Array* RigTransformHardware::getVertexAttrib(unsigned int index)
|
||||
|
||||
void RigTransformHardware::computeMatrixPaletteUniform(const osg::Matrix& transformFromSkeletonToGeometry, const osg::Matrix& invTransformFromSkeletonToGeometry)
|
||||
{
|
||||
for (unsigned int i = 0; i < _bonePalette.size(); i++)
|
||||
for (unsigned int i = 0; i < _bonePalette.size(); ++i)
|
||||
{
|
||||
osg::ref_ptr<Bone> bone = _bonePalette[i].get();
|
||||
const osg::Matrixf& invBindMatrix = bone->getInvBindMatrixInSkeletonSpace();
|
||||
@@ -63,9 +64,6 @@ void RigTransformHardware::computeMatrixPaletteUniform(const osg::Matrix& transf
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void createVertexAttribList(RigTransformHardware& rig,const std::vector<std::vector<VertexIndexWeight> > &perVertexInfluences,RigTransformHardware::BoneWeightAttribList & boneWeightAttribArrays);
|
||||
|
||||
//
|
||||
// create vertex attribute by 2 bones
|
||||
// vec4(boneIndex0, weight0, boneIndex1, weight1)
|
||||
@@ -76,45 +74,75 @@ void createVertexAttribList(RigTransformHardware& rig,const std::vector<std::ve
|
||||
//
|
||||
|
||||
typedef std::vector<std::vector<VertexIndexWeight> > PerVertexInfList;
|
||||
void createVertexAttribList(RigTransformHardware& rig,
|
||||
const PerVertexInfList & perVertexInfluences,
|
||||
RigTransformHardware::BoneWeightAttribList& boneWeightAttribArrays)
|
||||
{
|
||||
unsigned int nbVertices= rig.getNumVertexes();
|
||||
unsigned int maxbonepervertex=rig.getNumBonesPerVertex();
|
||||
unsigned int nbArray = static_cast<unsigned int>(ceilf( ((float)maxbonepervertex) * 0.5f));
|
||||
|
||||
///create normalized a set of Vertex Attribs given a PerVertexInfList and return the max num bone per vertex
|
||||
unsigned int createVertexAttribList(const PerVertexInfList & perVertexInfluences,
|
||||
RigTransformHardware::BoneWeightAttribList& boneWeightAttribArrays){
|
||||
short boneIndexInVec4;
|
||||
unsigned int vertid = 0,
|
||||
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)
|
||||
return ;
|
||||
return 0;
|
||||
|
||||
///create vertex attrib arrays
|
||||
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[i] = array;
|
||||
array->resize( nbVertices);
|
||||
for (unsigned int j = 0; j < nbVertices; j++)
|
||||
boneWeightAttribArrays[j] = new osg::Vec4Array(osg::Array::BIND_PER_VERTEX);
|
||||
boneWeightAttribArrays[j]->resize(perVertexInfluences.size());
|
||||
}
|
||||
|
||||
///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
|
||||
// it's convenient to init the second with a weight 0
|
||||
unsigned int boneIndexInList = i*2 + b;
|
||||
unsigned int boneIndexInVec4 = b*2;
|
||||
(*array)[j][0 + boneIndexInVec4] = 0;
|
||||
(*array)[j][1 + boneIndexInVec4] = 0;
|
||||
if (boneIndexInList < perVertexInfluences[j].size())
|
||||
osg::Vec4& dest=(* boneWeightAttribArrays[j])[vertid];
|
||||
for (unsigned int b = 0; b < 2; ++b)
|
||||
{
|
||||
float boneIndex = static_cast<float>(perVertexInfluences[j][boneIndexInList].getIndex());
|
||||
float boneWeight = perVertexInfluences[j][boneIndexInList].getWeight();
|
||||
// fill the vec4
|
||||
(*array)[j][0 + boneIndexInVec4] = boneIndex;
|
||||
(*array)[j][1 + boneIndexInVec4] = boneWeight;
|
||||
boneIndexInVec4 = b*2;
|
||||
boneIndexInList = j*2 + b;
|
||||
if (boneIndexInList < (*vertinfit).size())
|
||||
{
|
||||
float boneIndex = static_cast<float>((*vertinfit)[boneIndexInList].first);
|
||||
///normalization here
|
||||
float boneWeight = (*vertinfit)[boneIndexInList].second*sum;
|
||||
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)
|
||||
@@ -133,6 +161,8 @@ bool RigTransformHardware::prepareData(RigGeometry& rig)
|
||||
}
|
||||
rig.setSkeleton(finder._root.get());
|
||||
}
|
||||
if(!rig.getSkeleton())
|
||||
return false;
|
||||
BoneMapVisitor mapVisitor;
|
||||
rig.getSkeleton()->accept(mapVisitor);
|
||||
BoneMap boneMap = mapVisitor.getBoneMap();
|
||||
@@ -154,10 +184,12 @@ bool RigTransformHardware::prepareData(RigGeometry& rig)
|
||||
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;
|
||||
_nbVertexes = rig.getVertexArray()->getNumElements();
|
||||
_nbVertices = rig.getVertexArray()->getNumElements();
|
||||
_boneWeightAttribArrays.resize(0);
|
||||
_bonePalette.clear();
|
||||
_boneNameToPalette.clear();
|
||||
@@ -165,22 +197,22 @@ bool RigTransformHardware::buildPalette(const BoneMap&boneMap ,const RigGeometry
|
||||
IndexWeightList::size_type maxBonePerVertex=0;
|
||||
BoneNameCountMap boneNameCountMap;
|
||||
|
||||
const VertexInfluenceMap &vertexInfluenceMap=*rig.getInfluenceMap();
|
||||
const VertexInfluenceMap &vertexInfluenceMap = *rig.getInfluenceMap();
|
||||
BoneNamePaletteIndex::iterator boneName2PaletteIndex;
|
||||
|
||||
// init temp vertex attribute data
|
||||
std::vector<IndexWeightList > perVertexInfluences;
|
||||
perVertexInfluences.resize(_nbVertexes);
|
||||
perVertexInfluences.resize(_nbVertices);
|
||||
|
||||
unsigned int paletteindex;
|
||||
for (osgAnimation::VertexInfluenceMap::const_iterator boneinflistit = vertexInfluenceMap.begin();
|
||||
for (VertexInfluenceMap::const_iterator boneinflistit = vertexInfluenceMap.begin();
|
||||
boneinflistit != vertexInfluenceMap.end();
|
||||
++boneinflistit)
|
||||
{
|
||||
const IndexWeightList& boneinflist = boneinflistit->second;
|
||||
const std::string& bonename = boneinflistit->first;
|
||||
BoneMap::const_iterator bonebyname;
|
||||
if ((bonebyname=boneMap.find(bonename)) == boneMap.end())
|
||||
if ((bonebyname = boneMap.find(bonename)) == boneMap.end())
|
||||
{
|
||||
OSG_WARN << "RigTransformHardware::buildPalette can't find bone " << bonename << "in skeleton bonemap: skip this influence" << std::endl;
|
||||
continue;
|
||||
@@ -201,9 +233,9 @@ bool RigTransformHardware::buildPalette(const BoneMap&boneMap ,const RigGeometry
|
||||
for(IndexWeightList::const_iterator infit = boneinflist.begin(); infit!=boneinflist.end(); ++infit)
|
||||
{
|
||||
const VertexIndexWeight& iw = *infit;
|
||||
const unsigned int &index = iw.getIndex();
|
||||
const float &weight = iw.getWeight();
|
||||
IndexWeightList & iwlist=perVertexInfluences[index];
|
||||
const unsigned int &index = iw.first;
|
||||
const float &weight = iw.second;
|
||||
IndexWeightList & iwlist = perVertexInfluences[index];
|
||||
|
||||
if(fabs(weight) > 1e-4) // don't use bone with weight too small
|
||||
{
|
||||
@@ -213,10 +245,8 @@ bool RigTransformHardware::buildPalette(const BoneMap&boneMap ,const RigGeometry
|
||||
{
|
||||
OSG_WARN << "RigTransformHardware::buildPalette Bone " << bonename << " has a weight " << weight << " for vertex " << index << " this bone will not be in the palette" << std::endl;
|
||||
}
|
||||
maxBonePerVertex = osg::maximum(maxBonePerVertex, iwlist.size());
|
||||
|
||||
}
|
||||
OSG_INFO << "RigTransformHardware::buildPalette maximum number of bone per vertex is " << maxBonePerVertex << std::endl;
|
||||
OSG_INFO << "RigTransformHardware::buildPalette matrix palette has " << boneNameCountMap.size() << " entries" << std::endl;
|
||||
|
||||
for (BoneNameCountMap::iterator it = boneNameCountMap.begin(); it != boneNameCountMap.end(); ++it)
|
||||
@@ -228,37 +258,22 @@ bool RigTransformHardware::buildPalette(const BoneMap&boneMap ,const RigGeometry
|
||||
|
||||
}
|
||||
|
||||
///normalize
|
||||
unsigned int vertid=0;
|
||||
for(PerVertexInfList::iterator vertinfit=perVertexInfluences.begin(); vertinfit != perVertexInfluences.end(); ++vertinfit,++vertid)
|
||||
{
|
||||
float sum=0;
|
||||
for(IndexWeightList::iterator iwit = vertinfit->begin(); iwit != vertinfit->end(); ++iwit)
|
||||
sum+=iwit->second;
|
||||
|
||||
if(sum< 1e-4){
|
||||
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;
|
||||
}
|
||||
}
|
||||
if( (_bonesPerVertex = createVertexAttribList(perVertexInfluences, _boneWeightAttribArrays) ) < 1 )
|
||||
return false;
|
||||
|
||||
_uniformMatrixPalette = new osg::Uniform(osg::Uniform::FLOAT_MAT4, "matrixPalette", _bonePalette.size());
|
||||
|
||||
_bonesPerVertex = maxBonePerVertex;
|
||||
_needInit = true;
|
||||
|
||||
createVertexAttribList(*this,perVertexInfluences,this->_boneWeightAttribArrays);
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RigTransformHardware::init(RigGeometry& rig){
|
||||
if(_bonesPerVertex>0){
|
||||
///data seams prepared
|
||||
bool RigTransformHardware::init(RigGeometry& rig)
|
||||
{
|
||||
//if animdata seams prepared
|
||||
if(_uniformMatrixPalette.valid())
|
||||
{
|
||||
osg::ref_ptr<osg::Program> program ;
|
||||
osg::ref_ptr<osg::Shader> vertexshader;
|
||||
osg::ref_ptr<osg::StateSet> stateset = rig.getOrCreateStateSet();
|
||||
@@ -267,24 +282,28 @@ bool RigTransformHardware::init(RigGeometry& rig){
|
||||
if(!_shader.valid() && (program = (osg::Program*)stateset->getAttribute(osg::StateAttribute::PROGRAM)))
|
||||
{
|
||||
for(unsigned int i=0; i<program->getNumShaders(); ++i)
|
||||
if(program->getShader(i)->getType()==osg::Shader::VERTEX) {
|
||||
if(program->getShader(i)->getType()==osg::Shader::VERTEX)
|
||||
{
|
||||
vertexshader=program->getShader(i);
|
||||
program->removeShader(vertexshader);
|
||||
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
program = new osg::Program;
|
||||
program->setName("HardwareSkinning");
|
||||
}
|
||||
//set default source if _shader is not user setted
|
||||
if (!vertexshader.valid()) {
|
||||
if (!vertexshader.valid())
|
||||
{
|
||||
if (!_shader.valid())
|
||||
vertexshader = osg::Shader::readShaderFile(osg::Shader::VERTEX,"skinning.vert");
|
||||
else vertexshader=_shader;
|
||||
}
|
||||
|
||||
|
||||
if (!vertexshader.valid()) {
|
||||
if (!vertexshader.valid())
|
||||
{
|
||||
OSG_WARN << "RigTransformHardware can't load VertexShader" << std::endl;
|
||||
return false;
|
||||
}
|
||||
@@ -294,7 +313,8 @@ bool RigTransformHardware::init(RigGeometry& rig){
|
||||
std::string str = vertexshader->getShaderSource();
|
||||
std::string toreplace = std::string("MAX_MATRIX");
|
||||
std::size_t start = str.find(toreplace);
|
||||
if (std::string::npos != start) {
|
||||
if (std::string::npos != start)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << getMatrixPaletteUniform()->getNumElements();
|
||||
str.replace(start, toreplace.size(), ss.str());
|
||||
@@ -302,28 +322,21 @@ bool RigTransformHardware::init(RigGeometry& rig){
|
||||
}
|
||||
else
|
||||
{
|
||||
OSG_INFO<< "MAX_MATRIX not found in Shader! " << str << std::endl;
|
||||
OSG_WARN<< "MAX_MATRIX not found in Shader! " << str << std::endl;
|
||||
}
|
||||
OSG_INFO << "Shader " << str << std::endl;
|
||||
}
|
||||
|
||||
unsigned int attribIndex = _minAttribIndex;
|
||||
unsigned int nbAttribs = getNumVertexAttrib();
|
||||
if(nbAttribs==0)
|
||||
OSG_WARN << "nbAttribs== " << nbAttribs << std::endl;
|
||||
for (unsigned int i = 0; i < nbAttribs; i++)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "boneWeight" << i;
|
||||
program->addBindAttribLocation(ss.str(), attribIndex + i);
|
||||
|
||||
if(getVertexAttrib(i)->getNumElements()!=_nbVertexes)
|
||||
OSG_WARN << "getVertexAttrib== " << getVertexAttrib(i)->getNumElements() << std::endl;
|
||||
rig.setVertexAttribArray(attribIndex + i, getVertexAttrib(i));
|
||||
program->addBindAttribLocation(ss.str(), _minAttribIndex + i);
|
||||
rig.setVertexAttribArray(_minAttribIndex + i, getVertexAttrib(i));
|
||||
OSG_INFO << "set vertex attrib " << ss.str() << std::endl;
|
||||
}
|
||||
|
||||
|
||||
program->addShader(vertexshader.get());
|
||||
|
||||
stateset->removeUniform("nbBonesPerVertex");
|
||||
@@ -332,12 +345,10 @@ bool RigTransformHardware::init(RigGeometry& rig){
|
||||
stateset->removeUniform("matrixPalette");
|
||||
stateset->addUniform(_uniformMatrixPalette);
|
||||
|
||||
stateset->removeAttribute(osg::StateAttribute::PROGRAM);
|
||||
if(!stateset->getAttribute(osg::StateAttribute::PROGRAM))
|
||||
stateset->setAttributeAndModes(program.get());
|
||||
stateset->setAttribute(program.get());
|
||||
|
||||
_needInit = false;
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
else prepareData(rig);
|
||||
return false;
|
||||
|
||||
@@ -68,8 +68,8 @@ void RigTransformSoftware::buildMinimumUpdateSet( const BoneMap&boneMap, const R
|
||||
for(IndexWeightList::const_iterator infit=inflist.begin(); infit!=inflist.end(); ++infit)
|
||||
{
|
||||
const VertexIndexWeight &iw = *infit;
|
||||
const unsigned int &index = iw.getIndex();
|
||||
float weight = iw.getWeight();
|
||||
const unsigned int &index = iw.first;
|
||||
float weight = iw.second;
|
||||
perVertexInfluences[index].push_back(BonePtrWeight(bone, weight));
|
||||
}
|
||||
}
|
||||
@@ -139,6 +139,8 @@ bool RigTransformSoftware::prepareData(RigGeometry&rig) {
|
||||
}
|
||||
rig.setSkeleton(finder._root.get());
|
||||
}
|
||||
if(!rig.getSkeleton())
|
||||
return false;
|
||||
///get bonemap from skeleton
|
||||
BoneMapVisitor mapVisitor;
|
||||
rig.getSkeleton()->accept(mapVisitor);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/* -*-c++-*-
|
||||
* Copyright (C) 2008 Cedric Pinson <cedric.pinson@plopbyte.net>
|
||||
* Copyright (C) 2017 Julien Valentin <mp3butcher@hotmail.com>
|
||||
*
|
||||
* This library is open source and may be redistributed and/or modified under
|
||||
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
||||
@@ -24,9 +25,9 @@ struct invweight_ordered
|
||||
{
|
||||
inline bool operator() (const BoneWeight& bw1, const BoneWeight& bw2)
|
||||
{
|
||||
if (bw1.getWeight() > bw2.getWeight())return true;
|
||||
if (bw1.getWeight() < bw2.getWeight())return false;
|
||||
return(bw1.getBoneName()<bw2.getBoneName());
|
||||
if (bw1.second > bw2.second)return true;
|
||||
if (bw1.second < bw2.second)return false;
|
||||
return(bw1.first<bw2.first);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -72,7 +73,7 @@ void VertexInfluenceMap::cullInfluenceCountPerVertex(unsigned int numbonepervert
|
||||
for(IndexWeightList::iterator curinf=curvecinf.begin(); curinf!=curvecinf.end(); ++curinf) {
|
||||
VertexIndexWeight& inf=*curinf;
|
||||
if( bonename.empty()) {
|
||||
OSG_WARN << "VertexInfluenceSet::buildVertex2BoneList warning vertex " << inf.first << " is not assigned to a bone" << std::endl;
|
||||
OSG_WARN << "VertexInfluenceSet::cullInfluenceCountPerVertex warning vertex " << inf.first << " is not assigned to a bone" << std::endl;
|
||||
}
|
||||
else if(inf.second>minweight)tempVec2Bones[inf.first].insert(BoneWeight(bonename, inf.second));
|
||||
}
|
||||
@@ -85,20 +86,20 @@ void VertexInfluenceMap::cullInfluenceCountPerVertex(unsigned int numbonepervert
|
||||
while(bwset.size()>newsize)bwset.erase(*bwset.rbegin());
|
||||
if(renormalize){
|
||||
for(BoneWeightOrdered::iterator bwit=bwset.begin(); bwit!=bwset.end(); ++bwit)
|
||||
sum+=bwit->getWeight();
|
||||
sum+=bwit->second;
|
||||
if(sum>1e-4){
|
||||
sum=1.0f/sum;
|
||||
for(BoneWeightOrdered::iterator bwit=bwset.begin(); bwit!=bwset.end(); ++bwit) {
|
||||
VertexInfluence & inf= (*this)[bwit->getBoneName()];
|
||||
inf.push_back(VertexIndexWeight(mapit->first, bwit->getWeight()*sum));
|
||||
inf.setName(bwit->getBoneName());
|
||||
VertexInfluence & inf= (*this)[bwit->first];
|
||||
inf.push_back(VertexIndexWeight(mapit->first, bwit->second*sum));
|
||||
inf.setName(bwit->first);
|
||||
}
|
||||
}
|
||||
}else{
|
||||
for(BoneWeightOrdered::iterator bwit=bwset.begin(); bwit!=bwset.end(); ++bwit) {
|
||||
VertexInfluence & inf= (*this)[bwit->getBoneName()];
|
||||
inf.push_back(VertexIndexWeight(mapit->first,bwit->getWeight()));
|
||||
inf.setName(bwit->getBoneName());
|
||||
VertexInfluence & inf= (*this)[bwit->first];
|
||||
inf.push_back(VertexIndexWeight(mapit->first,bwit->second));
|
||||
inf.setName(bwit->first);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -119,8 +120,8 @@ void VertexInfluenceMap::computePerVertexInfluenceList(std::vector<BoneWeightLis
|
||||
for(IndexWeightList::const_iterator infit=inflist.begin(); infit!=inflist.end(); ++infit)
|
||||
{
|
||||
const VertexIndexWeight &iw = *infit;
|
||||
const unsigned int &index = iw.getIndex();
|
||||
float weight = iw.getWeight();
|
||||
const unsigned int &index = iw.first;
|
||||
const float &weight = iw.second;
|
||||
vertex2Bones[index].push_back(BoneWeight(it->first, weight));;
|
||||
}
|
||||
}
|
||||
@@ -132,11 +133,11 @@ struct SortByNameAndWeight : public std::less<BoneWeight>
|
||||
bool operator()(const BoneWeight& b0,
|
||||
const BoneWeight& b1) const
|
||||
{
|
||||
if (b0.getBoneName() < b1.getBoneName())
|
||||
if (b0.first < b1.first)
|
||||
return true;
|
||||
else if (b0.getBoneName() > b1.getBoneName())
|
||||
else if (b0.first> b1.first)
|
||||
return false;
|
||||
return (b0.getWeight() < b1.getWeight());
|
||||
return (b0.second < b1.second);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -161,7 +162,7 @@ struct SortByBoneWeightList : public std::less<BoneWeightList>
|
||||
return false;
|
||||
}
|
||||
};
|
||||
void VertexInfluenceMap::computeMinimalVertexGroupList(std::vector<VertexGroup>&uniqVertexGroupList,unsigned int numvert)const
|
||||
void VertexInfluenceMap::computeMinimalVertexGroupList(std::vector<VertexGroup>& uniqVertexGroupList, unsigned int numvert)const
|
||||
{
|
||||
uniqVertexGroupList.clear();
|
||||
std::vector<BoneWeightList> vertex2Bones;
|
||||
@@ -182,7 +183,7 @@ void VertexInfluenceMap::computeMinimalVertexGroupList(std::vector<VertexGroup>&
|
||||
unifyBuffer[boneweightlist].vertIDs().push_back(vertexID);
|
||||
}
|
||||
if(vertex2Bones.size()==unifyBuffer.size()) {
|
||||
OSG_WARN << "VertexInfluenceSet::buildmap is useless no duplicate VertexGroup" << std::endl;
|
||||
OSG_WARN << "VertexInfluenceMap::computeMinimalVertexGroupList is useless no duplicate VertexGroup" << std::endl;
|
||||
}
|
||||
uniqVertexGroupList.reserve(unifyBuffer.size());
|
||||
for (UnifyBoneGroup::iterator it = unifyBuffer.begin(); it != unifyBuffer.end(); ++it)
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include <osgDB/ObjectWrapper>
|
||||
#include <osgDB/InputStream>
|
||||
#include <osgDB/OutputStream>
|
||||
|
||||
namespace wrap_osgAnimationRigGeometry{
|
||||
static bool checkInfluenceMap( const osgAnimation::RigGeometry& geom )
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user