framework2

Форк
0
933 строки · 30.1 Кб
1
//
2
//  ofxFBXManager.cpp
3
//  ScenesSetup_Nick
4
//
5
//  Created by Nick Hardeman on 12/20/13.
6
//
7
//
8

9
#include "ofxFBX.h"
10

11
ofxFBXAnimation dummyAnimation;
12

13
vector< shared_ptr<ofxFBXSource::Scene> > ofxFBX::mCachedScenes;
14

15
//--------------------------------------------------------------
16
ofxFBX::ofxFBX() {
17
    bAnimationsEnabled              = true;
18
    animationIndex                  = 0;
19
    dummyAnimation.name             = "dummy";
20
    poseIndex                       = 0;
21
    bPosesEnabled                   = false;
22
    currentAnimationStack           = NULL;
23
}
24

25
//--------------------------------------------------------------
26
ofxFBX::~ofxFBX() {
27
    clear();
28
//    for( int i = 0; i < mSkeletons.size(); i++ ) {
29
//        mSkeletons[i]->clearParent();
30
////        skeletons[i]->root.clearParent();
31
//    }
32
//    mSkeletons.clear();
33
//
34
//    if( mSceneInternal ) {
35
//        if( fbxScene != NULL && fbxScene->getSettings().unloadIfUnused ) {
36
//            mSceneInternal.reset();
37
//            ofRemove( mCachedScenes, shouldRemoveScene );
38
//
39
//            ofLogVerbose("~ofxFBXManager :: mCachedScenes : size(): ") << mCachedScenes.size();
40
//        }
41
//    }
42
}
43

44
//--------------------------------------------------------------
45
bool ofxFBX::shouldRemoveScene( const shared_ptr<ofxFBXSource::Scene>& ascene ) {
46
    return (!ascene || ascene.use_count() <= 1); // only stored in the cache //
47
}
48

49
//--------------------------------------------------------------
50
bool ofxFBX::load(ofxFBXSource::Scene::Settings aSettings ) {
51
    return load( aSettings.filePath, aSettings );
52
}
53

54
//--------------------------------------------------------------
55
void ofxFBX::clear() {
56
    for( auto node : mAllNodes ) {
57
        node->clearParent();
58
    }
59
    
60
    mSkeletons.clear();
61
    poses.clear();
62
    meshes.clear();
63
    mNurbsCurves.clear();
64
    mNullNodes.clear();
65
    animations.clear();
66
    mRootNodes.clear();
67
    mAllNodes.clear();
68
    
69
//    for( int i = 0; i < mSkeletons.size(); i++ ) {
70
//        mSkeletons[i]->clearParent();
71
////        skeletons[i]->root.clearParent();
72
//    }
73
//    mSkeletons.clear();
74
    
75
    if( mSceneInternal ) {
76
        if( fbxScene != NULL && fbxScene->getSettings().unloadIfUnused ) {
77
            mSceneInternal.reset();
78
            ofRemove( mCachedScenes, shouldRemoveScene );
79
            ofLogVerbose("~ofxFBXManager :: mCachedScenes : size(): ") << mCachedScenes.size();
80
        }
81
    }
82
}
83

84
//--------------------------------------------------------------
85
bool ofxFBX::load( string path, ofxFBXSource::Scene::Settings aSettings ) {
86
    
87
    if( !ofFile::doesFileExist(path)) {
88
        ofLogError("ofxFBX::load()") << " File does not exist!!: " << path << " :(";
89
        return false;
90
    }
91
    
92
    // check to see if we already have a scene cached //
93
    string fpath = ofToDataPath(path);
94
    if( mSceneInternal && mSceneInternal->getFbxFilePath() == fpath ) {
95
        ofLogNotice("ofxFBX::load() already have this scene loaded") << mSceneInternal->getFbxFilePath();
96
        return true;
97
    }
98
    
99
    // clean up the internal scene if it is present //
100
    clear();
101
    
102
    for( auto scene : mCachedScenes ) {
103
        if( scene->getFbxFilePath() == fpath ) {
104
            mSceneInternal = scene;
105
            break;
106
        }
107
    }
108
    if( !mSceneInternal ) {
109
        mSceneInternal = make_shared<ofxFBXSource::Scene>();
110
        if( mSceneInternal->load( path, aSettings )) {
111
            mCachedScenes.push_back( mSceneInternal );
112
        } else {
113
            mSceneInternal.reset();
114
        }
115
    }
116
//    for( int i = 0; i < mCachedScenes.size(); i++ ) {
117
//        cout << i << " - " << "ofxFBXManager :: load : " << mCachedScenes[i]->getFbxFilePath() << endl;
118
//    }
119
    
120
    
121
    if( mSceneInternal ) {
122
        setup( mSceneInternal.get() );
123
        return true;
124
    }
125
    
126
    return false;
127
}
128

