framework2
544 строки · 17.2 Кб
1//
2// Node.cpp
3// ConnectionsWall-Nick
4//
5// Created by Nick Hardeman on 7/11/19.
6//
7
8#include "ofxFBXSrcNode.h"
9using namespace ofxFBXSource;
10
11//----------------------------------------
12Node::Node() {
13// parent = NULL;
14// globalParent = NULL;
15origScale = glm::vec3(1,1,1);
16}
17
18//----------------------------------------
19Node::~Node() {
20if( getParent() != NULL ) {
21clearParent();
22}
23}
24
25//----------------------------------------
26// this is painful :( -- probably should make an array of names
27string Node::getFbxTypeStringFromNode( FbxNode* aNode ) {
28if( aNode == NULL ) { return "Node is NULL";}
29FbxNodeAttribute* lNodeAttribute = aNode->GetNodeAttribute();
30if( lNodeAttribute ) {
31
32// -eUnknown,
33// -eNull,
34// -eMarker,
35// -eSkeleton,
36// -eMesh,
37// -eNurbs,
38// -ePatch,
39// -eCamera,
40// -eCameraStereo,
41// -eCameraSwitcher,
42// -eLight,
43// -eOpticalReference,
44// -eOpticalMarker,
45// -eNurbsCurve,
46// -eTrimNurbsSurface,
47// -eBoundary,
48// -eNurbsSurface,
49// -eShape,
50// -eLODGroup,
51// -eSubDiv,
52// -eCachedEffect,
53// -eLine
54
55FbxNodeAttribute::EType et = lNodeAttribute->GetAttributeType();
56if( et == FbxNodeAttribute::eUnknown ) {
57return "eUnknown";
58}
59if( et == FbxNodeAttribute::eNull ) {
60return "eNull";
61}
62if( et == FbxNodeAttribute::eMarker ) {
63return "eMarker";
64}
65if( et == FbxNodeAttribute::eSkeleton ) {
66return "eSkeleton";
67}
68if (et == FbxNodeAttribute::eMesh ) {
69return "eMesh";
70}
71if( et == FbxNodeAttribute::eNurbs ) {
72return "eNurbs";
73}
74if(et == FbxNodeAttribute::ePatch) {
75return "ePatch";
76}
77if(et == FbxNodeAttribute::eCamera) {
78return "eCamera";
79}
80if(et == FbxNodeAttribute::eCameraStereo) {
81return "eCameraStereo";
82}
83if(et == FbxNodeAttribute::eCameraSwitcher) {
84return "eCameraSwitcher";
85}
86if(et == FbxNodeAttribute::eLight) {
87return "eLight";
88}
89if( et == FbxNodeAttribute::eOpticalReference ) {
90return "eOpticalReference";
91}
92if( et == FbxNodeAttribute::eOpticalMarker ) {
93return "eOpticalMarker";
94}
95if( et == FbxNodeAttribute::eNurbsCurve ) {
96return "eNurbsCurve";
97}
98if( et == FbxNodeAttribute::eTrimNurbsSurface ) {
99return "eTrimNurbsSurface";
100}
101if( et == FbxNodeAttribute::eBoundary ) {
102return "eBoundary";
103}
104if(et == FbxNodeAttribute::eNurbsSurface) {
105return "eNurbsSurface";
106}
107if( et == FbxNodeAttribute::eShape ) {
108return "eShape";
109}
110if( et == FbxNodeAttribute::eLODGroup ) {
111return "eLODGroup";
112}
113if( et == FbxNodeAttribute::eSubDiv ) {
114return "eSubDiv";
115}
116if( et == FbxNodeAttribute::eCachedEffect ) {
117return "eCachedEffect";
118}
119if( et == FbxNodeAttribute::eLine ) {
120return "eLine";
121}
122return ("default - "+ofToString((int)et));
123}
124return "default - no attribute";
125}
126
127//----------------------------------------
128string Node::getFbxTypeString() {
129return Node::getFbxTypeStringFromNode( mFbxNode );
130}
131
132//----------------------------------------
133string Node::getNodeTypeAsString( NodeType atype ) {
134if( atype == OFX_FBX_NULL ) {
135return "Null";
136} else if( atype == OFX_FBX_MESH ) {
137return "Mesh";
138} else if( atype == OFX_FBX_SKELETON ) {
139return "Skeleton";
140} else if( atype == OFX_FBX_BONE ) {
141return "Bone";
142} else if( atype == OFX_FBX_NURBS_CURVE ) {
143return "Nurbs Curve";
144}
145//OFX_FBX_UNKNOWN
146return "Unknown";
147}
148
149//----------------------------------------
150string Node::getTypeAsString() {
151return Node::getNodeTypeAsString(getType());
152}
153
154//----------------------------------------
155void Node::setup( FbxNode *pNode ) {
156setName( pNode->GetNameOnly() );
157mFbxNode = pNode;
158}
159
160//----------------------------------------
161string Node::getName() {
162return name;
163}
164
165//----------------------------------------
166FbxString Node::getFbxName() {
167return FbxString( name.c_str() );
168}
169
170//----------------------------------------
171void Node::setName( FbxString aName ) {
172name = aName;
173}
174
175//--------------------------------------------------------------
176void Node::setUseKeyFrames( bool ab ) {
177bUseKeyFrames = ab;
178}
179
180//--------------------------------------------------------------
181bool Node::usingKeyFrames() {
182return bUseKeyFrames;
183}
184
185//--------------------------------------------------------------
186void Node::clearKeyFrames() {
187mKeyCollections.clear();
188}
189
190//--------------------------------------------------------------
191void Node::cacheStartTransforms() {
192// cache the orientations for use later //
193origGlobalRotation = getGlobalOrientation();
194origLocalRotation = getOrientationQuat();
195origGlobalTransform = getGlobalTransformMatrix();
196origLocalTransform = getLocalTransformMatrix();
197origPos = getPosition();
198origScale = getScale();
199}
200
201//----------------------------------------
202void Node::update( FbxTime& pTime, FbxPose* pPose ) {
203if( mFbxNode ) {
204if( !mFbxNode->GetParent() ) {
205FbxAMatrix lGlobalPosition = GetGlobalPosition(mFbxNode, pTime, NULL );
206setLocalTransformMatrix(lGlobalPosition);
207} else {
208FbxAMatrix lLocalPosition = GetLocalPositionForNode(mFbxNode, pTime, NULL );
209setLocalTransformMatrix(lLocalPosition);
210}
211}
212}
213
214//----------------------------------------
215void Node::update( int aAnimIndex, signed long aMillis ) {
216if( aAnimIndex < 0 ) return;
217if( mKeyCollections.size() == 0 ) return;
218if( aAnimIndex >= mKeyCollections.size() ) return;
219
220glm::vec3 tpos = getKeyTranslation( aAnimIndex, aMillis );
221glm::vec3 cpos = getPosition();
222if( cpos.x != tpos.x || cpos.y != tpos.y || cpos.z != tpos.z ) {
223setPosition( tpos );
224}
225
226glm::vec3 tscale = getKeyScale( aAnimIndex, aMillis );
227glm::vec3 cscale = getScale();
228if( cscale.x != tscale.x || cscale.y != tscale.y || cscale.z != tscale.z ) {
229setScale( tscale );
230}
231
232ofQuaternion tquat = getKeyRotation( aAnimIndex, aMillis );
233ofQuaternion cquat = getOrientationQuat();
234if( cquat.x() != tquat.x() || cquat.y() != tquat.y() || cquat.z() != tquat.z() || cquat.w() != tquat.w() ) {
235setOrientation( tquat );
236}
237}
238
239//----------------------------------------
240void Node::update( int aAnimIndex1, signed long aAnim1Millis, int aAnimIndex2, signed long aAnim2Millis, float aMixPct ) {
241if( mKeyCollections.size() == 0 ) return;
242if( aAnimIndex1 < 0 ) return;
243if( aAnimIndex1 >= mKeyCollections.size() ) return;
244if( aAnimIndex2 < 0 ) return;
245if( aAnimIndex2 >= mKeyCollections.size() ) return;
246
247aMixPct = ofClamp(aMixPct, 0.0, 1.0);
248float invpct = 1.0 - aMixPct;
249
250glm::vec3 tpos1 = getKeyTranslation( aAnimIndex1, aAnim1Millis );
251glm::vec3 tpos2 = getKeyTranslation( aAnimIndex2, aAnim2Millis);
252
253glm::vec3 tscale1 = getKeyScale( aAnimIndex1, aAnim1Millis );
254glm::vec3 tscale2 = getKeyScale( aAnimIndex2, aAnim2Millis );
255
256ofQuaternion tquat1 = getKeyRotation( aAnimIndex1, aAnim1Millis );
257ofQuaternion tquat2 = getKeyRotation( aAnimIndex2, aAnim2Millis );
258
259
260if( aMixPct <= 0.0f ) {
261setPosition( tpos1 );
262setScale(tscale1);
263setOrientation(tquat1);
264} else if( aMixPct >= 1.0 ) {
265setPosition( tpos2 );
266setScale(tscale2);
267setOrientation(tquat2);
268} else {
269setPosition( tpos1 * invpct + tpos2 * aMixPct );
270setScale( tscale1 * invpct + tscale2 * aMixPct );
271tquat1.slerp( aMixPct, tquat1, tquat2 );
272setOrientation( tquat1 );
273}
274}
275
276//----------------------------------------
277glm::vec3 Node::getKeyTranslation( int aAnimIndex, signed long aMillis ) {
278if( aAnimIndex < 0 ) return origPos;
279if( mKeyCollections.size() == 0 ) return origPos;
280if( aAnimIndex >= mKeyCollections.size() ) return origPos;
281
282AnimKeyCollection& tcollection = mKeyCollections[aAnimIndex];
283mAnimIndex = aAnimIndex;
284glm::vec3 tpos = origPos;
285if(tcollection.posKeysX.size() > 0) tpos.x = getKeyValue( tcollection.posKeysX, aMillis );
286if(tcollection.posKeysY.size() > 0) tpos.y = getKeyValue( tcollection.posKeysY, aMillis );
287if(tcollection.posKeysZ.size() > 0) tpos.z = getKeyValue( tcollection.posKeysZ, aMillis );
288return tpos;
289}
290
291//----------------------------------------
292ofQuaternion Node::getKeyRotation( int aAnimIndex, signed long aMillis ) {
293if( aAnimIndex < 0 ) return origLocalRotation;
294if( mKeyCollections.size() == 0 ) return origLocalRotation;
295if( aAnimIndex >= mKeyCollections.size() ) return origLocalRotation;
296
297AnimKeyCollection& tcollection = mKeyCollections[aAnimIndex];
298mAnimIndex = aAnimIndex;
299
300return getKeyRotation( tcollection.rotKeys, aMillis );
301}
302
303//----------------------------------------
304glm::vec3 Node::getKeyScale( int aAnimIndex, signed long aMillis ) {
305if( aAnimIndex < 0 ) return origScale;
306if( mKeyCollections.size() == 0 ) return origScale;
307if( aAnimIndex >= mKeyCollections.size() ) return origScale;
308
309AnimKeyCollection& tcollection = mKeyCollections[aAnimIndex];
310mAnimIndex = aAnimIndex;
311
312glm::vec3 tscale = origScale;
313if(tcollection.scaleKeysX.size() > 0) tscale.x = getKeyValue( tcollection.scaleKeysX, aMillis );
314if(tcollection.scaleKeysY.size() > 0) tscale.y = getKeyValue( tcollection.scaleKeysY, aMillis );
315if(tcollection.scaleKeysZ.size() > 0) tscale.z = getKeyValue( tcollection.scaleKeysZ, aMillis );
316
317return tscale;
318}
319
320//----------------------------------------
321// from Arturo Castro's ofxFBX ///
322float Node::getKeyValue( vector<AnimKey<float> >& keys, signed long ms ) {
323for(int i=0;i<keys.size();i++){
324if(keys[i].millis==ms){
325return keys[i].value;
326}else if(keys[i].millis>ms){
327if(i>0){
328signed long delta = ms - keys[i-1].millis;
329float pct = double(delta) / double(keys[i].millis - keys[i-1].millis);
330return ofLerp(keys[i-1].value,keys[i].value,pct);
331}else{
332return keys[0].value;
333//u_long delta = ms;
334//float pct = double(delta) / double(keys[i].millis);
335//return ofLerp(0.0f,keys[i].value,pct);
336}
337}
338}
339if(keys.empty()){
340return 0.0f;
341}else{
342return keys.back().value;
343}
344return 0.0f;
345}
346
347//----------------------------------------
348// from Arturo Castro's ofxFBX ///
349ofQuaternion Node::getKeyRotation(vector<AnimKey<ofQuaternion> >& keys, signed long ms) {
350for(int i=0;i<keys.size();i++){
351if(keys[i].millis==ms){
352return keys[i].value;
353}else if(keys[i].millis>ms){
354if(i>0){
355signed long delta = ms - keys[i-1].millis;
356float pct = double(delta) / double(keys[i].millis - keys[i-1].millis);
357ofQuaternion q;
358q.slerp(pct,keys[i-1].value,keys[i].value);
359return q;
360}else{
361signed long delta = ms;
362float pct = double(delta) / double(keys[i].millis);
363ofQuaternion q = keys[i].value;
364q.slerp(pct,origLocalRotation,keys[i].value);
365return q;
366}
367}
368}
369if(keys.empty()){
370return origLocalRotation;
371}else{
372return keys.back().value;
373}
374return origLocalRotation;
375}
376
377//----------------------------------------
378AnimKeyCollection& Node::getKeyCollection( int aAnimIndex ) {
379if( mKeyCollections.count(aAnimIndex) < 1 ) {
380AnimKeyCollection temp;
381mKeyCollections[ aAnimIndex ] = temp;
382}
383return mKeyCollections[aAnimIndex];
384}
385
386//----------------------------------------
387//void Node::setGlobalTransformMatrix( FbxAMatrix ainput ) {
388// glm::vec3 tpos, tscale;
389// glm::quat trot;
390//
391// fbxToGlmComponents( ainput, tpos, trot, tscale );
392//
393// setScale( tscale );
394// setGlobalPosition( tpos );
395// setGlobalOrientation( trot);
396//}
397
398//----------------------------------------
399void Node::setLocalTransformMatrix( FbxAMatrix ainput ) {
400glm::vec3 tpos, tscale;
401glm::quat trot;
402
403fbxToGlmComponents( ainput, tpos, trot, tscale );
404
405setScale( tscale );
406setPosition( tpos );
407setOrientation( trot);
408}
409
410//----------------------------------------
411void Node::clearChildren() {
412mKids.clear();
413}
414
415//----------------------------------------
416void Node::addChild( shared_ptr<Node> akiddo ) {
417mKids.push_back( akiddo );
418}
419
420//----------------------------------------
421int Node::getNumChildren() {
422return mKids.size();
423}
424
425//----------------------------------------
426vector< shared_ptr<Node> >& Node::getChildren() {
427return mKids;
428}
429
430//--------------------------------------------------------------
431string Node::getAsString( int aLevel ) {
432stringstream oStr;// = "";
433for( int i = 0; i < aLevel; i++ ) {
434oStr << " ";
435}
436if( aLevel > 0 ) {
437oStr <<" '";
438}
439if( mKids.size() ) {
440oStr << "+ ";
441} else {
442oStr << "- ";
443}
444// string pname = "";
445// if( getParent() != NULL ) {
446// pname = " parent: " + parentBoneName;
447// }
448oStr << getTypeAsString() << ": " << getName() << " fbx type: " << getFbxTypeString();
449if( getNumChildren() > 0 ) {
450oStr << " kids: " << mKids.size();
451}
452if(usingKeyFrames()) {
453oStr << " num keys collections: " << mKeyCollections.size();
454}
455oStr << endl;// "\n";
456
457for( auto& kid : mKids ) {
458oStr << kid->getAsString( aLevel + 1);
459}
460
461return oStr.str();
462}
463
464//#pragma mark - Search
465//--------------------------------------------------------------
466//shared_ptr<Node> Node::getNodeforName( shared_ptr<Node>& aBSelf, string aPath, bool bStrict ) {
467// vector< string > tsearches;
468// if( ofIsStringInString( aPath, ":" ) ) {
469// tsearches = ofSplitString( aPath, ":" );
470// } else {
471// tsearches.push_back( aPath );
472// if(aBSelf) {
473// if(bStrict) {
474// if( aBSelf->getName() == aPath ) {
475// // cout << "FOUND SELF" << endl;
476// return aBSelf;
477// }
478// } else {
479// if( ofIsStringInString( aBSelf->getName(), aPath )) {
480// // cout << "FOUND SELF" << endl;
481// return aBSelf;
482// }
483// }
484// }
485// }
486//
487// shared_ptr<Node> temp;// = aBSelf;
488// _getNodeForNameRecursive( tsearches, temp, mKids, bStrict );
489// return temp;
490//}
491//
492////--------------------------------------------------------------
493//shared_ptr<Node> Node::getKidforName( string aPath, bool bStrict ) {
494//
495// vector< string > tsearches;
496// if( ofIsStringInString( aPath, ":" ) ) {
497// tsearches = ofSplitString( aPath, ":" );
498// } else {
499// tsearches.push_back( aPath );
500// }
501//
502// shared_ptr<Node> temp;
503// _getNodeForNameRecursive( tsearches, temp, mKids, bStrict );
504// return temp;
505//}
506//
507////--------------------------------------------------------------
508//void Node::_getNodeForNameRecursive( vector<string>& aNamesToFind, shared_ptr<Node>& aTarget, vector< shared_ptr<Node> >& aElements, bool bStrict ) {
509//
510// for( int i = 0; i < aElements.size(); i++ ) {
511// bool bFound = false;
512// if(bStrict) {
513// if( aElements[i]->getName() == aNamesToFind[0] ) {
514// bFound = true;
515// }
516// } else {
517// if( ofIsStringInString( aElements[i]->getName(), aNamesToFind[0] )) {
518// // cout << "Found--- " << aNamesToFind[0] << " num names: " << aNamesToFind.size() << endl;
519// bFound = true;
520// }
521// }
522//
523// if( bFound == true ) {
524// aNamesToFind.erase( aNamesToFind.begin() );
525// if( aNamesToFind.size() == 0 ) {//}|| aElements[i]->getNumChildren() < 1 ) {
526// bool bgood = false;
527// if( aElements[i] ) {
528// bgood = true;
529// }
530// // cout << "going to return one of the elements " << aNamesToFind.size() << " good: " << bgood << " " << endl;
531// aTarget = aElements[i];
532// break;
533// } else {
534// if( aElements[i]->getNumChildren() > 0 ) {
535//// shared_ptr<Node> tgroup = dynamic_pointer_cast< ofxSvgGroup >( aElements[i] );
536// _getNodeForNameRecursive( aNamesToFind, aTarget, aElements[i]->getChildren(), bStrict );
537// break;
538// }
539// }
540// }
541// }
542//
543//
544//}
545