Skip to content

Commit aea356a

Browse files
committed
Fix unloading models in ATerrainInterface
1 parent c551f66 commit aea356a

File tree

14 files changed

+164
-139
lines changed

14 files changed

+164
-139
lines changed

OpenBarnyard/Source/Assets/AMaterialLibraryManager.cpp

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include "AMaterialLibraryManager.h"
88
#include "Locale/ALocaleManager.h"
99
#include "ALoadScreen.h"
10+
#include "AModelLoader.h"
1011

1112
//-----------------------------------------------------------------------------
1213
// Enables memory debugging.
@@ -205,22 +206,22 @@ void AMaterialLibraryManager::UnloadTexturesOfLibrary( AMaterialLibrary* a_pMate
205206

206207
if ( it->GetLibrary() == a_pMaterialLibrary )
207208
{
208-
auto removedSlot = m_UsedTextures.Erase( it );
209+
m_UsedTextures.Erase( it );
209210
m_iNumUsedTextures -= 1;
210211

211-
removedSlot->GetTexture()->DestroyResource();
212-
removedSlot->SetTexture( TNULL );
213-
removedSlot->ResetName();
212+
it->GetTexture()->DestroyResource();
213+
it->SetTexture( TNULL );
214+
it->ResetName();
214215

215-
m_FreeTextures.PushFront( removedSlot );
216+
m_FreeTextures.PushFront( it );
216217
m_iNumFreeTextures += 1;
217218
}
218219

219-
it = it->Next();
220+
it = pNextNode;
220221
}
221222

222223
TRenderInterface::GetSingleton()->FlushDyingResources();
223-
TTODO( "FUN_006120e0" );
224+
AModelLoader::ResolveTextures();
224225
}
225226

226227
// $Barnyard: FUNCTION 00613b50

OpenBarnyard/Source/Assets/AModelLoader.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,27 @@ void AModelLoader::DestroyMaterial( TMaterial* a_pMaterial )
352352
}
353353
}
354354

355+
// $Barnyard: FUNCTION 006120e0
356+
void AModelLoader::ResolveTextures()
357+
{
358+
T2_FOREACH( ms_oUsedMaterials, it )
359+
{
360+
TTexture* pTexture = AMaterialLibraryManager::GetSingleton()->FindTexture( it->szTextureName );
361+
362+
if ( !pTexture )
363+
pTexture = TRenderInterface::GetSingleton()->GetInvalidTexture();
364+
365+
if ( ASkinMaterial* pSkinMaterial = TDynamicCast<ASkinMaterial>( it->pMaterial ) )
366+
pSkinMaterial->m_pTexture = pTexture;
367+
else if ( AWorldMaterial* pWorldMaterial = TDynamicCast<AWorldMaterial>( it->pMaterial ) )
368+
pWorldMaterial->SetTexture( 0, pTexture );
369+
else if ( AGrassMaterial* pGrassMaterial = TDynamicCast<AGrassMaterial>( it->pMaterial ) )
370+
pGrassMaterial->SetTexture( 0, pTexture );
371+
else
372+
TASSERT( TFALSE && "Add other materials" );
373+
}
374+
}
375+
355376
static constexpr const TCHAR* TOSHICGROUP_NAMES[] = {
356377
"coll_support",
357378
"coll_player",

OpenBarnyard/Source/Assets/AModelLoader.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ class AModelLoader
5656

5757
static Toshi::TMaterial* CreateMaterial( Toshi::TShader* a_pShader, const TCHAR* a_szMaterialName );
5858
static void DestroyMaterial( Toshi::TMaterial* a_pMaterial );
59+
static void ResolveTextures();
5960

6061
static Toshi::TCollisionCommon::TOSHICGROUP GetCollisionGroup( const TCHAR* a_szCollGroupName );
6162

OpenBarnyard/Source/Assets/ASectionDoneJob.cpp

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -62,18 +62,14 @@ TBOOL ASectionDoneJob::RunJob()
6262

6363
return TTRUE;
6464
}
65-
else
66-
{
67-
// Loading was canceled before it was done
68-
m_pSection->SetLODLoading( m_eLODType, TFALSE );
69-
m_pSection->SetLODQueued( m_eLODType, TFALSE );
70-
m_pSection->SetLODEmpty( m_eLODType, TFALSE );
71-
m_pSection->DestroyLOD( m_eLODType );
7265

73-
ATerrainInterface::GetSingleton()->QueueStreamingAssets();
74-
return TTRUE;
75-
}
66+
// Loading was canceled before it was done
67+
m_pSection->SetLODLoading( m_eLODType, TFALSE );
68+
m_pSection->SetLODQueued( m_eLODType, TFALSE );
69+
m_pSection->SetLODEmpty( m_eLODType, TFALSE );
70+
m_pSection->DestroyLOD( m_eLODType );
7671