129
//--------------------------------------------------------------
130
void ofxFBX::setup( ofxFBXSource::Scene* aScene ) {
131
    fbxScene = aScene;
132
    if(fbxScene == NULL ) {
133
        ofLogError("ofxFBXManager::setup : ofxFBXScene is NULL, make sure set and load the ofxFBXScene!");
134
        return;
135
    }
136
    if(fbxScene->getFBXScene() == NULL) {
137
        ofLogWarning("ofxFBXManager::setup : FbxScene is NULL, make sure to not unload the ofxFBXScene!");
138
        return;
139
    }
140
    
141
//    cout << "ofxFBX::setup : parsing ofxFBXSource :: " << fbxScene->getFbxFilePath() << endl;
142
    
143
    // clear out any existing data //
144
    mSkeletons.clear();
145
    poses.clear();
146
    meshes.clear();
147
    mNurbsCurves.clear();
148
    mNullNodes.clear();
149
    animations.clear();
150
    mRootNodes.clear();
151
    mAllNodes.clear();
152
    
153
    // see if we are using keyframes //
154
    bUsingKeyframes = fbxScene->getSettings().useKeyFrames;
155
    
156
    aScene->populateAnimations( animations );
157
    
158
    // we need to parse the nodes from the scene to preserve the hierarchy //
159
    vector< shared_ptr<ofxFBXSource::Node> > fsceneNodes = fbxScene->getSceneNodes();
160
    shared_ptr<ofxFBXNode> tempParentNode;
161
    for( auto snode : fsceneNodes ) {
162
        _parseSceneNodesRecursive( snode, tempParentNode );
163
    }
164
    
165
    for( auto& tskel : mSkeletons ) {
166
        tskel->setupRoot(tskel);
167
    }
168
    
169
    aScene->populatePoses( poses );
170
    
171
    // check the fbx scene if the mesh keyframes have been cached //
172
    if( aScene->getSettings().cacheMeshKeyframes ) {
173
        cacheMeshKeyframes( aScene->getSettings().blendCachedMeshKeyframes );
174
    }
175
    
176
    if( hasAnimations() ) {
177
        // set to the first animation
178
        setAnimation(0);
179
    }
180
    
181
}
182

183
//--------------------------------------------------------------
184
void ofxFBX::_parseSceneNodesRecursive( shared_ptr<ofxFBXSource::Node> anode, shared_ptr<ofxFBXNode> aParentNode ) {
185
    if( !anode ) return;
186
    
187
    shared_ptr<ofxFBXNode> newNode;
188
    ofxFBXSource::Node::NodeType ftype = anode->getType();
189
    if (ftype == ofxFBXSource::Node::OFX_FBX_MESH) {
190
        auto tmesh = make_shared<ofxFBXMesh>();
191
        if( tmesh ) {
192
            meshes.push_back( tmesh );
193
            newNode = tmesh;
194
        }
195
    } else if(ftype == ofxFBXSource::Node::OFX_FBX_NURBS_CURVE) {
196
        auto tcurve = make_shared<ofxFBXNurbsCurve>();
197
        if( tcurve ) {
198
            mNurbsCurves.push_back(tcurve);
199
            newNode = tcurve;
200
        }
201
    } else if(ftype == ofxFBXSource::Node::OFX_FBX_NULL ) {
202
        auto tnull = make_shared<ofxFBXNode>();
203
        if( tnull ) {
204
            mNullNodes.push_back(tnull);
205
            newNode = tnull;
206
        }
207
    } else if( ftype == ofxFBXSource::Node::OFX_FBX_SKELETON ) {
208
        auto tskel = make_shared<ofxFBXSkeleton>();
209
        if( tskel ) {
210
            mSkeletons.push_back( tskel );
211
            newNode = tskel;
212
        }
213
    }
214
    
215
    if( newNode ) {
216
        if( aParentNode ) {
217
            aParentNode->addChild( newNode );
218
            newNode->setParent( *aParentNode );
219
            newNode->setParentNode( aParentNode );
220
        } else {
221
            newNode->setParent( *this );
222
            mRootNodes.push_back( newNode );
223
        }
224
        newNode->setup( anode );
225
        mAllNodes.push_back( newNode );
226
    }
227
    
228
    for( int i = 0; i < anode->getNumChildren(); i++ ) {
229
        _parseSceneNodesRecursive( anode->getChildren()[i], newNode );
230
    }
231
}
232

