make preparedata skeleton independant (as it was with the Rig::buildInfluenceSet)
no more divergence with master i think
This commit is contained in:
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user