[964] | 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 |
|
---|