233
//--------------------------------------------------------------
234
void ofxFBX::earlyUpdate(float aElapsedSeconds) {
235
    FbxPose * lPose = NULL;
236
    // poses will override the animations and the settings of the bones //
237
    if( arePosesEnabled() && hasPoses() && (poseIndex >= 0 && poseIndex < getNumPoses() ) ) {
238
        cout << "Got a pose | " << ofGetFrameNum() << endl;
239
        lPose = fbxScene->getFBXScene()->GetPose( poseIndex );
240
    }
241
    
242
    if( !areAnimationsEnabled() || !hasAnimations() ) {
243
        if( bFirstRun ) {
244
            FbxTime ttime(FBXSDK_TIME_INFINITE);
245
            //        cout << "Calling update bones: " << " | " << ofGetElapsedTimef() << endl;
246
            for( auto& node : mAllNodes ) {
247
//                if( node->getType() == ofxFBXSource::Node::OFX_FBX_SKELETON ) {
248
                    node->update( ttime, lPose );
249
                    node->update();
250
//                }
251
            }
252
        }
253
        
254
    }
255
    
256
    if(animations.size() < 1) return;
257
    if(!areAnimationsEnabled()) return;
258
    
259
    
260
    float etimef = aElapsedSeconds;//ofGetElapsedTimef();
261
    if (etimef < 0) {
262
        etimef = ofGetElapsedTimef();
263
    }
264
    //    cout << "Should not be reaching here: ofxFBXManager :: update | " << ofGetFrameNum() << endl;
265
    
266
    animations[animationIndex].update(etimef);
267
    if( mAnimTrans.bActive ) {
268
        animations[mAnimTrans.animIndex2].update(etimef);
269
    }
270
    
271
    
272
    
273
    if( currentAnimationStack != NULL ) {
274
        fbxScene->getFBXScene()->SetCurrentAnimationStack( currentAnimationStack );
275
    }
276
    
277
    //    cout << "ofxFBXManager :: update : animations | " << ofGetElapsedTimef() << endl;
278
    // TODO: is there a way to check if we need to update the bone positions? Right now it always updates.
279
    // If other fbxManagers are playing animations at different times or moving around bones, then it will get weird if it doesn't
280
    // update.  //
281
    //    if(animations[animationIndex].isFrameNew() || animations[animationIndex].isPaused() ) {
282
    signed long tFbxAnimTime = (signed long)animations[animationIndex].fbxCurrentTime.GetMilliSeconds();
283
    signed long tFbxAnimTime2 = 0;
284
    if( mAnimTrans.bActive ) {
285
        tFbxAnimTime2 = (signed long)animations[mAnimTrans.animIndex2].fbxCurrentTime.GetMilliSeconds();
286
    }
287
    
288
    for( auto& node : mAllNodes ) {
289
        if( bUsingKeyframes ) {
290
            if( mAnimTrans.bActive ) {
291
                node->update( mAnimTrans.animIndex1, tFbxAnimTime, mAnimTrans.animIndex2, tFbxAnimTime2, mAnimTrans.percent );
292
            } else {
293
                node->update( animationIndex, tFbxAnimTime );
294
            }
295
        } else {
296
            node->update( animations[animationIndex].fbxCurrentTime, lPose );
297
        }
298
        node->update();
299
    }
300
    
301
    if( mAnimTrans.bActive ) {
302
//        float etimef = aElapsedSeconds;//ofGetElapsedTimef();
303
//        if (etimef < 0) {
304
//            etimef = ofGetElapsedTimef();
305
//        }
306
        mAnimTrans.percent = (etimef - mAnimTrans.startTime) / mAnimTrans.duration;
307
        if( mAnimTrans.percent >= 1.f ) {
308
            mAnimTrans.percent = 1.0;
309
            animationIndex = mAnimTrans.animIndex2; // switch to the targeted animation
310
            mAnimTrans.bActive = false;
311
        }
312
    }
313
}
314

315
//--------------------------------------------------------------
316
void ofxFBX::update(float aElapsedSeconds) {
317
    earlyUpdate(aElapsedSeconds);
318
    lateUpdate();
319
}
320

321
//--------------------------------------------------------------
322
void ofxFBX::lateUpdate() {
323
    
324
    if( !areAnimationsEnabled() || !hasAnimations() ) {
325
        if( bFirstRun ) {
326
            FbxTime ttime(FBXSDK_TIME_INFINITE);
327
            for( auto& node : mAllNodes ) {
328
                node->lateUpdate(ttime, currentFbxAnimationLayer, NULL);
329
            }
330
        }
331
    }
332
    
333
    if(animations.size() > 0 && areAnimationsEnabled() ) {
334
        for( auto& node : mAllNodes ) {
335
            node->lateUpdate(animations[animationIndex].fbxCurrentTime, currentFbxAnimationLayer, NULL);
336
        }
337
    }
338
    
339
    if(!bUpdateMeshVbo) {
340
        // tell all of the meshes not to update the vbo //
341
        for( auto& m : meshes ) {
342
            m->setMeshDirty(false);
343
        }
344
    }
345
    
346
    bFirstRun = false;
347
}
348

