1 | /*
|
---|
2 | Copyright (C) 2005-2006 Feeling Software Inc.
|
---|
3 | MIT License: http://www.opensource.org/licenses/mit-license.php
|
---|
4 | */
|
---|
5 | /*
|
---|
6 | Based on the FS Import classes:
|
---|
7 | Copyright (C) 2005-2006 Feeling Software Inc
|
---|
8 | Copyright (C) 2005-2006 Autodesk Media Entertainment
|
---|
9 | MIT License: http://www.opensource.org/licenses/mit-license.php
|
---|
10 | */
|
---|
11 |
|
---|
12 | /**
|
---|
13 | @file FCDSkinController.h
|
---|
14 | This file contains the FCDSkinController class.
|
---|
15 | */
|
---|
16 |
|
---|
17 | #ifndef _FCD_SKIN_CONTROLLER_H_
|
---|
18 | #define _FCD_SKIN_CONTROLLER_H_
|
---|
19 |
|
---|
20 | #include "FCDocument/FCDObject.h"
|
---|
21 |
|
---|
22 | class FCDocument;
|
---|
23 | class FCDController;
|
---|
24 | class FCDGeometry;
|
---|
25 | class FCDSceneNode;
|
---|
26 |
|
---|
27 | /**
|
---|
28 | A weighted joint index used in skinning.
|
---|
29 | */
|
---|
30 | struct FCDJointWeightPair
|
---|
31 | {
|
---|
32 | /** Default constructor: sets both the joint index and the weight to zero. */
|
---|
33 | FCDJointWeightPair() { jointIndex = 0; weight = 0.0f; }
|
---|
34 |
|
---|
35 | /** Constructor: sets the joint index and the weight to the given values.
|
---|
36 | @param _jointIndex The jointIndex.
|
---|
37 | @param _weight Its weight. */
|
---|
38 | FCDJointWeightPair(uint32 _jointIndex, float _weight) { jointIndex = _jointIndex; weight = _weight; }
|
---|
39 |
|
---|
40 | uint32 jointIndex; /**< A joint index. Use this index within the skin's joint list. */
|
---|
41 | float weight; /**< A skinning weight. */
|
---|
42 | };
|
---|
43 |
|
---|
44 | /**
|
---|
45 | A joint and its bind pose used in skinning.
|
---|
46 | */
|
---|
47 | struct FCDJointMatrixPair
|
---|
48 | {
|
---|
49 | FMMatrix44 invertedBindPose; /**< The inverse matrix of the bind pose of the joint. */
|
---|
50 | FCDSceneNode* joint; /**< A joint. */
|
---|
51 | };
|
---|
52 |
|
---|
53 | /** A dynamically-sized array of joints and bind poses. */
|
---|
54 | typedef vector<FCDJointMatrixPair> FCDJointList;
|
---|
55 |
|
---|
56 | /** A dynamically-sized array of weighted joint indices.
|
---|
57 | The sum of the weights within this list should always add up to one. */
|
---|
58 | typedef vector<FCDJointWeightPair> FCDJointWeightPairList;
|
---|
59 |
|
---|
60 | /** A dynamically-sized array of weighted joint index lists.
|
---|
61 | Each entry within this list represents one vertex of the skinned geometry. */
|
---|
62 | typedef vector<FCDJointWeightPairList> FCDWeightedMatches;
|
---|
63 |
|
---|
64 | /**
|
---|
65 | A COLLADA skin controller.
|
---|
66 |
|
---|
67 | The skin controller holds the information to skin a geometric object.
|
---|
68 | That information includes a target/base entity and its bind-pose matrix,
|
---|
69 | a list of joints and their bind pose and the influences for the joints.
|
---|
70 |
|
---|
71 | The influences are a list, for each vertex of the target entity, of which
|
---|
72 | joints affect the vertex and by how much.
|
---|
73 |
|
---|
74 | @ingroup FCDGeometry
|
---|
75 | */
|
---|
76 | class FCOLLADA_EXPORT FCDSkinController : public FCDObject
|
---|
77 | {
|
---|
78 | private:
|
---|
79 | DeclareObjectType;
|
---|
80 | FCDController* parent;
|
---|
81 |
|
---|
82 | bool ownsTarget;
|
---|
83 | FCDEntity* target;
|
---|
84 | FMMatrix44 bindShapeTransform;
|
---|
85 |
|
---|
86 | StringList jointIds;
|
---|
87 | FCDJointList joints;
|
---|
88 | FCDWeightedMatches weightedMatches;
|
---|
89 |
|
---|
90 | public:
|
---|
91 | /** Constructor: do not use directly.
|
---|
92 | Instead, use the FCDController::CreateSkinController function.
|
---|
93 | @param document The COLLADA document that owns the skin.
|
---|
94 | @param parent The COLLADA controller that contains this skin. */
|
---|
95 | FCDSkinController(FCDocument* document, FCDController* parent);
|
---|
96 |
|
---|
97 | /** Destructor: do not use directly.
|
---|
98 | Instead, release the parent controller or create a new skin/morpher. */
|
---|
99 | virtual ~FCDSkinController();
|
---|
100 |
|
---|
101 | /** Retrieves the target entity.
|
---|
102 | This entity may be a geometric entity or another controller.
|
---|
103 | @return The target entity. */
|
---|
104 | FCDEntity* GetTarget() { return target; }
|
---|
105 | const FCDEntity* GetTarget() const { return target; } /**< See above. */
|
---|
106 |
|
---|
107 | /** Sets the target entity.
|
---|
108 | This function has very important ramifications, as the number
|
---|
109 | of vertices may change. The influences list will be modified to
|
---|
110 | follow the number of vertices.
|
---|
111 | This entity may be a geometric entity or another controller.
|
---|
112 | @param _target The target entity. */
|
---|
113 | void SetTarget(FCDEntity* _target);
|
---|
114 |
|
---|
115 | /** Retrieves the bind-pose transform of the target entity.
|
---|
116 | @return The bind-pose transform. */
|
---|
117 | const FMMatrix44& GetBindShapeTransform() const { return bindShapeTransform; }
|
---|
118 |
|
---|
119 | /** Sets the bind-pose transform of the target entity.
|
---|
120 | @param bindPose The bind-pose transform. */
|
---|
121 | void SetBindShapeTransform(const FMMatrix44& bindPose) { bindShapeTransform = bindPose; }
|
---|
122 |
|
---|
123 | /** Retrieves a list of the joints that influence this skin.
|
---|
124 | @return The list of joints. */
|
---|
125 | FCDJointList& GetJoints() { return joints; }
|
---|
126 | const FCDJointList& GetJoints() const { return joints; } /**< See above. */
|
---|
127 |
|
---|
128 | /** Retrieves the number of joints that influence the skin.
|
---|
129 | @return The number of joints. */
|
---|
130 | size_t GetJointCount() const { return joints.size(); }
|
---|
131 |
|
---|
132 | /** Retrieves a specific joint.
|
---|
133 | @param index The index of the joint.
|
---|
134 | @return The joint. This pointer will be NULL, if the index is out-of-bounds. */
|
---|
135 | FCDJointMatrixPair* GetJoint(size_t index) { FUAssert(index < GetJointCount(), return NULL); return &joints.at(index); }
|
---|
136 | const FCDJointMatrixPair* GetJoint(size_t index) const { FUAssert(index < GetJointCount(), return NULL); return &joints.at(index); } /**< See above. */
|
---|
137 |
|
---|
138 | /** Retrieves the information specific to a given joint.
|
---|
139 | @param joint The joint.
|
---|
140 | @return The information specific to this joint. This pointer will be NULL
|
---|
141 | if the given joint does not influence this skin. */
|
---|
142 | FCDJointMatrixPair* FindJoint(FCDSceneNode* joint);
|
---|
143 | const FCDJointMatrixPair* FindJoint(const FCDSceneNode* joint) const; /**< See above. */
|
---|
144 |
|
---|
145 | /** Adds a joint and its bind-pose to the list of joint influencing the skin.
|
---|
146 | @param joint The joint.
|
---|
147 | @param bindPose The joint's bind-pose. This matrix will be inverted by this function. */
|
---|
148 | void AddJoint(FCDSceneNode* joint, const FMMatrix44& bindPose);
|
---|
149 |
|
---|
150 | /** Removes a joint from the list of joints influencing the skin.
|
---|
151 | All the per-vertex influences that use this joint will be removed.
|
---|
152 | @param joint The joint. */
|
---|
153 | void RemoveJoint(FCDSceneNode* joint);
|
---|
154 |
|
---|
155 | /** Retrieves a list of the per-vertex influences for the skin.
|
---|
156 | You should not modify the size of the list. Instead, use the SetTarget function.
|
---|
157 | @deprecated Will be replaces by GetVertexInfluences.
|
---|
158 | @return The list of per-vertex influences. */
|
---|
159 | FCDWeightedMatches& GetWeightedMatches() { return weightedMatches; }
|
---|
160 | const FCDWeightedMatches& GetWeightedMatches() const { return weightedMatches; } /**< See above. */
|
---|
161 |
|
---|
162 | /** Retrieves a list of the per-vertex influences for the skin.
|
---|
163 | You should not modify the size of the list. Instead, use the SetTarget function.
|
---|
164 | @return The list of per-vertex influences. */
|
---|
165 | FCDWeightedMatches& GetVertexInfluences() { return weightedMatches; }
|
---|
166 | const FCDWeightedMatches& GetVertexInfluences() const { return weightedMatches; } /**< See above. */
|
---|
167 |
|
---|
168 | /** Retrieves the number of per-vertex influences.
|
---|
169 | This value should be equal to the number of vertices/control points
|
---|
170 | within the target geometric entity.
|
---|
171 | @return The number of per-vertex influences. */
|
---|
172 | size_t GetVertexInfluenceCount() const { return weightedMatches.size(); }
|
---|
173 |
|
---|
174 | /** Retrieves the per-vertex influences for a given vertex.
|
---|
175 | @param index The vertex index.
|
---|
176 | @return The per-vertex influences. */
|
---|
177 | FCDJointWeightPairList* GetInfluences(size_t index) { FUAssert(index < GetVertexInfluenceCount(), return NULL); return &weightedMatches.at(index); }
|
---|
178 | const FCDJointWeightPairList* GetInfluences(size_t index) const { FUAssert(index < GetVertexInfluenceCount(), return NULL); return &weightedMatches.at(index); } /**< See above. */
|
---|
179 |
|
---|
180 | /** Reduces the number of joints influencing each vertex.
|
---|
181 | 1) All the influences with a weight less than the minimum will be removed.
|
---|
182 | 2) If a vertex has more influences than the given maximum, they will be sorted and the
|
---|
183 | most important influences will be kept.
|
---|
184 | If some of the influences for a vertex are removed, the weight will be normalized.
|
---|
185 | @param maxInfluenceCount The maximum number of influence to keep for each vertex.
|
---|
186 | @param minimumWeight The smallest weight to keep. */
|
---|
187 | void ReduceInfluences(uint32 maxInfluenceCount, float minimumWeight=0.0f);
|
---|
188 |
|
---|
189 | /** [INTERNAL] Reads in the \<skin\> element from a given COLLADA XML tree node.
|
---|
190 | @param skinNode The COLLADA XML tree node.
|
---|
191 | @return The status of the import. If the status is not successful,
|
---|
192 | it may be dangerous to extract information from the skin.*/
|
---|
193 | FUStatus LoadFromXML(xmlNode* skinNode);
|
---|
194 |
|
---|
195 | /** [INTERNAL] Writes out the \<skin\> element to the given COLLADA XML tree node.
|
---|
196 | @param parentNode The COLLADA XML parent node in which to insert the skin information.
|
---|
197 | @return The created element XML tree node. */
|
---|
198 | xmlNode* WriteToXML(xmlNode* parentNode) const;
|
---|
199 |
|
---|
200 | /** [INTERNAL] Links the skin with its joints.
|
---|
201 | Since the scene graph is imported after the controllers, this function is used
|
---|
202 | to link the skin with its joints.
|
---|
203 | @return The status of the linkage.*/
|
---|
204 | FUStatus Link();
|
---|
205 | };
|
---|
206 |
|
---|
207 | #endif // _FCD_SKIN_CONTROLLER_H_
|
---|
208 |
|
---|