#
root/OpenSceneGraph/trunk/include/osgAnimation/RigTransformSoftware
@
10877

Revision 10877, 6.4 kB (checked in by cedricpinson, 7 years ago) |
---|

Rev | Line | |
---|---|---|

[10693] | 1 | /* -*-c++-*- |

2 | * Copyright (C) 2009 Cedric Pinson <cedric.pinson@plopbyte.net> | |

3 | * | |

4 | * This library is open source and may be redistributed and/or modified under | |

5 | * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or | |

6 | * (at your option) any later version. The full license is in LICENSE file | |

7 | * included with this distribution, and on the openscenegraph.org website. | |

8 | * | |

9 | * This library is distributed in the hope that it will be useful, | |

10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |

11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |

12 | * OpenSceneGraph Public License for more details. | |

13 | */ | |

14 | ||

15 | #ifndef OSGANIMATION_RIG_TRANSFORM_SOFTWARE_H | |

16 | #define OSGANIMATION_RIG_TRANSFORM_SOFTWARE_H 1 | |

17 | ||

18 | #include <osgAnimation/Export> | |

19 | #include <osgAnimation/RigTransform> | |

20 | #include <osgAnimation/Bone> | |

21 | ||

22 | namespace osgAnimation | |

23 | { | |

24 | ||

25 | class RigGeometry; | |

26 | ||

27 | /// This class manage format for hardware skinning | |

28 | class OSGANIMATION_EXPORT RigTransformSoftware : public RigTransform | |

29 | { | |

30 | public: | |

31 | ||

32 | virtual bool init(RigGeometry&); | |

33 | virtual void update(RigGeometry&); | |

34 | ||

35 | ||

36 | class BoneWeight | |

37 | { | |

38 | public: | |

39 | BoneWeight(Bone* bone, float weight) : _bone(bone), _weight(weight) {} | |

40 | const Bone* getBone() const { return _bone.get(); } | |

41 | float getWeight() const { return _weight; } | |

42 | void setWeight(float w) { _weight = w; } | |

43 | protected: | |

44 | osg::observer_ptr<Bone> _bone; | |

45 | float _weight; | |

46 | }; | |

47 | ||

48 | typedef std::vector<BoneWeight> BoneWeightList; | |

49 | typedef std::vector<int> VertexList; | |

50 | ||

51 | class UniqBoneSetVertexSet | |

52 | { | |

53 | public: | |

54 | BoneWeightList& getBones() { return _bones; } | |

55 | VertexList& getVertexes() { return _vertexes; } | |

56 | ||

57 | void resetMatrix() | |

58 | { | |

59 | _result.set(0, 0, 0, 0, | |

60 | 0, 0, 0, 0, | |

61 | 0, 0, 0, 0, | |

62 | 0, 0, 0, 1); | |

63 | } | |

64 | void accummulateMatrix(const osg::Matrix& invBindMatrix, const osg::Matrix& matrix, osg::Matrix::value_type weight) | |

65 | { | |

66 | osg::Matrix m = invBindMatrix * matrix; | |

67 | osg::Matrix::value_type* ptr = m.ptr(); | |

68 | osg::Matrix::value_type* ptrresult = _result.ptr(); | |

69 | ptrresult[0] += ptr[0] * weight; | |

70 | ptrresult[1] += ptr[1] * weight; | |

71 | ptrresult[2] += ptr[2] * weight; | |

72 | ||

73 | ptrresult[4] += ptr[4] * weight; | |

74 | ptrresult[5] += ptr[5] * weight; | |

75 | ptrresult[6] += ptr[6] * weight; | |

76 | ||

77 | ptrresult[8] += ptr[8] * weight; | |

78 | ptrresult[9] += ptr[9] * weight; | |

79 | ptrresult[10] += ptr[10] * weight; | |

80 | ||

81 | ptrresult[12] += ptr[12] * weight; | |

82 | ptrresult[13] += ptr[13] * weight; | |

83 | ptrresult[14] += ptr[14] * weight; | |

84 | } | |

85 | void computeMatrixForVertexSet() | |

86 | { | |

87 | if (_bones.empty()) | |

88 | { | |

[10877] | 89 | osg::notify(osg::WARN) << this << " RigTransformSoftware::UniqBoneSetVertexSet no bones found" << std::endl; |

[10693] | 90 | _result = osg::Matrix::identity(); |

91 | return; | |

92 | } | |

93 | resetMatrix(); | |

94 | ||

95 | int size = _bones.size(); | |

96 | for (int i = 0; i < size; i++) | |

97 | { | |

98 | const Bone* bone = _bones[i].getBone(); | |

[10877] | 99 | if (!bone) |

100 | { | |

101 | osg::notify(osg::WARN) << this << " RigTransformSoftware::computeMatrixForVertexSet Warning a bone is null, skip it" << std::endl; | |

102 | continue; | |

103 | } | |

[10693] | 104 | const osg::Matrix& invBindMatrix = bone->getInvBindMatrixInSkeletonSpace(); |

105 | const osg::Matrix& matrix = bone->getMatrixInSkeletonSpace(); | |

106 | osg::Matrix::value_type w = _bones[i].getWeight(); | |

107 | accummulateMatrix(invBindMatrix, matrix, w); | |

108 | } | |

109 | } | |

110 | const osg::Matrix& getMatrix() const { return _result;} | |

111 | protected: | |

112 | BoneWeightList _bones; | |

113 | VertexList _vertexes; | |

114 | osg::Matrix _result; | |

115 | }; | |

116 | ||

117 | ||

118 | ||

119 | template <class V> void compute(const osg::Matrix& transform, const osg::Matrix& invTransform, const V* src, V* dst) | |

120 | { | |

121 | // the result of matrix mult should be cached to be used for vertexes transform and normal transform and maybe other computation | |

122 | int size = _boneSetVertexSet.size(); | |

123 | for (int i = 0; i < size; i++) | |

124 | { | |

125 | UniqBoneSetVertexSet& uniq = _boneSetVertexSet[i]; | |

126 | uniq.computeMatrixForVertexSet(); | |

127 | osg::Matrix matrix = transform * uniq.getMatrix() * invTransform; | |

128 | ||

129 | const VertexList& vertexes = uniq.getVertexes(); | |

130 | int vertexSize = vertexes.size(); | |

131 | for (int j = 0; j < vertexSize; j++) | |

132 | { | |

133 | int idx = vertexes[j]; | |

134 | dst[idx] = src[idx] * matrix; | |

135 | } | |

136 | } | |

137 | } | |

138 | ||

139 | ||

140 | template <class V> void computeNormal(const osg::Matrix& transform, const osg::Matrix& invTransform, const V* src, V* dst) | |

141 | { | |

142 | int size = _boneSetVertexSet.size(); | |

143 | for (int i = 0; i < size; i++) | |

144 | { | |

145 | UniqBoneSetVertexSet& uniq = _boneSetVertexSet[i]; | |

146 | uniq.computeMatrixForVertexSet(); | |

147 | osg::Matrix matrix = transform * uniq.getMatrix() * invTransform; | |

148 | ||

149 | const VertexList& vertexes = uniq.getVertexes(); | |

150 | int vertexSize = vertexes.size(); | |

151 | for (int j = 0; j < vertexSize; j++) | |

152 | { | |

153 | int idx = vertexes[j]; | |

154 | dst[idx] = osg::Matrix::transform3x3(src[idx],matrix); | |

155 | } | |

156 | } | |

157 | } | |

158 | ||

159 | const std::vector<osg::Vec3>& getPositionSource() const { return _positionSource;} | |

160 | const std::vector<osg::Vec3>& getNormalSource() const { return _normalSource;} | |

161 | ||

162 | protected: | |

163 | ||

164 | void initVertexSetFromBones(const Bone::BoneMap& map, const VertexInfluenceSet::UniqVertexSetToBoneSetList& influence); | |

165 | ||

166 | std::vector<UniqBoneSetVertexSet> _boneSetVertexSet; | |

167 | std::vector<osg::Vec3> _positionSource; | |

168 | std::vector<osg::Vec3> _normalSource; | |

169 | ||

170 | }; | |

171 | } | |

172 | ||

173 | #endif |

**Note:**See TracBrowser for help on using the browser.