349
#pragma mark - Draw
350
//--------------------------------------------------------------
351
void ofxFBX::draw() {
352
    drawMeshes();
353
    drawCurves();
354
}
355

356
//--------------------------------------------------------------
357
void ofxFBX::drawMesh(int aindex) {
358
	if (aindex < 0 || aindex >= meshes.size()) {
359
		return;
360
	}
361
    meshes[aindex]->draw();
362
}
363

364
//--------------------------------------------------------------
365
void ofxFBX::drawMeshWireframe(int aindex) {
366
	if (aindex < 0 || aindex >= meshes.size()) {
367
		return;
368
	}
369
    meshes[aindex]->drawWireframe();
370
}
371

372
//--------------------------------------------------------------
373
void ofxFBX::drawMeshes() {
374
    for( auto& tmesh : meshes ) {
375
        tmesh->draw();
376
    }
377
}
378

379
//--------------------------------------------------------------
380
void ofxFBX::drawMeshWireframes() {
381
    for( auto& tmesh : meshes ) {
382
        tmesh->drawWireframe();
383
    }
384
}
385

386
//--------------------------------------------------------------
387
void ofxFBX::drawMeshNormals( float aLen, bool aBFaceNormals ) {
388
    for( auto& tmesh : meshes ) {
389
        tmesh->drawNormals(aLen, aBFaceNormals);
390
    }
391
}
392

393
//--------------------------------------------------------------
394
void ofxFBX::drawSkeletons( float aLen, bool aBDrawAxes ) {
395
    for(int i = 0; i < mSkeletons.size(); i++ ) {
396
        mSkeletons[i]->draw( aLen, aBDrawAxes );
397
    }
398
}
399

400
//--------------------------------------------------------------
401
void ofxFBX::drawCurves() {
402
    for( auto& nc : mNurbsCurves ) {
403
        nc->draw();
404
    }
405
}
406

407
#pragma mark - Getters
408

409
//--------------------------------------------------------------
410
string ofxFBX::getInfoString() {
411
    stringstream ss;
412
    if(fbxScene) {
413
        ss << "ofxFBX :: " << ofFilePath::getBaseName(fbxScene->getFbxFilePath())<<"."<<ofFilePath::getFileExt(fbxScene->getFbxFilePath()) << endl;
414
    }
415
    for( auto& sn : mRootNodes ) {
416
        ss << sn->getAsString();
417
    }
418
    return ss.str();
419
}
420

421
//--------------------------------------------------------------
422
ofxFBXSource::Scene* ofxFBX::getFbxScene() {
423
    return fbxScene;
424
}
425

426
//--------------------------------------------------------------
427
string ofxFBX::getFbxFilePath() {
428
    if( fbxScene ) {
429
        return fbxScene->getFbxFilePath();
430
    }
431
    return "";
432
}
433

434
#pragma mark Null Nodes
435
//--------------------------------------------------------------
436
vector< shared_ptr<ofxFBXNode> >& ofxFBX::getNullNodes() {
437
    return mNullNodes;
438
}
439

440
//--------------------------------------------------------------
441
int ofxFBX::getNumNullNodes() {
442
    return mNullNodes.size();
443
}
444

445
#pragma mark Meshes
446
//--------------------------------------------------------------
447
vector< shared_ptr<ofxFBXMesh> >& ofxFBX::getMeshes() {
448
    return meshes;
449
}
450

451
//--------------------------------------------------------------
452
int ofxFBX::getNumMeshes() {
453
    return (int)meshes.size();
454
}
455

456
//--------------------------------------------------------------
457
string ofxFBX::getMeshName( int aMeshIndex ) {
458
    return meshes[aMeshIndex]->getName();//fbxScene->getMeshes()[aMeshIndex]->getName();
459
}
460

461
//--------------------------------------------------------------
462
void ofxFBX::setMaterialsEnabled( bool ab ) {
463
    for( auto mesh : meshes ) {
464
        mesh->setMaterialsEnabled( ab );
465
    }
466
}
467

468
//--------------------------------------------------------------
469
vector< shared_ptr<ofxFBXSource::MeshTexture> > ofxFBX::getSourceTextures() {
470
    vector< shared_ptr<ofxFBXSource::MeshTexture> > rtexs;
471
    for( auto mesh : meshes ) {
472
        auto mats = mesh->getMaterials();
473
        for( auto mat : mats ) {
474
            if( mat->hasSourceTexture() ) {
475
                rtexs.push_back( mat->getSrcTexture() );
476
            }
477
        }
478
    }
479
    return rtexs;
480
}
481