72+
ATerrainInterface::GetSingleton()->QueueStreamingAssets();
7773
return TTRUE;
7874
}
7975

OpenBarnyard/Source/Physics/ACollisionModelSet.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,10 @@ ACollisionModelSet::ACollisionModelSet()
2121
// $Barnyard: FUNCTION 0061ac50
2222
ACollisionModelSet::~ACollisionModelSet()
2323
{
24-
T2_FOREACH( m_vecCollModels, it )
25-
{
26-
delete it;
27-
}
24+
T2_FOREACH( m_vecCollModels, it )
25+
{
26+
delete *it;
27+
}
2828

2929
m_vecCollModels.Clear();
3030
}

OpenBarnyard/Source/Render/ASkinShader/ASkinMaterial.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ class ASkinMaterial : public Toshi::TMaterial
1818

1919
using BLENDMODE = TUINT;
2020

21+
friend class AModelLoader;
22+
2123
public:
2224
ASkinMaterial();
2325
~ASkinMaterial();

OpenBarnyard/Source/Terrain/ATerrainInterface.cpp

Lines changed: 100 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -139,9 +139,7 @@ void ATerrainInterface::Update()
139139
TINT iCurrentGroup = m_fnGetCurrentVISGroup();
140140

141141
if ( iCurrentGroup != -1 )
142-
{
143142
m_iCurrentSection = iCurrentGroup;
144-
}
145143
}
146144

