clean and bugfixes

This commit is contained in:
Julien Valentin
2017-08-31 16:35:05 +02:00
parent 34270cdcaa
commit 5aa96727e9
8 changed files with 63 additions and 54 deletions

View File

@@ -23,7 +23,9 @@
using namespace osgAnimation;
MorphTransformHardware::MorphTransformHardware():_needInit(true),_reservedTextureUnit(DEFAULTMORPHTEXTUREUNIT)
MorphTransformHardware::MorphTransformHardware():
_needInit(true),
_reservedTextureUnit(DEFAULTMORPHTEXTUREUNIT)
{
}
@@ -46,23 +48,22 @@ bool MorphTransformHardware::init(MorphGeometry& morphGeometry)
///check for correct morph configuration
///(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 +99,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 +140,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;

View File

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

View File

@@ -21,12 +21,13 @@
using namespace osgAnimation;
#define DEFAULT_FIRST_VERTATTRIB_TARGETTED 11
RigTransformHardware::RigTransformHardware():
_bonesPerVertex (0),
_nbVertexes (0),
_needInit (true),
_minAttribIndex(DEFAULT_FIRST_VERTATTRIB_TARGETTED)
{}
{}
RigTransformHardware::RigTransformHardware(const RigTransformHardware& rth, const osg::CopyOp& copyop):
RigTransform(rth, copyop),
@@ -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,12 +74,12 @@ void createVertexAttribList(RigTransformHardware& rig,const std::vector<std::ve
//
typedef std::vector<std::vector<VertexIndexWeight> > PerVertexInfList;
void createVertexAttribList(RigTransformHardware& rig,
void createVertexAttribList(const RigTransformHardware& rig,
const PerVertexInfList & perVertexInfluences,
RigTransformHardware::BoneWeightAttribList& boneWeightAttribArrays)
{
unsigned int nbVertices= rig.getNumVertexes();
unsigned int maxbonepervertex=rig.getNumBonesPerVertex();
unsigned int nbVertices = rig.getNumVertexes();
unsigned int maxbonepervertex = rig.getNumBonesPerVertex();
unsigned int nbArray = static_cast<unsigned int>(ceilf( ((float)maxbonepervertex) * 0.5f));
if (!nbArray)
@@ -101,8 +99,6 @@ void createVertexAttribList(RigTransformHardware& rig,
// 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())
{
float boneIndex = static_cast<float>(perVertexInfluences[j][boneIndexInList].getIndex());
@@ -110,6 +106,9 @@ void createVertexAttribList(RigTransformHardware& rig,
// fill the vec4
(*array)[j][0 + boneIndexInVec4] = boneIndex;
(*array)[j][1 + boneIndexInVec4] = boneWeight;
}else{
(*array)[j][0 + boneIndexInVec4] = 0;
(*array)[j][1 + boneIndexInVec4] = 0;
}
}
}
@@ -133,6 +132,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,7 +155,8 @@ 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();
@@ -165,7 +167,7 @@ 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
@@ -173,14 +175,14 @@ bool RigTransformHardware::buildPalette(const BoneMap&boneMap ,const RigGeometry
perVertexInfluences.resize(_nbVertexes);
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;
@@ -213,10 +215,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,24 +228,27 @@ bool RigTransformHardware::buildPalette(const BoneMap&boneMap ,const RigGeometry
}
///normalize
///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(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)
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());
@@ -253,12 +256,16 @@ bool RigTransformHardware::buildPalette(const BoneMap&boneMap ,const RigGeometry
createVertexAttribList(*this,perVertexInfluences,this->_boneWeightAttribArrays);
return true;
_needInit = 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 +274,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 +305,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 +314,22 @@ 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));
OSG_INFO << "set vertex attrib " << ss.str() << std::endl;
}
program->addShader(vertexshader.get());
stateset->removeUniform("nbBonesPerVertex");
@@ -333,11 +339,10 @@ bool RigTransformHardware::init(RigGeometry& rig){
stateset->addUniform(_uniformMatrixPalette);
stateset->removeAttribute(osg::StateAttribute::PROGRAM);
if(!stateset->getAttribute(osg::StateAttribute::PROGRAM))
stateset->setAttributeAndModes(program.get());
stateset->setAttributeAndModes(program.get());
_needInit = false;
return false;
return true;
}
else prepareData(rig);
return false;

View File

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

View File

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

View File

@@ -2,6 +2,7 @@
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
namespace wrap_osgAnimationRigGeometry{
static bool checkInfluenceMap( const osgAnimation::RigGeometry& geom )
{