482
//--------------------------------------------------------------
483
int ofxFBX::getNumSourceTextures() {
484
    int tnum = 0;
485
    for( auto mesh : meshes ) {
486
        auto mats = mesh->getMaterials();
487
        for( auto mat : mats ) {
488
            if( mat->hasSourceTexture() ) {
489
                tnum++;
490
            }
491
        }
492
    }
493
    return tnum;
494
}
495

496
//--------------------------------------------------------------
497
void ofxFBX::setMeshesDirty( bool ab ) {
498
    for( auto mesh : meshes ) {
499
        mesh->setMeshDirty( ab );
500
    }
501
}
502

503
//--------------------------------------------------------------
504
void ofxFBX::cacheMeshKeyframes( bool aBlendMeshKeys ) {
505
    if( fbxScene == NULL ) return;
506
    
507
    if( !fbxScene->getSettings().useKeyFrames ) {
508
        ofLogWarning("ofxFBX :: cacheMeshKeyframes : must use .useKeyFrames when loading scene in Settings ");
509
        return;
510
    }
511
    
512
//    if( fbxScene->areMeshKeyframesCached() ) {
513
//        return;
514
//    }
515
    
516
    if( !fbxScene->areMeshKeyframesCached() ) {
517
        
518
        ofLogNotice(" ofxFBX :: cacheMeshKeyframes : ") << getFbxFilePath();
519
        
520
        // one mesh per keyframe per animation //
521
        for( int ia = 0; ia < animations.size(); ia++ ) {
522
            setAnimation(ia);
523
            auto& tanim = getCurrentAnimation();
524
            
525
            ofLogNotice( "ofxFBX :: cacheMeshKeyframes : animation: " ) << tanim.name << " num key frames: " << tanim.getTotalNumFrames();
526
            
527
            for( int i = 0; i < tanim.getTotalNumFrames(); i++ ) {
528
                tanim.setFrame(i);
529
                signed long tFbxAnimTime = (signed long)tanim.fbxCurrentTime.GetMilliSeconds();
530
                // update all the nodes //
531
                for( auto& node : mAllNodes ) {
532
                    if( bUsingKeyframes ) {
533
                        node->update( ia, tFbxAnimTime );
534
                    } else {
535
                        node->update( tanim.fbxCurrentTime, NULL );
536
                    }
537
                    node->update();
538
                }
539
                
540
                for( auto& node : mAllNodes ) {
541
                    node->lateUpdate( tanim.fbxCurrentTime, currentFbxAnimationLayer, NULL );
542
                    // now we need to cache the meshes in the meshes //
543
                    if( node->getType() == ofxFBXSource::Node::OFX_FBX_MESH && node->getofxFbxSrcNode() ) {
544
                        // now lets cache the mesh //
545
                        shared_ptr<ofxFBXMesh> meshNode = dynamic_pointer_cast<ofxFBXMesh>(node);
546
                        shared_ptr<ofxFBXSource::Mesh> tSrcMesh = dynamic_pointer_cast<ofxFBXSource::Mesh>(node->getofxFbxSrcNode());
547
                        auto& kMeshKeyCollection = tSrcMesh->getMeshKeyCollection(ia);
548
                        ofxFBXSource::MeshAnimKey meshKey;
549
                        meshKey.mesh = meshNode->getMesh();
550
                        meshKey.millis = tFbxAnimTime;
551
                        kMeshKeyCollection.meshKeys.push_back( meshKey );
552
                    }
553
                }
554
            }
555
        }
556
    }
557
    
558
    // disable all of the bones, since the meshes are cached, it will not be influenced by the bones anymore //
559
    for( auto& node : mAllNodes ) {
560
        if( node->getType() == ofxFBXSource::Node::OFX_FBX_BONE ) {
561
            auto bone = dynamic_pointer_cast<ofxFBXBone>(node);
562
            bone->disableAnimation( true );
563
            
564
            if(node->getofxFbxSrcNode()) {
565
                // now disable the source bones //
566
                auto sbone = dynamic_pointer_cast<ofxFBXSource::Bone>(node->getofxFbxSrcNode());
567
                if( sbone ) sbone->disableAnimation(true);
568
            }
569
        }
570
    }
571
    
572
    for( int i = 0; i < mSkeletons.size(); i++ ) {
573
        mSkeletons[i]->disableAnimation();
574
        if( mSkeletons[i]->getofxFbxSrcNode() ) {
575
            auto sskel = dynamic_pointer_cast<ofxFBXSource::Skeleton>(mSkeletons[i]->getofxFbxSrcNode());
576
            if( sskel->root ) {
577
                sskel->root->disableAnimation(true);
578
            }
579
        }
580
        
581
    }
582
    
583
    
584
    // let the source meshes know that they are cached //
585
    for( auto& node : mAllNodes ) {
586
        if( node->getType() == ofxFBXSource::Node::OFX_FBX_MESH && node->getofxFbxSrcNode() ) {
587
            auto mesh = dynamic_pointer_cast<ofxFBXMesh>(node);
588
            if( mesh ) {
589
                mesh->setBlendMeshFrames( aBlendMeshKeys );
590
            }
591
            auto tSrcMesh = dynamic_pointer_cast<ofxFBXSource::Mesh>(node->getofxFbxSrcNode());
592
            if(tSrcMesh) tSrcMesh->setUsingCachedMeshes(true);
593
        }
594
    }
595
    fbxScene->getSettings().cacheMeshKeyframes = true;
596
    fbxScene->setMeshKeyframesCached( true );
597
}
598

