vrshoot

view libs/assimp/FBXAnimation.cpp @ 0:b2f14e535253

initial commit
author John Tsiombikas <nuclear@member.fsf.org>
date Sat, 01 Feb 2014 19:58:19 +0200
parents
children
line source
1 /*
2 Open Asset Import Library (assimp)
3 ----------------------------------------------------------------------
5 Copyright (c) 2006-2012, assimp team
6 All rights reserved.
8 Redistribution and use of this software in source and binary forms,
9 with or without modification, are permitted provided that the
10 following conditions are met:
12 * Redistributions of source code must retain the above
13 copyright notice, this list of conditions and the
14 following disclaimer.
16 * Redistributions in binary form must reproduce the above
17 copyright notice, this list of conditions and the
18 following disclaimer in the documentation and/or other
19 materials provided with the distribution.
21 * Neither the name of the assimp team, nor the names of its
22 contributors may be used to endorse or promote products
23 derived from this software without specific prior
24 written permission of the assimp team.
26 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 ----------------------------------------------------------------------
39 */
41 /** @file FBXAnimation.cpp
42 * @brief Assimp::FBX::AnimationCurve, Assimp::FBX::AnimationCurveNode,
43 * Assimp::FBX::AnimationLayer, Assimp::FBX::AnimationStack
44 */
45 #include "AssimpPCH.h"
47 #ifndef ASSIMP_BUILD_NO_FBX_IMPORTER
49 #include "FBXParser.h"
50 #include "FBXDocument.h"
51 #include "FBXImporter.h"
52 #include "FBXImportSettings.h"
53 #include "FBXDocumentUtil.h"
54 #include "FBXProperties.h"
56 namespace Assimp {
57 namespace FBX {
59 using namespace Util;
61 // ------------------------------------------------------------------------------------------------
62 AnimationCurve::AnimationCurve(uint64_t id, const Element& element, const std::string& name, const Document& doc)
63 : Object(id, element, name)
64 {
65 const Scope& sc = GetRequiredScope(element);
66 const Element& KeyTime = GetRequiredElement(sc,"KeyTime");
67 const Element& KeyValueFloat = GetRequiredElement(sc,"KeyValueFloat");
69 ParseVectorDataArray(keys, KeyTime);
70 ParseVectorDataArray(values, KeyValueFloat);
72 if(keys.size() != values.size()) {
73 DOMError("the number of key times does not match the number of keyframe values",&KeyTime);
74 }
76 // check if the key times are well-ordered
77 if(!std::equal(keys.begin(), keys.end() - 1, keys.begin() + 1, std::less<KeyTimeList::value_type>())) {
78 DOMError("the keyframes are not in ascending order",&KeyTime);
79 }
81 const Element* KeyAttrDataFloat = sc["KeyAttrDataFloat"];
82 if(KeyAttrDataFloat) {
83 ParseVectorDataArray(attributes, *KeyAttrDataFloat);
84 }
86 const Element* KeyAttrFlags = sc["KeyAttrFlags"];
87 if(KeyAttrFlags) {
88 ParseVectorDataArray(flags, *KeyAttrFlags);
89 }
90 }
93 // ------------------------------------------------------------------------------------------------
94 AnimationCurve::~AnimationCurve()
95 {
97 }
100 // ------------------------------------------------------------------------------------------------
101 AnimationCurveNode::AnimationCurveNode(uint64_t id, const Element& element, const std::string& name, const Document& doc,
102 const char* const * target_prop_whitelist /*= NULL*/, size_t whitelist_size /*= 0*/)
103 : Object(id, element, name)
104 , target()
105 , doc(doc)
106 {
107 const Scope& sc = GetRequiredScope(element);
109 // find target node
110 const char* whitelist[] = {"Model","NodeAttribute"};
111 const std::vector<const Connection*>& conns = doc.GetConnectionsBySourceSequenced(ID(),whitelist,2);
113 BOOST_FOREACH(const Connection* con, conns) {
115 // link should go for a property
116 if (!con->PropertyName().length()) {
117 continue;
118 }
120 if(target_prop_whitelist) {
121 const char* const s = con->PropertyName().c_str();
122 bool ok = false;
123 for (size_t i = 0; i < whitelist_size; ++i) {
124 if (!strcmp(s, target_prop_whitelist[i])) {
125 ok = true;
126 break;
127 }
128 }
130 if (!ok) {
131 throw std::range_error("AnimationCurveNode target property is not in whitelist");
132 }
133 }
135 const Object* const ob = con->DestinationObject();
136 if(!ob) {
137 DOMWarning("failed to read destination object for AnimationCurveNode->Model link, ignoring",&element);
138 continue;
139 }
141 // XXX support constraints as DOM class
142 //ai_assert(dynamic_cast<const Model*>(ob) || dynamic_cast<const NodeAttribute*>(ob));
143 target = ob;
144 if(!target) {
145 continue;
146 }
148 prop = con->PropertyName();
149 break;
150 }
152 if(!target) {
153 DOMWarning("failed to resolve target Model/NodeAttribute/Constraint for AnimationCurveNode",&element);
154 }
156 props = GetPropertyTable(doc,"AnimationCurveNode.FbxAnimCurveNode",element,sc,false);
157 }
160 // ------------------------------------------------------------------------------------------------
161 AnimationCurveNode::~AnimationCurveNode()
162 {
164 }
167 // ------------------------------------------------------------------------------------------------
168 const AnimationCurveMap& AnimationCurveNode::Curves() const
169 {
170 if(curves.empty()) {
171 // resolve attached animation curves
172 const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID(),"AnimationCurve");
174 BOOST_FOREACH(const Connection* con, conns) {
176 // link should go for a property
177 if (!con->PropertyName().length()) {
178 continue;
179 }
181 const Object* const ob = con->SourceObject();
182 if(!ob) {
183 DOMWarning("failed to read source object for AnimationCurve->AnimationCurveNode link, ignoring",&element);
184 continue;
185 }
187 const AnimationCurve* const anim = dynamic_cast<const AnimationCurve*>(ob);
188 if(!anim) {
189 DOMWarning("source object for ->AnimationCurveNode link is not an AnimationCurve",&element);
190 continue;
191 }
193 curves[con->PropertyName()] = anim;
194 }
195 }
197 return curves;
198 }
201 // ------------------------------------------------------------------------------------------------
202 AnimationLayer::AnimationLayer(uint64_t id, const Element& element, const std::string& name, const Document& doc)
203 : Object(id, element, name)
204 , doc(doc)
205 {
206 const Scope& sc = GetRequiredScope(element);
208 // note: the props table here bears little importance and is usually absent
209 props = GetPropertyTable(doc,"AnimationLayer.FbxAnimLayer",element,sc, true);
210 }
213 // ------------------------------------------------------------------------------------------------
214 AnimationLayer::~AnimationLayer()
215 {
217 }
220 // ------------------------------------------------------------------------------------------------
221 AnimationCurveNodeList AnimationLayer::Nodes(const char* const * target_prop_whitelist /*= NULL*/,
222 size_t whitelist_size /*= 0*/) const
223 {
224 AnimationCurveNodeList nodes;
226 // resolve attached animation nodes
227 const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID(),"AnimationCurveNode");
228 nodes.reserve(conns.size());
230 BOOST_FOREACH(const Connection* con, conns) {
232 // link should not go to a property
233 if (con->PropertyName().length()) {
234 continue;
235 }
237 const Object* const ob = con->SourceObject();
238 if(!ob) {
239 DOMWarning("failed to read source object for AnimationCurveNode->AnimationLayer link, ignoring",&element);
240 continue;
241 }
243 const AnimationCurveNode* const anim = dynamic_cast<const AnimationCurveNode*>(ob);
244 if(!anim) {
245 DOMWarning("source object for ->AnimationLayer link is not an AnimationCurveNode",&element);
246 continue;
247 }
249 if(target_prop_whitelist) {
250 const char* s = anim->TargetProperty().c_str();
251 bool ok = false;
252 for (size_t i = 0; i < whitelist_size; ++i) {
253 if (!strcmp(s, target_prop_whitelist[i])) {
254 ok = true;
255 break;
256 }
257 }
258 if(!ok) {
259 continue;
260 }
261 }
262 nodes.push_back(anim);
263 }
265 return nodes; // pray for NRVO
266 }
268 // ------------------------------------------------------------------------------------------------
269 AnimationStack::AnimationStack(uint64_t id, const Element& element, const std::string& name, const Document& doc)
270 : Object(id, element, name)
271 {
272 const Scope& sc = GetRequiredScope(element);
274 // note: we don't currently use any of these properties so we shouldn't bother if it is missing
275 props = GetPropertyTable(doc,"AnimationStack.FbxAnimStack",element,sc, true);
277 // resolve attached animation layers
278 const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID(),"AnimationLayer");
279 layers.reserve(conns.size());
281 BOOST_FOREACH(const Connection* con, conns) {
283 // link should not go to a property
284 if (con->PropertyName().length()) {
285 continue;
286 }
288 const Object* const ob = con->SourceObject();
289 if(!ob) {
290 DOMWarning("failed to read source object for AnimationLayer->AnimationStack link, ignoring",&element);
291 continue;
292 }
294 const AnimationLayer* const anim = dynamic_cast<const AnimationLayer*>(ob);
295 if(!anim) {
296 DOMWarning("source object for ->AnimationStack link is not an AnimationLayer",&element);
297 continue;
298 }
299 layers.push_back(anim);
300 }
301 }
304 // ------------------------------------------------------------------------------------------------
305 AnimationStack::~AnimationStack()
306 {
308 }
310 } //!FBX
311 } //!Assimp
313 #endif