| [10693] | 1 | |
|---|
| 2 | |
|---|
| 3 | |
|---|
| 4 | |
|---|
| 5 | |
|---|
| 6 | |
|---|
| 7 | |
|---|
| 8 | |
|---|
| 9 | |
|---|
| 10 | |
|---|
| 11 | |
|---|
| 12 | |
|---|
| 13 | |
|---|
| 14 | |
|---|
| 15 | |
|---|
| 16 | #include <osgAnimation/RigTransformSoftware> |
|---|
| 17 | #include <osgAnimation/RigGeometry> |
|---|
| 18 | |
|---|
| 19 | using namespace osgAnimation; |
|---|
| 20 | |
|---|
| 21 | bool RigTransformSoftware::init(RigGeometry& geom) |
|---|
| 22 | { |
|---|
| 23 | if (!geom.getSkeleton()) |
|---|
| 24 | return false; |
|---|
| 25 | Bone::BoneMap bm = geom.getSkeleton()->getBoneMap(); |
|---|
| 26 | initVertexSetFromBones(bm, geom.getVertexInfluenceSet().getUniqVertexSetToBoneSetList()); |
|---|
| 27 | _needInit = false; |
|---|
| 28 | return true; |
|---|
| 29 | } |
|---|
| 30 | |
|---|
| 31 | void RigTransformSoftware::update(RigGeometry& geom) |
|---|
| 32 | { |
|---|
| 33 | osg::Vec3Array* pos = dynamic_cast<osg::Vec3Array*>(geom.getVertexArray()); |
|---|
| 34 | if (pos && _positionSource.size() != pos->size()) |
|---|
| 35 | { |
|---|
| 36 | _positionSource = std::vector<osg::Vec3>(pos->begin(),pos->end()); |
|---|
| 37 | geom.getVertexArray()->setDataVariance(osg::Object::DYNAMIC); |
|---|
| 38 | } |
|---|
| 39 | osg::Vec3Array* normal = dynamic_cast<osg::Vec3Array*>(geom.getNormalArray()); |
|---|
| 40 | if (normal && _normalSource.size() != normal->size()) |
|---|
| 41 | { |
|---|
| 42 | _normalSource = std::vector<osg::Vec3>(normal->begin(),normal->end()); |
|---|
| 43 | geom.getNormalArray()->setDataVariance(osg::Object::DYNAMIC); |
|---|
| 44 | } |
|---|
| 45 | |
|---|
| 46 | if (!_positionSource.empty()) |
|---|
| 47 | { |
|---|
| 48 | compute<osg::Vec3>(geom.getMatrixFromSkeletonToGeometry(), geom.getInvMatrixFromSkeletonToGeometry(), &_positionSource.front(), &pos->front()); |
|---|
| 49 | pos->dirty(); |
|---|
| 50 | } |
|---|
| 51 | if (!_normalSource.empty()) |
|---|
| 52 | { |
|---|
| 53 | computeNormal<osg::Vec3>(geom.getMatrixFromSkeletonToGeometry(), geom.getInvMatrixFromSkeletonToGeometry(), &_normalSource.front(), &normal->front()); |
|---|
| 54 | normal->dirty(); |
|---|
| 55 | } |
|---|
| 56 | } |
|---|
| 57 | |
|---|
| 58 | void RigTransformSoftware::initVertexSetFromBones(const Bone::BoneMap& map, const VertexInfluenceSet::UniqVertexSetToBoneSetList& influence) |
|---|
| 59 | { |
|---|
| 60 | _boneSetVertexSet.clear(); |
|---|
| 61 | |
|---|
| 62 | int size = influence.size(); |
|---|
| 63 | _boneSetVertexSet.resize(size); |
|---|
| 64 | for (int i = 0; i < size; i++) |
|---|
| 65 | { |
|---|
| 66 | const VertexInfluenceSet::UniqVertexSetToBoneSet& inf = influence[i]; |
|---|
| 67 | int nbBones = inf.getBones().size(); |
|---|
| 68 | BoneWeightList& boneList = _boneSetVertexSet[i].getBones(); |
|---|
| 69 | |
|---|
| 70 | double sumOfWeight = 0; |
|---|
| 71 | for (int b = 0; b < nbBones; b++) |
|---|
| 72 | { |
|---|
| 73 | const std::string& bname = inf.getBones()[b].getBoneName(); |
|---|
| 74 | float weight = inf.getBones()[b].getWeight(); |
|---|
| 75 | Bone::BoneMap::const_iterator it = map.find(bname); |
|---|
| 76 | if (it == map.end()) |
|---|
| 77 | { |
|---|
| 78 | osg::notify(osg::WARN) << "RigTransformSoftware Bone " << bname << " not found, skip the influence group " <<bname << std::endl; |
|---|
| 79 | continue; |
|---|
| 80 | } |
|---|
| 81 | Bone* bone = it->second.get(); |
|---|
| 82 | boneList.push_back(BoneWeight(bone, weight)); |
|---|
| 83 | sumOfWeight += weight; |
|---|
| 84 | } |
|---|
| 85 | |
|---|
| 86 | |
|---|
| 87 | const double threshold = 1e-4; |
|---|
| 88 | if (!_boneSetVertexSet[i].getBones().empty() && |
|---|
| 89 | (sumOfWeight < 1.0 - threshold || sumOfWeight > 1.0 + threshold)) |
|---|
| 90 | { |
|---|
| 91 | for (int b = 0; b < (int)boneList.size(); b++) |
|---|
| 92 | boneList[b].setWeight(boneList[b].getWeight() / sumOfWeight); |
|---|
| 93 | } |
|---|
| 94 | _boneSetVertexSet[i].getVertexes() = inf.getVertexes(); |
|---|
| 95 | } |
|---|
| 96 | } |
|---|