599
//--------------------------------------------------------------
600
void ofxFBX::setMeshVboUpdate(bool ab) {
601
    bUpdateMeshVbo=ab;
602
}
603

604
#pragma mark Curves
605
//--------------------------------------------------------------
606
vector< shared_ptr<ofxFBXNurbsCurve> >& ofxFBX::getNurbsCurves() {
607
    return mNurbsCurves;
608
}
609

610
//--------------------------------------------------------------
611
int ofxFBX::getNumNurbsCurves() {
612
    return mNurbsCurves.size();
613
}
614

615
#pragma mark Skeletons
616
//--------------------------------------------------------------
617
vector< shared_ptr<ofxFBXSkeleton> >& ofxFBX::getSkeletons() {
618
    return mSkeletons;
619
}
620

621
//--------------------------------------------------------------
622
bool ofxFBX::hasBones() {
623
    return getNumBones() > 0;
624
}
625

626
//--------------------------------------------------------------
627
int ofxFBX::getNumSkeletons() {
628
    return mSkeletons.size();
629
}
630

631
//--------------------------------------------------------------
632
int ofxFBX::getNumBones() {
633
    int tNumBones = 0;
634
    for( int i = 0; i < mSkeletons.size(); i++ ) {
635
        tNumBones += mSkeletons[i]->getNumBones();
636
    }
637
    return tNumBones;
638
}
639

640
//--------------------------------------------------------------
641
shared_ptr<ofxFBXBone> ofxFBX::getBone( string aBoneName, int aSkeletonIndex ) {
642
    if( aSkeletonIndex < 0 ) return NULL;
643
    if( aSkeletonIndex >= mSkeletons.size() ) return NULL;
644
    return mSkeletons[ aSkeletonIndex ]->getBone( aBoneName );
645
}
646

647
//--------------------------------------------------------------
648
string ofxFBX::getSkeletonInfo() {
649
    string retStr = "";
650
    for( int i = 0; i < mSkeletons.size(); i++ ) {
651
        retStr += ofToString(i,0)+" - " + mSkeletons[i]->getAsString();
652
    }
653
    return retStr;
654
}
655

656
#pragma mark - Poses
657
//--------------------------------------------------------------
658
bool ofxFBX::hasPoses() {
659
    return getNumPoses() > 0;
660
}
661

662
//--------------------------------------------------------------
663
bool ofxFBX::arePosesEnabled() {
664
    return bPosesEnabled;
665
}
666

667
//--------------------------------------------------------------
668
void ofxFBX::enablePoses() {
669
    bPosesEnabled = true;
670
}
671

672
//--------------------------------------------------------------
673
void ofxFBX::disablePoses() {
674
    bPosesEnabled = false;
675
}
676

677
//--------------------------------------------------------------
678
void ofxFBX::togglePosesEnabled() {
679
    if( arePosesEnabled() ) disablePoses();
680
    else enablePoses();
681
}
682

683
//--------------------------------------------------------------
684
int ofxFBX::getNumPoses() {
685
    return (int)poses.size();
686
}
687

688
//--------------------------------------------------------------
689
void ofxFBX::setPoseIndex( int aIndex ) {
690
    aIndex = ofClamp( aIndex, 0, getNumPoses()-1 );
691
    poseIndex = aIndex;
692
}
693

694
//--------------------------------------------------------------
695
shared_ptr< ofxFBXSource::Pose > ofxFBX::getCurrentPose() {
696
    if( hasPoses() && (poseIndex >= 0 && poseIndex < getNumPoses() ) ) {
697
        return poses[ poseIndex ];
698
    }
699
    shared_ptr<ofxFBXSource::Pose> tpose;
700
    return tpose;
701
}
702