147145
if ( m_iCurrentSection >= 0 )
@@ -223,7 +221,8 @@ void ATerrainInterface::Update()
223221
pGroups[ i ].LoadModels( ATerrainLODType_High );
224222
break;
225223
}
226-
else if ( pGroups[ i ].IsLODQueued( ATerrainLODType_Low ) )
224+
225+
if ( pGroups[ i ].IsLODQueued( ATerrainLODType_Low ) )
227226
{
228227
pGroups[ i ].LoadModels( ATerrainLODType_Low );
229228
break;
@@ -308,32 +307,67 @@ void ATerrainInterface::Render()
308307
m_fUnused3 = 1.0f;
309308
m_bUnused4 = TTRUE;
310309

311-
auto pTerrainVIS = m_pTerrainVIS;
312-
313-
if ( TNULL != pTerrainVIS )
310+
if ( m_pTerrainVIS )
314311
{
315312
// Reset current section if it is out of range
316-
if ( pTerrainVIS->m_iNumSections <= m_iCurrentSection || m_iCurrentSection < 0 )
317-
{
313+
if ( m_pTerrainVIS->m_iNumSections <= m_iCurrentSection || m_iCurrentSection < 0 )
318314
m_iCurrentSection = 0;
319-
}
320315

321-
auto pSections = pTerrainVIS->m_pSections;
316+
auto pSections = m_pTerrainVIS->m_pSections;
322317
auto iCurrentSection = m_iCurrentSection;
323318
auto pCurrentSection = &pSections[ iCurrentSection ];
324319

325-
if ( TNULL == m_pOrderDVIS )
320+
if ( !m_pOrderDVIS )
326321
{
327-
pCurrentSection->Draw( ATerrainLODType_High );
322+
if ( pCurrentSection->IsLODLoaded( ATerrainLODType_High ) )
323+
{
324+
// Draw models of the high LOD
325+
for ( TINT i = 0; i < pCurrentSection->m_iNumHighModelFiles; i++ )
326+
{
327+
pCurrentSection->m_ppLODModelsData[ ATerrainLODType_High ][ i ]->Render();
328+
}
329+
}
330+
else if ( pCurrentSection->IsLODLoaded( ATerrainLODType_Low ) )
331+
{
332+
// High LOD is still loading so let's render low LOD instead
333+
for ( TINT i = 0; i < pCurrentSection->m_iNumLowModelFiles; i++ )
334+
{
335+
pCurrentSection->m_ppLODModelsData[ ATerrainLODType_Low ][ i ]->Render();
336+
}
337+
}
328338
}
329339

330340
for ( TINT i = 0; i < m_pTerrainVIS->m_iNumSections; i++ )
331341
{
332-
ATerrainLODType eSectionVisibility = pCurrentSection->m_pVisibility[ i ];
342+
ATerrainLODType eSectionVisibility = pSections[ iCurrentSection ].m_pVisibility[ i ];
333343

334344
if ( eSectionVisibility != ATerrainLODType_None )
335345
{
336-
pSections[ i ].Draw( eSectionVisibility );
346+
TINT iTargetNumModels = ( eSectionVisibility == ATerrainLODType_High ) ? pSections[ i ].m_iNumHighModelFiles : pSections[ i ].m_iNumLowModelFiles;
347+
348+
if ( !pSections[ i ].IsLODLoaded( eSectionVisibility ) ||
349+
!pSections[ i ].IsLODEmpty( eSectionVisibility ) ||
350+
iTargetNumModels < 1 )
351+
{
352+
if ( pSections[ i ].IsLODLoaded( ATerrainLODType_Low ) )
353+
{
354+
// Target LOD is still loading, so let's see if we can render low LOD instead
355+
for ( TINT k = 0; k < pSections[ i ].m_iNumLowModelFiles; k++ )
356+
{
357+
if ( !pSections[ i ].m_ppLODModelsData[ ATerrainLODType_Low ][ k ]->IsGlow() )
358+
pSections[ i ].m_ppLODModelsData[ ATerrainLODType_Low ][ k ]->Render();
359+
}
360+
}
361+
}
362+
else
363+
{
364+
// Draw models of the target LOD, since it is loaded
365+
for ( TINT k = 0; k < iTargetNumModels; k++ )
366+
{
367+
if ( !pSections[ i ].m_ppLODModelsData[ eSectionVisibility ][ k ]->IsGlow() )
368+
pSections[ i ].m_ppLODModelsData[ eSectionVisibility ][ k ]->Render();
369+
}
370+
}
337371
}
338372
}
339373
}
@@ -635,81 +669,85 @@ ATerrainLODBlock* ATerrainInterface::AllocateLODBlock( ATerrainLODType a_eLODTyp
635669
ppBlocks = m_pTerrainVIS->m_ppLowBlocks;
636670
}
637671

638-
TFLOAT fMinAccessTime = TMath::MAXFLOAT;
639-
TINT iPrevFoundIndex = -1;
640-
TINT iFoundIndex;
641-
642-
for ( TINT i = 0; i < iNumBlocks; i++ )
672+
if ( iNumBlocks > 0 )
643673
{
644-
auto pBlock = ppBlocks[ i ];
645-
iFoundIndex = iPrevFoundIndex;
674+
TFLOAT fMinAccessTime = TMath::MAXFLOAT;
675+
TINT iPrevFoundIndex = -1;
676+
TINT iFoundIndex = -1;
646677

647-
if ( !pBlock->IsUsed() )
678+
for ( TINT i = 0; i < iNumBlocks; i++ )
648679
{
649-
iFoundIndex = i;
650-
if ( pBlock->m_pVISGroup == TNULL ) break;
651-
680+
auto pBlock = ppBlocks[ i ];
652681
iFoundIndex = iPrevFoundIndex;
653-
if ( !pBlock->m_pVISGroup->IsLODLoading( a_eLODType ) )
682+
683+
if ( !pBlock->IsUsed() )
654684
{
655685
iFoundIndex = i;
656-
if ( pBlock->m_pVISGroup = TNULL ) break;
686+
if ( pBlock->m_pVISGroup == TNULL ) break;
657687

658688
iFoundIndex = iPrevFoundIndex;
659-
if ( pBlock->m_fLastAccessTime < fMinAccessTime )
689+
if ( !pBlock->m_pVISGroup->IsLODLoading( a_eLODType ) )
660690
{
661-
fMinAccessTime = pBlock->m_fLastAccessTime;
662-
iFoundIndex = i;
691+
iFoundIndex = i;
692+
if ( pBlock->m_pVISGroup == TNULL ) break;
693+
694+
iFoundIndex = iPrevFoundIndex;
695+
if ( pBlock->m_fLastAccessTime < fMinAccessTime )
696+
{
697+
fMinAccessTime = pBlock->m_fLastAccessTime;
698+
iFoundIndex = i;
699+
}
663700
}
664701
}
665-
}
666702

667-
iPrevFoundIndex = iFoundIndex;
668-
}
669-
670-
if ( iFoundIndex >= 0 )
671-
{
672-
auto pBlock = ppBlocks[ iFoundIndex ];
673-
auto pVISGroup = pBlock->m_pVISGroup;
703+
iPrevFoundIndex = iFoundIndex;
704+
}
674705

675-
if ( pVISGroup )
706+
if ( iFoundIndex >= 0 )
676707
{
677-
if ( pVISGroup->IsLODEmpty( pBlock->m_eLODType ) )
678-
{
679-
pVISGroup->SetLODEmpty( pBlock->m_eLODType, TFALSE );
680-
return TNULL;
681-
}
708+
auto pBlock = ppBlocks[ iFoundIndex ];
709+
auto pVISGroup = pBlock->m_pVISGroup;
682710

683711
if ( pVISGroup )
684712
{
685-
if ( ( pVISGroup->m_eFlags & ( 21 << a_eLODType ) ) != 0 )
713+
if ( pVISGroup->IsLODEmpty( pBlock->m_eLODType ) )
714+
{
715+
pVISGroup->SetLODEmpty( pBlock->m_eLODType, TFALSE );
716+
return TNULL;
717+
}
718+
719+
if ( pVISGroup )
686720
{
687-
if ( pVISGroup->IsMatLibLoaded( pBlock->m_eLODType ) )
721+
if ( ( pVISGroup->m_eFlags & ( 21 << a_eLODType ) ) != 0 )
688722
{
689-
pVISGroup->SetLODEmpty( pBlock->m_eLODType, TFALSE );
723+
if ( pVISGroup->IsMatLibLoaded( pBlock->m_eLODType ) )
724+
{
725+
pVISGroup->SetLODEmpty( pBlock->m_eLODType, TFALSE );
690726

691-
if ( pBlock->m_pVISGroup )
727+
if ( pBlock->m_pVISGroup )
728+
{
729+
pBlock->m_pVISGroup->UnloadMatlib( pBlock->m_eLODType );
730+
return TNULL;
731+
}
732+
}
733+
else if ( pBlock->m_pVISGroup )
692734
{
693-
pBlock->m_pVISGroup->UnloadMatlib( pBlock->m_eLODType );
735+
pBlock->m_pVISGroup->DestroyLOD( pBlock->m_eLODType );
694736
}
737+
738+
return TNULL;
695739
}
696-
else if ( pBlock->m_pVISGroup )
740+
741+
if ( pVISGroup )
697742
{
698-
pBlock->m_pVISGroup->DestroyLOD( pBlock->m_eLODType );
743+
pVISGroup->DestroyLOD( pBlock->m_eLODType );
699744
}
700-
701-
return TNULL;
702-
}
703-
704-
if ( pVISGroup )
705-
{
706-
pVISGroup->DestroyLOD( pBlock->m_eLODType );
707745
}
708746
}
709-
}
710747

711-
pBlock->Assign( a_pVISGroup, a_eLODType );
712-
return pBlock;
748+
pBlock->Assign( a_pVISGroup, a_eLODType );
749+
return pBlock;
750+
}
713751
}
714752

