make preparedata skeleton independant (as it was with the Rig::buildInfluenceSet)

no more divergence with master i think
This commit is contained in:
Julien Valentin
2017-09-03 17:37:06 +02:00
parent 381c2150d4
commit 041a2a6e72
5 changed files with 290 additions and 236 deletions

View File

@@ -38,39 +38,31 @@ RigTransformSoftware::RigTransformSoftware(const RigTransformSoftware& rts,const
typedef std::vector<RigTransformSoftware::BonePtrWeight> BonePtrWeightList;
void RigTransformSoftware::buildMinimumUpdateSet( const BoneMap&boneMap, const RigGeometry&rig ){
void RigTransformSoftware::buildMinimumUpdateSet( const RigGeometry&rig )
{
///1 Create Index2Vec<BoneWeight>
const VertexInfluenceMap &vertexInfluenceMap=*rig.getInfluenceMap();
std::vector<BonePtrWeightList> perVertexInfluences;
perVertexInfluences.resize(rig.getSourceGeometry()->getVertexArray()->getNumElements());
unsigned int vimapBoneID = 0;
for (osgAnimation::VertexInfluenceMap::const_iterator perBoneinfit = vertexInfluenceMap.begin();
perBoneinfit != vertexInfluenceMap.end();
++perBoneinfit)
++perBoneinfit,++vimapBoneID)
{
const IndexWeightList& inflist = perBoneinfit->second;
const std::string& bonename = perBoneinfit->first;
if (bonename.empty()) {
if (bonename.empty())
{
OSG_WARN << "RigTransformSoftware::VertexInfluenceMap contains unamed bone IndexWeightList" << std::endl;
}
BoneMap::const_iterator bmit = boneMap.find(bonename);
if (bmit == boneMap.end() )
{
if (_invalidInfluence.find(bonename) != _invalidInfluence.end()) {
_invalidInfluence[bonename] = true;
OSG_WARN << "RigTransformSoftware Bone " << bonename << " not found, skip the influence group " << std::endl;
}
continue;
}
Bone* bone = bmit->second.get();
for(IndexWeightList::const_iterator infit=inflist.begin(); infit!=inflist.end(); ++infit)
{
const VertexIndexWeight &iw = *infit;
const unsigned int &index = iw.first;
float weight = iw.second;
perVertexInfluences[index].push_back(BonePtrWeight(bone, weight));
perVertexInfluences[index].push_back(BonePtrWeight(vimapBoneID, weight));
}
}
@@ -80,7 +72,7 @@ void RigTransformSoftware::buildMinimumUpdateSet( const BoneMap&boneMap, const R
{
BonePtrWeightList& bones = *it;
float sum = 0;
for(BonePtrWeightList::iterator bwit=bones.begin();bwit!=bones.end();++bwit)
for(BonePtrWeightList::iterator bwit=bones.begin(); bwit!=bones.end(); ++bwit)
sum += bwit->getWeight();
if (sum < 1e-4)
{
@@ -89,7 +81,7 @@ void RigTransformSoftware::buildMinimumUpdateSet( const BoneMap&boneMap, const R
else
{
float mult = 1.0/sum;
for(BonePtrWeightList::iterator bwit=bones.begin();bwit!=bones.end();++bwit)
for(BonePtrWeightList::iterator bwit=bones.begin(); bwit!=bones.end(); ++bwit)
bwit->setWeight(bwit->getWeight() * mult);
}
}
@@ -123,37 +115,13 @@ void RigTransformSoftware::buildMinimumUpdateSet( const BoneMap&boneMap, const R
OSG_INFO << "uniq groups " << _uniqVertexGroupList.size() << " for " << rig.getName() << std::endl;
}
bool RigTransformSoftware::prepareData(RigGeometry&rig) {
///find skeleton if not set
if(!rig.getSkeleton() && !rig.getParents().empty())
{
RigGeometry::FindNearestParentSkeleton finder;
if(rig.getParents().size() > 1)
osg::notify(osg::WARN) << "A RigGeometry should not have multi parent ( " << rig.getName() << " )" << std::endl;
rig.getParents()[0]->accept(finder);
if(!finder._root.valid())
{
osg::notify(osg::WARN) << "A RigGeometry did not find a parent skeleton for RigGeometry ( " << rig.getName() << " )" << std::endl;
return false;
}
rig.setSkeleton(finder._root.get());
}
if(!rig.getSkeleton())
return false;
///get bonemap from skeleton
BoneMapVisitor mapVisitor;
rig.getSkeleton()->accept(mapVisitor);
BoneMap boneMap = mapVisitor.getBoneMap();
/// build minimal set of VertexGroup
buildMinimumUpdateSet(boneMap,rig);
bool RigTransformSoftware::prepareData(RigGeometry&rig)
{
///set geom as it source
if (rig.getSourceGeometry())
rig.copyFrom(*rig.getSourceGeometry());
osg::Vec3Array* normalSrc = dynamic_cast<osg::Vec3Array*>(rig.getSourceGeometry()->getNormalArray());
osg::Vec3Array* positionSrc = dynamic_cast<osg::Vec3Array*>(rig.getSourceGeometry()->getVertexArray());
@@ -169,24 +137,92 @@ bool RigTransformSoftware::prepareData(RigGeometry&rig) {
*positionDst=*positionSrc;
positionDst->setDataVariance(osg::Object::DYNAMIC);
if(normalSrc) {
if(normalSrc)
{
osg::Vec3Array* normalDst =new osg::Vec3Array;
*normalDst=*normalSrc;
rig.setNormalArray(normalDst, osg::Array::BIND_PER_VERTEX);
normalDst->setDataVariance(osg::Object::DYNAMIC);
}
_needInit = false;
/// build minimal set of VertexGroup
buildMinimumUpdateSet(rig);
return true;
}
bool RigTransformSoftware::init(RigGeometry&rig)
{
///test if dataprepared
if(_uniqVertexGroupList.empty())
{
prepareData(rig);
return false;
}
if(!rig.getSkeleton())
return false;
///get bonemap from skeleton
BoneMapVisitor mapVisitor;
rig.getSkeleton()->accept(mapVisitor);
BoneMap boneMap = mapVisitor.getBoneMap();
VertexInfluenceMap & vertexInfluenceMap= *rig.getInfluenceMap();
///create local bonemap
std::vector<Bone*> localid2bone;
localid2bone.reserve(vertexInfluenceMap.size());
for (osgAnimation::VertexInfluenceMap::const_iterator perBoneinfit = vertexInfluenceMap.begin();
perBoneinfit != vertexInfluenceMap.end();
++perBoneinfit)
{
const std::string& bonename = perBoneinfit->first;
if (bonename.empty())
{
OSG_WARN << "RigTransformSoftware::VertexInfluenceMap contains unamed bone IndexWeightList" << std::endl;
}
BoneMap::const_iterator bmit = boneMap.find(bonename);
if (bmit == boneMap.end() )
{
if (_invalidInfluence.find(bonename) != _invalidInfluence.end())
{
_invalidInfluence[bonename] = true;
OSG_WARN << "RigTransformSoftware Bone " << bonename << " not found, skip the influence group " << std::endl;
}
localid2bone.push_back(0);
continue;
}
Bone* bone = bmit->second.get();
localid2bone.push_back(bone);
}
///fill bone ptr in the _uniqVertexGroupList
for(VertexGroupList::iterator itvg=_uniqVertexGroupList.begin(); itvg!=_uniqVertexGroupList.end(); ++itvg)
{
VertexGroup& uniq = *itvg;
for(BonePtrWeightList::iterator bwit= uniq.getBoneWeights().begin(); bwit!=uniq.getBoneWeights().end(); )
{
Bone * b=localid2bone[bwit->getBoneID()];
if(!b)
bwit=uniq.getBoneWeights().erase(bwit);
else
bwit++->setBonePtr(b);
}
}
_needInit = false;
return true;
}
void RigTransformSoftware::operator()(RigGeometry& geom)
{
if (_needInit)
if (!prepareData(geom))
if (!init(geom))
return;
if (!geom.getSourceGeometry()) {
if (!geom.getSourceGeometry())
{
OSG_WARN << this << " RigTransformSoftware no source geometry found on RigGeometry" << std::endl;
return;
}
@@ -209,11 +245,11 @@ void RigTransformSoftware::operator()(RigGeometry& geom)
if (normalSrc )
{
computeNormal<osg::Vec3>(geom.getMatrixFromSkeletonToGeometry(),
geom.getInvMatrixFromSkeletonToGeometry(),
&normalSrc->front(),
&normalDst->front());
normalDst->dirty();
computeNormal<osg::Vec3>(geom.getMatrixFromSkeletonToGeometry(),
geom.getInvMatrixFromSkeletonToGeometry(),
&normalSrc->front(),
&normalDst->front());
normalDst->dirty();
}
}