703
//--------------------------------------------------------------
704
vector< shared_ptr<ofxFBXSource::Pose> > ofxFBX::getPoses() {
705
    return poses;
706
}
707

708
#pragma mark - Animation
709
//--------------------------------------------------------------
710
int ofxFBX::getNumAnimations() {
711
    return animations.size();
712
}
713

714
//--------------------------------------------------------------
715
int ofxFBX::getCurrentAnimationIndex() {
716
    return animationIndex;
717
}
718

719
//--------------------------------------------------------------
720
ofxFBXAnimation& ofxFBX::getCurrentAnimation() {
721
    if(animations.size() < 1) {
722
        ofLogWarning("ofxFBXAnimation :: return dummy animation, there are no animations");
723
        return dummyAnimation;
724
    }
725
    return animations[ animationIndex ];
726
}
727

728
//--------------------------------------------------------------
729
int ofxFBX::getAnimationIndex( string aname ) {
730
    int findex = -1;
731
    for( int i = 0; i < animations.size(); i++ ) {
732
        if( animations[i].name == aname ) {
733
            findex = i;
734
            break;
735
        }
736
    }
737
    return findex;
738
}
739

740
//--------------------------------------------------------------
741
ofxFBXAnimation& ofxFBX::getAnimation( int aIndex ) {
742
    if( aIndex > animations.size() -1 ) {
743
        ofLogWarning( "ofxFBXManager :: getAnimation : index is too high " ) << aIndex;
744
        aIndex = ofClamp(aIndex, 0, animations.size()-1);
745
    }
746
    
747
    if( aIndex < 0 ) {
748
        ofLogWarning( "ofxFBXManager :: getAnimation : index is too low " ) << aIndex;
749
        return dummyAnimation;
750
    }
751
    
752
    if( animations.size() == 0 ) {
753
        aIndex = 0;
754
        animations.push_back( dummyAnimation );
755
    }
756
    
757
    return animations[ aIndex ];
758
}
759

760
//--------------------------------------------------------------
761
ofxFBXAnimation& ofxFBX::getAnimation( string aname ) {
762
    return getAnimation( getAnimationIndex( aname ) );
763
}
764

765
//--------------------------------------------------------------
766
bool ofxFBX::hasAnimation( string aname ) {
767
    return (getAnimationIndex(aname) > -1);
768
}
769

770
//--------------------------------------------------------------
771
void ofxFBX::setAnimation( int aIndex ) {
772
    
773
    if( aIndex < 0) {
774
        ofLogWarning("ofxFBXManager :: setAnimation : returning because the index is less than 0!");
775
        return;
776
    }
777
    
778
    if(animations.size() < 1) {
779
        ofLogWarning("ofxFBXManager :: setAnimation : returning because there are no animations!");
780
        return;
781
    }
782
    if(aIndex >= animations.size()) {
783
        aIndex = ofClamp(aIndex, 0, animations.size()-1);
784
        ofLogWarning("ofxFBXManager :: setAnimation : index to high, clamping to ") << aIndex;
785
    }
786
    currentAnimationStack = fbxScene->getFBXScene()->FindMember<FbxAnimStack>( (&animations[aIndex].fbxname)->Buffer() );
787
    if (currentAnimationStack == NULL) {
788
        // this is a problem. The anim stack should be found in the scene!
789
        ofLogWarning("ofxFBXManager :: setAnimation : the anim stack was not found in the scene!");
790
        return;
791
    }
792
//    int numAnimLayers = lCurrentAnimationStack->GetMemberCount<FbxAnimLayer>();
793
//    cout << "Number of animation layers= " << numAnimLayers << endl;
794
    currentFbxAnimationLayer = currentAnimationStack->GetMember<FbxAnimLayer>();
795
    fbxScene->getFBXScene()->SetCurrentAnimationStack( currentAnimationStack );
796
    
797
    animationIndex = aIndex;
798
}
799

800
//--------------------------------------------------------------
801
void ofxFBX::setAnimation( string aname ) {
802
    setAnimation( getAnimationIndex( aname ) );
803
}
804

805
//--------------------------------------------------------------
806
void ofxFBX::enableAnimations() {
807
    if(!hasAnimations()) {
808
        ofLogWarning("ofxFBXManager :: enableAnimations : there are no animations in this scene. Disabling.");
809
        disableAnimations();
810
        return;
811
    }
812
    bAnimationsEnabled = true;
813
    for( int i = 0; i < mSkeletons.size(); i++ ) {
814
        mSkeletons[i]->enableAnimation();
815
    }
816
}
817