715753
return TNULL;
@@ -1135,7 +1173,7 @@ void ATerrainInterface::CancelUnrequiredJobs()
11351173
if ( pGroup->m_eFlags & ( ATerrainSection::FLAGS_HIGH_LOD_LOADING | ATerrainSection::FLAGS_LOW_LOD_LOADING ) )
11361174
{
11371175
if ( i < 0 ) return;
1138-
if ( pGroup->m_pVisibility[ i ] == ( ( pGroup->m_eFlags >> 2 ) - 1 ) % ATerrainLODType_NUMOF ) return;
1176+
if ( m_pTerrainVIS->m_pSections[ m_iCurrentSection ].m_pVisibility[ i ] == ( ( pGroup->m_eFlags >> 2 ) - 1 ) % ATerrainLODType_NUMOF ) return;
11391177
if ( i == m_iCurrentSection ) return;
11401178

11411179
AAssetStreaming::GetSingleton()->CancelAllJobs();

OpenBarnyard/Source/Terrain/ATerrainLODBlock.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,10 @@ ATerrainLODBlock::~ATerrainLODBlock()
4242
m_pUnk2 = &s_Unk2AfterDestroy;
4343
}
4444

45-
// $Barnyard: FUNCTION 005ecc80
45+
// $Barnyard: FUNCTION 005ecc80 +
4646
void ATerrainLODBlock::SetupTRB( TTRB* a_pTRB, ATerrainLODBlock* a_pOther )
4747
{
48-
Node::InsertAfter( a_pOther );
48+
a_pOther->m_pNext = this;
4949
a_pTRB->SetMemoryFunctions(
5050
[]( TTRB::AllocType alloctype, TUINT32 size, TINT16 unk1, TUINT32 unk2, void* userData ) -> void* {
5151
auto pBlock = TSTATICCAST( ATerrainLODBlock, userData );
@@ -55,7 +55,7 @@ void ATerrainLODBlock::SetupTRB( TTRB* a_pTRB, ATerrainLODBlock* a_pOther )
5555
*pBlock->m_pAllocatedSize += size;
5656
}
5757

58-
return TMemalign( 128, size, pBlock->Next()->m_pCreatedMemBlock );
58+
return TMemalign( 128, size, pBlock->m_pNext->m_pCreatedMemBlock );
5959
},
6060
[]( TTRB::AllocType alloctype, void* ptr, TINT16 unk1, TUINT32 unk2, void* userData ) {
6161
TFree( ptr );

0 commit comments

Comments
 (0)