-
Notifications
You must be signed in to change notification settings - Fork 50
Expand file tree
/
Copy pathdmerig.cpp
More file actions
667 lines (550 loc) · 23.3 KB
/
dmerig.cpp
File metadata and controls
667 lines (550 loc) · 23.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
//====== Copyright © 1996-2009, Valve Corporation, All rights reserved. =======
//
// Purpose: Implementation of the CDmeRig class, a class which groups a set of
// associated constraints and operators together, allowing operations to be
// performed on the group of elements. Also contains the implementation of
// CDmeRigAnimSetElements, a helper class used to store a list of elements which
// are all associated with a single animation set.
//
//=============================================================================
#include "movieobjects/dmerig.h"
#include "movieobjects/dmeanimationset.h"
#include "movieobjects/dmeoperator.h"
#include "movieobjects/dmeclip.h"
#include "movieobjects/dmetrackgroup.h"
#include "movieobjects/dmetrack.h"
#include "movieobjects/dmerigconstraintoperators.h"
#include "movieobjects/dmetransformcontrol.h"
#include "movieobjects/dmechannel.h"
#include "datamodel/dmelementfactoryhelper.h"
#include "tier1/fmtstr.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
// Expose this the classes to the scene database
IMPLEMENT_ELEMENT_FACTORY( DmeRigAnimSetElements, CDmeRigAnimSetElements );
IMPLEMENT_ELEMENT_FACTORY( DmeRig, CDmeRig );
//-------------------------------------------------------------------------------------------------
// Purpose: Provide post construction processing.
//-------------------------------------------------------------------------------------------------
void CDmeRigAnimSetElements::OnConstruction()
{
m_AnimationSet.Init( this, "animationSet" );
m_ElementList.Init( this, "elementList" );
m_HiddenGroups.Init( this, "hiddenGroups" );
}
//-------------------------------------------------------------------------------------------------
// Purpose: Provide processing and cleanup before shutdown
//-------------------------------------------------------------------------------------------------
void CDmeRigAnimSetElements::OnDestruction()
{
}
//-------------------------------------------------------------------------------------------------
// Purpose: Set the animation set elements in the list are to be associated with, only allowed
// when the element list is empty.
//-------------------------------------------------------------------------------------------------
void CDmeRigAnimSetElements::SetAnimationSet( CDmeAnimationSet* pAnimationSet )
{
// The element list must be empty when the animation set is assigned.
Assert( m_ElementList.Count() == 0 );
if ( m_ElementList.Count() == 0 )
{
m_AnimationSet = pAnimationSet;
}
}
//-------------------------------------------------------------------------------------------------
// Purpose: Add an element to the list
//-------------------------------------------------------------------------------------------------
void CDmeRigAnimSetElements::AddElement( CDmElement *pElement )
{
if ( pElement == NULL )
return;
m_ElementList.AddToTail( pElement );
}
//-------------------------------------------------------------------------------------------------
// Purpose: Remove the specified element from the list. Returns true if the element is found and
// removed, return false if the element could not be found.
//-------------------------------------------------------------------------------------------------
bool CDmeRigAnimSetElements::RemoveElement( CDmElement *pElement )
{
int index = m_ElementList.Find( pElement );
if ( index != m_ElementList.InvalidIndex() )
{
m_ElementList.Remove( index );
return true;
}
return false;
}
//-------------------------------------------------------------------------------------------------
// Purpose: Remove all of the elements from the list
//-------------------------------------------------------------------------------------------------
void CDmeRigAnimSetElements::RemoveAll()
{
m_ElementList.RemoveAll();
}
//-------------------------------------------------------------------------------------------------
// Purpose: Add all of the elements to the provided array
//-------------------------------------------------------------------------------------------------
void CDmeRigAnimSetElements::GetElements( CUtlVector< CDmElement* > &elementList ) const
{
int nElements = m_ElementList.Count();
for ( int iElement = 0; iElement < nElements; ++iElement )
{
CDmElement *pElement = m_ElementList[ iElement ];
if ( pElement )
{
elementList.AddToTail( pElement );
}
}
}
//-------------------------------------------------------------------------------------------------
// Add a control group to the list of hidden control groups
//-------------------------------------------------------------------------------------------------
void CDmeRigAnimSetElements::AddHiddenControlGroup( CDmeControlGroup *pControlGroup )
{
m_HiddenGroups.AddToTail( pControlGroup->GetName() );
}
//-------------------------------------------------------------------------------------------------
// Purpose: Provide post construction processing.
//-------------------------------------------------------------------------------------------------
void CDmeRig::OnConstruction()
{
m_AnimSetList.Init( this, "animSetList" );
}
//-------------------------------------------------------------------------------------------------
// Purpose: Provide processing and cleanup before shutdown
//-------------------------------------------------------------------------------------------------
void CDmeRig::OnDestruction()
{
}
//-------------------------------------------------------------------------------------------------
// Purpose: Add an element to the rig
//-------------------------------------------------------------------------------------------------
void CDmeRig::AddElement( CDmElement* pElement, CDmeAnimationSet *pAnimationSet )
{
if ( ( pElement == NULL ) || ( pAnimationSet == NULL ) )
return;
// Search for an element set with the specified
// animation set, if none is found, create one.
CDmeRigAnimSetElements *pAnimSetElementList = FindOrCreateAnimSetElementList( pAnimationSet );
if ( pAnimSetElementList )
{
pAnimSetElementList->AddElement( pElement );
}
}
//-------------------------------------------------------------------------------------------------
// Set the state of the specified control group and add it to list of control group modified by
// the rig
//-------------------------------------------------------------------------------------------------
void CDmeRig::HideControlGroup( CDmeControlGroup *pGroup )
{
if ( pGroup == NULL )
return;
CDmeAnimationSet *pAnimationSet = pGroup->FindAnimationSet( true );
if ( pAnimationSet == NULL )
return;
CDmeRigAnimSetElements *pAnimSetElementList = FindOrCreateAnimSetElementList( pAnimationSet );
if ( pAnimSetElementList)
{
pGroup->SetVisible( false );
pAnimSetElementList->AddHiddenControlGroup( pGroup );
}
}
//-------------------------------------------------------------------------------------------------
// Purpose: Remove an element from the rig
//-------------------------------------------------------------------------------------------------
void CDmeRig::RemoveElement( CDmElement *pElement, CDmeAnimationSet *pAnimationSet )
{
if ( pElement == NULL )
return;
// Search each of the animation set element lists for the specified element, if the element
// is found and removed from an animation set element list, stop and don't search the others,
// as each element should belong to only on animation set.
int nAnimSets = m_AnimSetList.Count();
for ( int iAnimSet = 0; iAnimSet < nAnimSets; ++iAnimSet )
{
CDmeRigAnimSetElements *pAnimSetElements = m_AnimSetList[ iAnimSet ];
if ( pAnimSetElements )
{
if ( pAnimSetElements->AnimationSet() == pAnimationSet )
{
if ( pAnimSetElements->RemoveElement( pElement ) )
break;
}
}
}
}
//-------------------------------------------------------------------------------------------------
// Purpose: Remove an animation set and all associated elements from the group
//-------------------------------------------------------------------------------------------------
void CDmeRig::RemoveAnimationSet( CDmeAnimationSet *pAnimationSet )
{
int index = FindAnimSetElementList( pAnimationSet );
if ( index != m_AnimSetList.InvalidIndex() )
{
m_AnimSetList.Remove( index );
}
}
//-------------------------------------------------------------------------------------------------
// Determine if the rig has any animation sets associated with it
//-------------------------------------------------------------------------------------------------
bool CDmeRig::HasAnyAnimationSets() const
{
int nAnimSets = m_AnimSetList.Count();
for ( int iAnimSet = 0; iAnimSet < nAnimSets; ++iAnimSet )
{
if ( CDmeRigAnimSetElements *pAnimSetElements = m_AnimSetList[ iAnimSet ] )
{
if ( CDmeAnimationSet *pAnimSet = pAnimSetElements->AnimationSet() )
return true;
}
}
return false;
}
//-------------------------------------------------------------------------------------------------
// Purpose: Get the list of animation sets in the group
//-------------------------------------------------------------------------------------------------
void CDmeRig::GetAnimationSets( CUtlVector< CDmeAnimationSet* > &animationSetList ) const
{
int nAnimSets = m_AnimSetList.Count();
animationSetList.EnsureCapacity( animationSetList.Count() + nAnimSets );
for ( int iAnimSet = 0; iAnimSet < nAnimSets; ++iAnimSet )
{
CDmeRigAnimSetElements *pAnimSetElements = m_AnimSetList[ iAnimSet ];
if ( pAnimSetElements != NULL )
{
CDmeAnimationSet *pAnimSet = pAnimSetElements->AnimationSet();
if ( pAnimSet != NULL )
{
animationSetList.AddToTail( pAnimSet );
}
}
}
}
//-------------------------------------------------------------------------------------------------
// Purpose: Get the list of elements for the specified animation set
//-------------------------------------------------------------------------------------------------
void CDmeRig::GetAnimationSetElements( const CDmeAnimationSet* pAnimationSet, CUtlVector< CDmElement* > &elementList ) const
{
int nAnimSets = m_AnimSetList.Count();
// Count the number of total elements in all the animation sets
int nTotalElements = 0;
for ( int iAnimSet = 0; iAnimSet < nAnimSets; ++iAnimSet )
{
CDmeRigAnimSetElements *pAnimSetElements = m_AnimSetList[ iAnimSet ];
if ( pAnimSetElements != NULL )
{
nTotalElements = pAnimSetElements->NumElements();
}
}
// Allocate enough space in the element list for all of the elements in the rig.
elementList.EnsureCapacity( elementList.Count() + nTotalElements );
// Add all the elements in the rig to the provided element list
for ( int iAnimSet = 0; iAnimSet < nAnimSets; ++iAnimSet )
{
CDmeRigAnimSetElements *pAnimSetElements = m_AnimSetList[ iAnimSet ];
if ( pAnimSetElements != NULL )
{
pAnimSetElements->GetElements( elementList );
}
}
}
//-------------------------------------------------------------------------------------------------
// Purpose: Determine if the rig has any elements from the specified animation set
//-------------------------------------------------------------------------------------------------
bool CDmeRig::HasAnimationSet( const CDmeAnimationSet *pAnimationSet ) const
{
return ( FindAnimSetElementList( pAnimationSet ) != m_AnimSetList.InvalidIndex() );
}
//-------------------------------------------------------------------------------------------------
// Purpose: Find the element list for the specified animation set
//-------------------------------------------------------------------------------------------------
int CDmeRig::FindAnimSetElementList( const CDmeAnimationSet *pAnimationSet ) const
{
int nAnimSets = m_AnimSetList.Count();
for ( int iAnimSet = 0; iAnimSet < nAnimSets; ++iAnimSet )
{
CDmeRigAnimSetElements *pAnimSetElements = m_AnimSetList[ iAnimSet ];
if ( pAnimSetElements == NULL )
continue;
if ( pAnimSetElements->AnimationSet() == pAnimationSet )
{
return iAnimSet;
}
}
return m_AnimSetList.InvalidIndex();
}
//-------------------------------------------------------------------------------------------------
// Find the element list for the specified animation set or create one
//-------------------------------------------------------------------------------------------------
CDmeRigAnimSetElements *CDmeRig::FindOrCreateAnimSetElementList( CDmeAnimationSet *pAnimationSet )
{
int nIndex = FindAnimSetElementList( pAnimationSet );
if ( nIndex != m_AnimSetList.InvalidIndex() )
return m_AnimSetList[ nIndex ];
CDmeRigAnimSetElements *pAnimSetElementList = CreateElement< CDmeRigAnimSetElements >( CFmtStr( "rigElements_%s", pAnimationSet->GetName() ), GetFileId() );
if ( pAnimSetElementList )
{
pAnimSetElementList->SetAnimationSet( pAnimationSet );
m_AnimSetList.AddToTail( pAnimSetElementList );
}
return pAnimSetElementList;
}
//-------------------------------------------------------------------------------------------------
// Purpose: Build a list of all of the dag nodes which are influenced by rig, does not include
// dag nodes that are part of the rig.
//-------------------------------------------------------------------------------------------------
void CDmeRig::FindInfluencedDags( CUtlVector< CDmeDag* > &dagList ) const
{
// Count the total number of elements, this is done to calculate a good pre-allocation size for lists
int totalElements = 0;
int nAnimSets = m_AnimSetList.Count();
for ( int iAnimSet = 0; iAnimSet < nAnimSets; ++iAnimSet )
{
totalElements += m_AnimSetList[ iAnimSet ]->NumElements();
}
// First build a tree of all of the dag nodes that are part of the rig, we do this so that we
// can quickly determine if a dag which is influenced by some element of the rig is part of the
// rig and therefore should not be added to the list of influenced dag nodes.
CUtlVector< CDmElement* > elementList( 0, totalElements );
CUtlRBTree< const CDmeDag* > rigDags( 0, totalElements, DefLessFunc( const CDmeDag *) );
for ( int iAnimSet = 0; iAnimSet < nAnimSets; ++iAnimSet )
{
const CDmaElementArray< CDmElement > &animSetElements = m_AnimSetList[ iAnimSet ]->Elements();
int nElements = animSetElements.Count();
for ( int iElement = 0; iElement < nElements; ++iElement )
{
CDmElement *pElement = animSetElements[ iElement ];
if ( pElement )
{
elementList.AddToTail( pElement );
CDmeDag *pDag = CastElement< CDmeDag >( pElement );
if ( pDag )
{
rigDags.Insert( pDag );
}
}
}
}
// Now iterate through all of the elements that belong to the rig and find any dag nodes which
// are influenced by the rig elements. This is done by looking for any operators and then
// getting the output attributes of the operator and determining if any of those attributes
// belong to a dag node which is not part of the rig.
CUtlRBTree< CDmeDag* > influencedDags( 0, totalElements, DefLessFunc( CDmeDag *) );
CUtlVector< CDmAttribute* > outputAttributes( 0, 32 );
int nElements = elementList.Count();
for ( int iElement = 0; iElement < nElements; ++iElement )
{
CDmElement *pElement = elementList[ iElement ];
CDmeOperator *pOperator = CastElement< CDmeOperator >( pElement );
if ( pOperator )
{
outputAttributes.RemoveAll();
pOperator->GetOutputAttributes( outputAttributes );
int nAttributes = outputAttributes.Count();
for ( int iAttr = 0; iAttr < nAttributes; ++iAttr )
{
CDmAttribute *pAttr = outputAttributes[ iAttr ];
if ( pAttr == NULL )
continue;
CDmeDag *pDag = CastElement< CDmeDag >( pAttr->GetOwner() );
if ( pDag == NULL )
{
CDmeTransform *pTransform = CastElement< CDmeTransform >( pAttr->GetOwner() );
if ( pTransform )
{
pDag = pTransform->GetDag();
}
}
if ( pDag == NULL )
continue;
// Make sure the dag is not part of the rig, if
// not add it to the list of influenced dag nodes.
if ( rigDags.Find( pDag ) == rigDags.InvalidIndex() )
{
influencedDags.InsertIfNotFound( pDag );
}
}
}
}
// Copy the influenced dag nodes into the provided list
int nDagNodes = influencedDags.Count();
dagList.SetCount( nDagNodes );
for ( int iDag = 0; iDag < nDagNodes; ++iDag )
{
dagList[ iDag ] = influencedDags[ iDag ];
}
}
//-------------------------------------------------------------------------------------------------
// Purpose: Remove all of elements in the rig from the specified shot
//-------------------------------------------------------------------------------------------------
void CDmeRig::RemoveElementsFromShot( CDmeFilmClip *pShot )
{
// Find the animation set channels track group, this will be used to find
// the the channels clip for each of the animation sets referenced by the rig.
CDmeTrack *pAnimSetEditorTrack = NULL;
CDmeTrackGroup *pTrackGroup = pShot->FindOrAddTrackGroup( "channelTrackGroup" );
if ( pTrackGroup )
{
pAnimSetEditorTrack = pTrackGroup->FindOrAddTrack( "animSetEditorChannels", DMECLIP_CHANNEL );
}
int nAnimSets = m_AnimSetList.Count();
for ( int iAnimSet = 0; iAnimSet < nAnimSets; ++iAnimSet )
{
CDmeRigAnimSetElements *pAnimSetElements = m_AnimSetList[ iAnimSet ];
if ( pAnimSetElements == NULL )
continue;
CDmeAnimationSet *pAnimSet = pAnimSetElements->AnimationSet();
if ( pAnimSet == NULL )
continue;
CDmeChannelsClip *pChannelsClip = NULL;
if ( pAnimSetEditorTrack )
{
pChannelsClip = CastElement< CDmeChannelsClip >( pAnimSetEditorTrack->FindNamedClip( pAnimSet->GetName() ) );
}
// Make a copy of the array since we may remove elements from the original while iterating
const CDmaElementArray< CDmElement > &elements = pAnimSetElements->Elements();
int nElements = elements.Count();
CUtlVector< DmElementHandle_t > elementHandles( 0, nElements );
for ( int iElement = 0; iElement < nElements; ++iElement )
{
CDmElement *pElement = elements[ iElement ];
if ( pElement )
{
elementHandles.AddToTail( pElement->GetHandle() );
}
}
int nElementHandles = elementHandles.Count();
for ( int iHandle = 0; iHandle < nElementHandles; ++iHandle )
{
// Get the element using its handle because it may have been destroyed already
CDmElement *pElement = GetElement< CDmElement >( elementHandles[ iHandle ] );
if ( pElement == NULL )
continue;
// If the element is an operator make sure it is removed from the
// list of operators maintained by the shot and animation set.
CDmeOperator *pOperator = CastElement< CDmeOperator >( pElement );
if ( pOperator )
{
pAnimSet->RemoveOperator( pOperator );
pShot->RemoveOperator( pOperator );
// If the element is a channel remove it from the animation set's channel clip.
if ( pChannelsClip )
{
CDmeChannel *pChannel = CastElement< CDmeChannel >( pElement );
if ( pChannel )
{
pChannelsClip->RemoveChannel( pChannel );
}
}
// If the element is a constraint reconnect the original
// channels of the constrained dag back to the transform.
CDmeRigBaseConstraintOperator *pConstraint = CastElement< CDmeRigBaseConstraintOperator >( pElement );
if ( pConstraint )
{
pConstraint->ReconnectTransformChannels();
}
}
else if ( pElement->IsA( CDmeDag::GetStaticTypeSymbol() ) )
{
CDmeDag *pDag = CastElement< CDmeDag >( pElement );
CDmeDag *pParent = pDag->GetParent();
if ( pParent )
{
// Make sure the parent hasn't already been destroyed
if ( g_pDataModel->GetElement( pParent->GetHandle() ) )
{
pParent->RemoveChild( pDag );
}
}
// If the dag has any constraints on it, remove them
CDmeRigBaseConstraintOperator::RemoveConstraintsFromDag( pDag );
}
else if ( ( pElement->GetType() == CDmElement::GetStaticTypeSymbol() ) || pElement->IsA( CDmeTransformControl::GetStaticTypeSymbol() ) )
{
// If the element is just only element assume it may be a control or if the element is
// a transform control try to remove it from the animation set's list of controls.
pAnimSet->RemoveControl( pElement );
}
// Destroy the element, this is done because many elements refer to each other so if undo is enabled
// the auto cleanup will not take place and the elements will persist until the undo history is cleared.
g_pDataModel->DestroyElement( pElement->GetHandle() );
} // For iElement
// Reset the visibility on control groups that were hidden by the rig
SetHiddenControlGroupVisibility( pAnimSetElements, true );
// Clear the element list since they have all been destroyed
pAnimSetElements->RemoveAll();
} // For iAnimSet
m_AnimSetList.RemoveAll();
}
//-------------------------------------------------------------------------------------------------
// Set the visibility of the control groups in the hidden list
//-------------------------------------------------------------------------------------------------
void CDmeRig::SetHiddenControlGroupVisibility( CDmeRigAnimSetElements *pAnimSetElements, bool bVisible )
{
CDmeAnimationSet *pAnimSet = pAnimSetElements->AnimationSet();
if ( pAnimSet == NULL )
return;
const CDmaStringArray &hiddenGroupList = pAnimSetElements->HiddenControlGroups();
int nNumGroups = hiddenGroupList.Count();
for ( int iGroup = 0; iGroup < nNumGroups; ++iGroup )
{
CDmeControlGroup *pGroup = pAnimSet->FindControlGroup( hiddenGroupList[ iGroup ] );
if ( pGroup )
{
pGroup->SetVisible( bVisible );
}
}
}
//-------------------------------------------------------------------------------------------------
// Hide all of the control groups in the rig's list of hidden control groups
//-------------------------------------------------------------------------------------------------
void CDmeRig::HideHiddenControlGroups( CDmeAnimationSet *pAnimationSet )
{
int nAnimSetIndex = FindAnimSetElementList( pAnimationSet );
if ( nAnimSetIndex == m_AnimSetList.InvalidIndex() )
return;
CDmeRigAnimSetElements *pAnimSetElements = m_AnimSetList[ nAnimSetIndex ];
if ( pAnimSetElements == NULL )
return;
SetHiddenControlGroupVisibility( pAnimSetElements, false );
}
//-------------------------------------------------------------------------------------------------
// Purpose: Remove the specified element from any rig which it may be associated with.
//-------------------------------------------------------------------------------------------------
void CDmeRig::RemoveElementFromRig( CDmElement *pElement )
{
if ( pElement == NULL )
return;
CUtlVector< CDmeRigAnimSetElements* > rigElementLists;
FindAncestorsReferencingElement( pElement, rigElementLists );
for ( int iList = 0; iList < rigElementLists.Count(); ++iList )
{
CDmeRigAnimSetElements *pElementList = rigElementLists[ iList ];
if ( pElementList )
{
pElementList->RemoveElement( pElement );
}
}
}
//-------------------------------------------------------------------------------------------------
// Find all of the rigs which refer to the specified animation set
//-------------------------------------------------------------------------------------------------
void CollectRigsOnAnimationSet( CDmeAnimationSet *pAnimSet, CUtlVector< CDmeRig* > &rigList )
{
CDmeFilmClip *pFilmClip = FindReferringElement< CDmeFilmClip >( pAnimSet, "animationSets" );
if ( pFilmClip == NULL )
return;
CDmeDag *pScene = pFilmClip->GetScene();
if ( !pScene || !pAnimSet )
return;
pScene->FindChildrenOfType( rigList );
int i = rigList.Count();
while ( --i >= 0 )
{
CDmeRig *pRig = rigList[ i ];
if ( !pRig || !pRig->HasAnimationSet( pAnimSet ) )
{
rigList.Remove( i );
}
}
}