OpenBarnyard
 
Loading...
Searching...
No Matches
AAnimatableObjectManager.cpp
Go to the documentation of this file.
1#include "pch.h"
4#include "AModelRepos.h"
5#include "ALoadScreen.h"
6
7//-----------------------------------------------------------------------------
8// Enables memory debugging.
9// Note: Should be the last include!
10//-----------------------------------------------------------------------------
11#include <Core/TMemoryDebugOn.h>
12
14
16
17Toshi::T2ObjectPool<AToshiAnimationRef, 100> g_oAnimationRefPool;
18
19static constexpr const TCHAR* MODELTYPES_DIR = "data\\modeltypes\\";
20
21// $Barnyard: FUNCTION 0057d5f0
22// $Barnyard: FUNCTION 0057d560
24 : m_pAnimSoundBPsTRB( TNULL )
25 , m_pSoundBreakpoints( TNULL )
26{
27}
28
29// $Barnyard: FUNCTION 0057db80
30// $Barnyard: FUNCTION 0057d680
32{
33 if ( m_pAnimSoundBPsTRB )
34 {
35 delete m_pAnimSoundBPsTRB;
36 m_pAnimSoundBPsTRB = TNULL;
37 m_pSoundBreakpoints = TNULL;
38 }
39
40 m_llObjectTypes.DeleteAll();
41 m_llAnimatableObjects.DeleteAll();
42}
43
44// $Barnyard: FUNCTION 0057d710
46{
47 AAnimatableObject* pObject = new AAnimatableObject();
48
49 m_llAnimatableObjects.PushBack( pObject );
50 pObject->Create( a_pObjectType, a_Unk1, a_eFlags );
51
52 return pObject;
53}
54
55// $Barnyard: FUNCTION 0057e8c0
57{
58 TString8 strLibPath;
59 strLibPath.Format( "%slibs\\%s.trb", MODELTYPES_DIR, a_szLibName );
60
61 TTRB oTRB;
62 TUINT8 eLoadRes = oTRB.Load( strLibPath );
63 TASSERT( eLoadRes == TTRB::ERROR_OK );
64
65 if ( eLoadRes == TTRB::ERROR_OK )
66 {
67 const PBProperties* pProperties = PBProperties::LoadFromTRB( oTRB );
68 oTRB.DeleteSymbolTable();
69
70 // Skip file if the first type's name is starting with _ (why?)
71 if ( pProperties->Begin()->GetName().GetString()[ 0 ] != '_' )
72 {
73 TINT iLoadScreenUpdateCounter = 0;
74
75 T2_FOREACH( ( *pProperties ), it )
76 {
77 LoadAnimObjType( it->GetName().GetString(), it->GetValue()->GetProperties(), TFALSE );
78
79 // Update load screen only each N type
80 if ( ++iLoadScreenUpdateCounter > 5 )
81 {
82 iLoadScreenUpdateCounter = 0;
83 g_oLoadScreen.Update();
84 }
85 }
86 }
87
88 oTRB.Close();
89 }
90
91 g_oLoadScreen.Update();
92}
93
94// $Barnyard: FUNCTION 0057e550
95void AAnimatableObjectManager::LoadAnimObjType( const TPString8& a_rcName, const PBProperties* a_pProperties, TBOOL a_bNoBreakpoints )
96{
97 TString8 strAnimObjPath;
98 strAnimObjPath.Format( "%s%s.trb", MODELTYPES_DIR, a_rcName.GetString() );
99
100 TTRB oTRB;
101
102 // If no properties is specified, load from file
103 if ( !a_pProperties && oTRB.Load( strAnimObjPath ) == TTRB::ERROR_OK )
104 {
105 a_pProperties = PBProperties::LoadFromTRB( oTRB );
106 oTRB.DeleteSymbolTable();
107 }
108
109 TVALIDPTR( a_pProperties );
110 const PBProperties* pTypeProperties = TNULL;
111
112 AAnimatableObjectType* pObjectType = TNULL;
113
114 if ( a_pProperties )
115 {
116 // Get AnimatableObjectTypeBunch or AnimatableObjectType
117
118 if ( a_pProperties->GetOptionalPropertyValue( pTypeProperties, "AnimatableObjectTypeBunch" ) )
119 pObjectType = new AAnimatableObjectTypeBunch();
120 else
121 a_pProperties->GetOptionalPropertyValue( pTypeProperties, "AnimatableObjectType" );
122 }
123
124 if ( !pObjectType )
125 pObjectType = new AAnimatableObjectType();
126
127 TVALIDPTR( pObjectType );
128
129 m_llObjectTypes.PushBack( pObjectType );
130
131 TBOOL bCreated = ( pTypeProperties ) ?
132 pObjectType->CreateFromProperties( pTypeProperties, a_rcName ) :
133 pObjectType->Create( a_rcName );
134
135 if ( bCreated && !a_bNoBreakpoints )
136 AttachSoundBreakpoints( pObjectType );
137
138 oTRB.Close();
139}
140
141// $Barnyard: FUNCTION 0057e840
142void AAnimatableObjectManager::LoadAnimObjType( const TCHAR* a_szName, const PBProperties* a_pProperties, TBOOL a_bNoBreakpoints )
143{
144 LoadAnimObjType( TPString8( a_szName ), a_pProperties, a_bNoBreakpoints );
145}
146
147// $Barnyard: FUNCTION 0057d820
149{
150 T2_FOREACH( m_llObjectTypes, it )
151 {
152 if ( it->GetName() == a_rcName )
153 return it;
154 }
155
156 TERROR( "AAnimatableObjectManager: unable to find animatable type '%s'\n", a_rcName.GetString() );
157 return TNULL;
158}
159
160// $Barnyard: FUNCTION 0057dac0
162{
163 TASSERT( a_pObject->m_oAttachmentInfo.pParentObject == a_pParent );
164 a_pObject->m_oAttachmentInfo.pParentObject = TNULL;
165 a_pParent->m_llAttachedObjects.Erase( a_pObject );
166}
167
168// $Barnyard: FUNCTION 0057d870
169void AAnimatableObjectManager::DestroyType( const Toshi::TPString8& a_rcName )
170{
171 AAnimatableObjectType* pType = FindType( a_rcName );
172
173 if ( pType )
174 {
175 pType->Remove();
176 delete pType;
177
178 AModelRepos::GetSingleton()->UnloadUnusedModels();
179 }
180}
181
182// $Barnyard: FUNCTION 0057dc60
184{
185 if ( !a_pAnimatableObject )
186 return;
187
188 if ( m_llAnimatableObjects.Exists( a_pAnimatableObject ) )
189 {
190 // Destroy all attached objects
191 DestroyAttachedObjects( a_pAnimatableObject );
192
193 // Detach from a parent
194 if ( a_pAnimatableObject->m_oAttachmentInfo.pParentObject )
195 DetachObject( a_pAnimatableObject, a_pAnimatableObject->m_oAttachmentInfo.pParentObject );
196
197 a_pAnimatableObject->Remove();
198 delete a_pAnimatableObject;
199 }
200}
201
202// $Barnyard: FUNCTION 0057d7c0
204{
205 if ( !a_pAnimatableObject )
206 return;
207
208 while ( a_pAnimatableObject->m_llAttachedObjects.IsLinked() )
209 {
210 AAnimatableObject* pAttachedObject = a_pAnimatableObject->m_llAttachedObjects.Begin();
211 DestroyAnimatableObject( pAttachedObject );
212 }
213}
214
215// $Barnyard: FUNCTION 0057d390
217{
218 TASSERT( m_pAnimSoundBPsTRB == TNULL );
219
220 if ( a_szFilePath )
221 {
222 m_pAnimSoundBPsTRB = new TTRB();
223
224 if ( m_pAnimSoundBPsTRB->Load( a_szFilePath ) == TTRB::ERROR_OK )
225 {
226 m_pSoundBreakpoints = m_pAnimSoundBPsTRB->CastSymbol<ASoundBreakpointsTable>( "Main" );
227 TVALIDPTR( m_pSoundBreakpoints );
228 }
229 else
230 {
231 TASSERT( !"Unable to load info about sound breakpoints" );
232 }
233 }
234
235 return TTRUE;
236}
237
238// $Barnyard: FUNCTION 0057d420
239TINT AAnimatableObjectManager::FindNumAnimationSoundBreakpoints( const Toshi::TPString8& a_rcModelName, ANamedAnimation* a_pAnimation )
240{
241 TVALIDPTR( m_pSoundBreakpoints );
242
243 TINT iCount = 0;
244
245 for ( TUINT i = 0; i < m_pSoundBreakpoints->uiCount; i++ )
246 {
247 if ( !T2String8::CompareNoCase( m_pSoundBreakpoints->pBreakpoints[ i ].pszModelName, a_rcModelName ) &&
248 !T2String8::CompareNoCase( m_pSoundBreakpoints->pBreakpoints[ i ].pszAnimationName, a_pAnimation->GetExportedName() ) )
249 {
250 iCount += 1;
251 }
252 }
253
254 return iCount;
255}
256
257// $Barnyard: FUNCTION 0057ddc0
259{
260 T2_FOREACH( m_llAnimatableObjects, it )
261 {
262 // Find out whether the animation of this object needs to be updated or not
263 TBOOL bUpdateAnim = it->IsAnimated();
264
265 if ( bUpdateAnim )
266 {
267 AModelInstanceRef modelInstance = it->GetModelInstance();
268
269 // Also, don't update animations when skeleton is not updating and no animations are queued
270 if ( !modelInstance->IsUpdatingSkeleton() && it->GetQueuedAnimations().Size() <= 0 )
271 bUpdateAnim = TFALSE;
272 }
273
274 if ( bUpdateAnim )
275 it->Update( a_fDeltaTime );
276 }
277
278 return TTRUE;
279}
280
281// $Barnyard: FUNCTION 0057e3e0
282void AAnimatableObjectManager::AttachSoundBreakpoints( AAnimatableObjectType* a_pObjectType )
283{
284 if ( m_pSoundBreakpoints )
285 {
286 // Extract model name from the path
287 const TCHAR* pszModelName = a_pObjectType->GetModel()->GetName().GetString();
288 TINT iModelNameStartPos = T2String8::Length( pszModelName );
289
290 while ( iModelNameStartPos > 0 && ( pszModelName[ iModelNameStartPos - 1 ] != '\\' && pszModelName[ iModelNameStartPos - 1 ] != '/' ) )
291 {
292 iModelNameStartPos--;
293 }
294
295 TCHAR szModelName[ 512 ];
296 T2String8::Copy( szModelName, pszModelName + iModelNameStartPos );
297
298 TSkeleton* pSkeleton = a_pObjectType->GetModel()->GetSkeleton();
299
300 for ( TUINT i = 0; i < m_pSoundBreakpoints->uiCount; i++ )
301 {
302 ASoundBreakpoint* pSoundBreakpoint = &m_pSoundBreakpoints->pBreakpoints[ i ];
303
304 if ( !T2String8::CompareNoCase( szModelName, pSoundBreakpoint->pszModelName ) )
305 {
306 for ( TINT k = 0; k < a_pObjectType->GetNumAnimationSets(); k++ )
307 {
308 ANamedAnimationSetRef pAnimationSet = a_pObjectType->GetAnimationSet( k );
309
310 pAnimationSet->AddSoundBreakpoint( pSoundBreakpoint, pSkeleton );
311 }
312 }
313 }
314 }
315}
#define TASSERT(X,...)
Definition Defines.h:138
#define TERROR(...)
Definition Defines.h:153
#define TOSHI_NAMESPACE_USING
Definition Defines.h:46
#define TVALIDPTR(PTR)
Definition Defines.h:139
#define T2_FOREACH(vecName, iteratorName)
Definition T2Iterator.h:4
#define TDEFINE_CLASS(...)
Definition TObject.h:120
unsigned int TUINT
Definition Typedefs.h:8
char TCHAR
Definition Typedefs.h:20
uint8_t TUINT8
Definition Typedefs.h:17
float TFLOAT
Definition Typedefs.h:4
#define TNULL
Definition Typedefs.h:23
int TINT
Definition Typedefs.h:7
#define TFALSE
Definition Typedefs.h:24
#define TTRUE
Definition Typedefs.h:25
bool TBOOL
Definition Typedefs.h:6
ALoadScreen g_oLoadScreen
Toshi::T2ObjectPool< AToshiAnimationRef, 100 > g_oAnimationRefPool
Toshi::TRef< AModelInstance > AModelInstanceRef
Definition AModel.h:78
Toshi::TRef< ANamedAnimationSet > ANamedAnimationSetRef
Definition TTRB.h:253
void DeleteSymbolTable()
Definition TTRB.cpp:319
ERROR Load(const TCHAR *a_szFilePath, TUINT32 a_uiUnknown=0)
Definition TTRB.cpp:38
void Close()
Definition TTRB.cpp:289
@ ERROR_OK
Definition TTRB.h:258
const TCHAR * GetString() const
PBProperty * Begin()
TBOOL GetOptionalPropertyValue(T &a_rOutValue, const TCHAR *a_szName) const
PBPropertyName & GetName()
static TSIZE Length(const TCHAR *str)
static TINT CompareNoCase(const TCHAR *str1, const TCHAR *str2, TSIZE size=-1)
Definition T2String8.cpp:60
static TCHAR * Copy(TCHAR *dst, const TCHAR *src, TSIZE size=-1)
Definition T2String8.cpp:68
TFORCEINLINE const TCHAR * GetString() const
Definition TPString8.h:167
TString8 & Format(const TCHAR *a_pcFormat,...)
Definition TString8.cpp:176
TBOOL Create(AAnimatableObjectType *a_pObjectType, void *a_Unk1, CREATE_FLAGS a_eFlags=CREATE_FLAGS_NONE)
AAnimatableObject * CreateAnimatableObject(AAnimatableObjectType *a_pObjectType, void *a_Unk1=nullptr, TUINT a_eFlags=0)
void LoadAnimObjType(const TCHAR *a_szName, const PBProperties *a_pProperties, TBOOL a_bNoBreakpoints)
void DestroyAnimatableObject(AAnimatableObject *a_pAnimatableObject)
TBOOL LoadAnimSoundBreakpoints(const TCHAR *a_szFilePath)
AAnimatableObjectType * FindType(const Toshi::TPString8 &a_rcName)
void DetachObject(AAnimatableObject *a_pObject, AAnimatableObject *a_pParent)
void LoadTypesFromLibrary(const TCHAR *a_szLibName)
void DestroyType(const Toshi::TPString8 &a_rcName)
void DestroyAttachedObjects(AAnimatableObject *a_pAnimatableObject)
TINT FindNumAnimationSoundBreakpoints(const Toshi::TPString8 &a_rcModelName, ANamedAnimation *a_pAnimation)
virtual TBOOL OnUpdate(TFLOAT a_fDeltaTime) override
ANamedAnimationSetRef GetAnimationSet(TINT a_iIndex) const
virtual TBOOL Create(const Toshi::TPString8 &a_rcName)
virtual TBOOL CreateFromProperties(const PBProperties *a_pProperties, const Toshi::TPString8 &a_rcName)
const Toshi::TPString8 & GetName() const
Definition AModel.h:98
Toshi::TSkeleton * GetSkeleton() const
Definition AModel.h:99
const Toshi::TPString8 & GetExportedName() const