818
//--------------------------------------------------------------
819
void ofxFBX::disableAnimations() {
820
    bAnimationsEnabled = false;
821
    for( int i = 0; i < mSkeletons.size(); i++ ) {
822
        mSkeletons[i]->disableAnimation();
823
    }
824
    bFirstRun=true;
825
}
826

827
//--------------------------------------------------------------
828
void ofxFBX::toggleAnimationsEnabled() {
829
    if( bAnimationsEnabled ) {
830
        disableAnimations();
831
    } else {
832
        enableAnimations();
833
    }
834
}
835

836
//--------------------------------------------------------------
837
bool ofxFBX::areAnimationsEnabled() {
838
    return (bAnimationsEnabled && hasAnimations());
839
}
840

841
//--------------------------------------------------------------
842
bool ofxFBX::hasAnimations() {
843
    if( animations.size() > 1 ) return true;
844
    if( animations.size() == 1 ) {
845
        if( animations[0].name == "dummyAnimation" ) {
846
            return false;
847
        } else {
848
            return true;
849
        }
850
    }
851
    return false;
852
}
853

854
//--------------------------------------------------------------
855
void ofxFBX::reloadAnimationsFromScene() {
856
    if( getFbxScene() ) {
857
        animations.clear();
858
        getFbxScene()->populateAnimations( animations );
859
    }
860
}
861

862
//--------------------------------------------------------------
863
void ofxFBX::transition( int aAnimIndex1, int aNumIndex2, float aduration ) {
864
    if( !bUsingKeyframes ) {
865
        ofLogError("ofxFbxManager :: transition : not transitioning, must be using keyframes. Set ofxFBXSceneSettings.useKeyFrames to true when loading the fbx scene" );
866
        return;
867
    }
868
    if( !hasAnimations() ) {
869
        ofLogError("ofxFbxManager :: transition : not transitioning, no animations" );
870
        return;
871
    }
872
    if( !areAnimationsEnabled() ) {
873
        ofLogError("ofxFbxManager :: transition : not transitioning, animations disabled" );
874
        return;
875
    }
876
    if( aAnimIndex1 < 0 || aNumIndex2 < 0 || aAnimIndex1 >= getNumAnimations() || aNumIndex2 >= getNumAnimations() ) {
877
        ofLogError("ofxFbxManager :: transition : invalid index: " ) << aAnimIndex1 << " index2: " << aNumIndex2 << " num animations: " << getNumAnimations();
878
        return;
879
    }
880
    mAnimTrans.animIndex1 = aAnimIndex1;
881
    mAnimTrans.animIndex2 = aNumIndex2;
882
    mAnimTrans.duration = aduration;
883
    mAnimTrans.percent = 0.f;
884
    mAnimTrans.startTime = ofGetElapsedTimef();
885
    mAnimTrans.bActive = true;
886
}
887

888
//--------------------------------------------------------------
889
void ofxFBX::transition( string aAnimName1, string aNumName2, float aduration ) {
890
    transition( getAnimationIndex( aAnimName1 ), getAnimationIndex( aNumName2 ), aduration );
891
}
892

893
//--------------------------------------------------------------
894
void ofxFBX::transition( string aToAnimName, float aduration ) {
895
    transition( getCurrentAnimationIndex(), getAnimationIndex(aToAnimName), aduration );
896
}
897

898
//--------------------------------------------------------------
899
void ofxFBX::transition( int aToAnimIndex, float aduration ) {
900
    transition( getCurrentAnimationIndex(), aToAnimIndex, aduration );
901
}
902

903
//--------------------------------------------------------------
904
bool ofxFBX::isTransitioning() {
905
    return mAnimTrans.bActive;
906
}
907

908
//--------------------------------------------------------------
909
float ofxFBX::getTransitionPercent() {
910
    return mAnimTrans.percent;
911
}
912

913
#pragma mark Hierarchy
914
//--------------------------------------------------------------
915
shared_ptr<ofxFBXNode> ofxFBX::getNodeForName( string aPath, bool bStrict) {
916
    shared_ptr<ofxFBXNode> temp;
917
    for( auto& sn : mRootNodes ) {
918
        temp = sn->getNodeforName( sn, aPath, bStrict );
919
        if( temp ) break;
920
    }
921
    return temp;
922
}
923

924
// Flattens out scene hierarchy //
925
//--------------------------------------------------------------
926
vector< shared_ptr<ofxFBXNode> > ofxFBX::getAllNodes() {
927
    return mAllNodes;
928
}
929

930
//--------------------------------------------------------------
931
vector< shared_ptr<ofxFBXNode> > ofxFBX::getRootNodes() {
932
    return mRootNodes;
933
}
934

935

936

937

938

939

940

941

942

943

944

945

946

947

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.