OpenBarnyard
 
Loading...
Searching...
No Matches
ATerrainSection.cpp
Go to the documentation of this file.
1#include "pch.h"
2#include "ATerrainSection.h"
3#include "ATerrainInterface.h"
7
8#include <Toshi/TScheduler.h>
9
10#ifdef TOSHI_SKU_WINDOWS
13#endif // TOSHI_SKU_WINDOWS
14
15//-----------------------------------------------------------------------------
16// Enables memory debugging.
17// Note: Should be the last include!
18//-----------------------------------------------------------------------------
19#include <Core/TMemoryDebugOn.h>
20
22
24{
25 TASSERT( a_eLODType != ATerrainLODType_None );
26
28 {
29 // Draw models of the high LOD
30 for ( TINT i = 0; i < m_iNumHighModelFiles; i++ )
31 {
32 m_ppLODModelsData[ ATerrainLODType_High ][ i ]->Render();
33 }
34 }
35 else
36 {
37 // High LOD is still loading so let's check if we can render low LOD instead
39 {
40 // Draw models of the low LOD
41 for ( TINT i = 0; i < m_iNumLowModelFiles; i++ )
42 {
43 m_ppLODModelsData[ ATerrainLODType_Low ][ i ]->Render();
44 }
45 }
46 }
47}
48
50{
51 auto pTerrain = ATerrainInterface::GetSingleton();
52
53 if ( m_szCollisionFilename[ 0 ] != '\0' )
54 {
55 auto pBlock = ( !pTerrain->IsCollisionStreamed() ) ?
56 pTerrain->GetVIS()->m_pPersistantTerrainBlock :
57 m_ppHighLODBlocks[ m_iCollisionMemBlockID ];
58
59 m_pCollisionModelData = new ( pBlock->GetMemBlock() ) ModelNode();
60
61 auto pTRB = new ( pBlock->GetMemBlock() ) TTRB();
62 pBlock->SetupTRB( pTRB, pBlock );
63
64 auto pModelLoaderJob = pTerrain->GetFreeModelLoaderJob();
65 pModelLoaderJob->InitJob(
66 &m_pCollisionModelData->m_ModelRef,
67 pTRB,
68 m_szCollisionFilename,
69 pTerrain->IsCollisionStreamed()
70 );
71
72 auto pCollisionJob = pTerrain->GetFreeCollisionLoaderJob();
73 pCollisionJob->InitJob( this, TFALSE );
74
75 AAssetStreaming::GetSingleton()->AddMainThreadJob( pModelLoaderJob );
76 AAssetStreaming::GetSingleton()->AddMainThreadJob( pCollisionJob );
77 m_eFlags |= FLAGS_COLLISION_LOADING;
78 }
79}
80
82{
83 TASSERT( a_eLODType == ATerrainLODType_High || a_eLODType == ATerrainLODType_Low );
84
85 auto pTerrain = ATerrainInterface::GetSingleton();
86
87 if ( !IsLODLoading( a_eLODType ) && !IsLODLoaded( a_eLODType ) )
88 {
89 const TCHAR** ppLODNames;
90 TINT iNumLODs;
91 GetLODNames( a_eLODType, ppLODNames, iNumLODs );
92
93 if ( iNumLODs == 0 && m_szCollisionFilename[ 0 ] == '\0' )
94 {
95 SetLODQueued( a_eLODType, TFALSE );
96 SetLODEmpty( a_eLODType, TTRUE );
97 SetLODLoaded( a_eLODType, TTRUE );
98 }
99 else
100 {
101 ATerrainLODBlock** ppLODBlocks;
102 TUINT16 uiNumMemBlocks;
103 GetLODBlocks( a_eLODType, ppLODBlocks, uiNumMemBlocks );
104
105 TUINT8* pLODToBlock = ( a_eLODType == ATerrainLODType_High ) ? m_pHighLODToBlock : m_pLowLODToBlock;
106
107 for ( TINT i = 0; i < uiNumMemBlocks; i++ )
108 {
109 if ( ppLODBlocks[ i ] == TNULL )
110 {
111 ppLODBlocks[ i ] = pTerrain->AllocateLODBlock( a_eLODType, this );
112
113 if ( ppLODBlocks[ i ] == TNULL )
114 {
115 TASSERT( TFALSE, "Couldn't allocated new LOD block!" );
116 return;
117 }
118
119 ppLODBlocks[ i ]->m_bIsUnused = TFALSE;
120 }
121 }
122
123 if ( a_eLODType == ATerrainLODType_High && pTerrain->IsCollisionStreamed() )
124 {
126 }
127
128 LoadMatlib( a_eLODType );
129
130 for ( TINT i = 0; i < iNumLODs; i++ )
131 {
132 if ( m_ppLODModelsData[ a_eLODType ][ i ] == TNULL )
133 {
134 auto pBlock = ppLODBlocks[ pLODToBlock[ i ] ];
135 auto pModelData = new ( pBlock->GetMemBlock() ) ModelNode();
136
137 auto pTRB = new ( pBlock->GetMemBlock() ) TTRB();
138 pBlock->SetupTRB( pTRB, pBlock );
139 m_ppLODModelsData[ a_eLODType ][ i ] = pModelData;
140
141 auto pModelLoaderJob = pTerrain->GetFreeModelLoaderJob();
142 pModelLoaderJob->InitJob(
143 &pModelData->m_ModelRef,
144 pTRB,
145 ppLODNames[ i ],
146 TTRUE
147 );
148
149 AAssetStreaming::GetSingleton()->AddMainThreadJob( pModelLoaderJob );
150 }
151 }
152
153 auto pSectionJob = pTerrain->GetFreeSectionLoaderJob();
154 pSectionJob->InitJob( this, a_eLODType );
155
156 AAssetStreaming::GetSingleton()->AddMainThreadJob( pSectionJob );
157
158 SetLODQueued( a_eLODType, TFALSE );
159 SetLODLoading( a_eLODType, TTRUE );
160 }
161 }
162}
163
165{
166 TASSERT( a_eLODType == ATerrainLODType_High || a_eLODType == ATerrainLODType_Low );
167
168 TUINT8 uiAllocAtBlock;
169 ATerrainLODBlock** ppBlocks;
170
171 if ( a_eLODType == ATerrainLODType_High )
172 {
173 if ( m_szHighMatLibFilename[ 0 ] == '\0' ) return;
174 uiAllocAtBlock = m_iHighMatLibMemBlockID;
175 ppBlocks = m_ppHighLODBlocks;
176 }
177 else
178 {
179 if ( m_szLowMatLibFilename[ 0 ] == '\0' ) return;
180 uiAllocAtBlock = m_iLowMatLibMemBlockID;
181 ppBlocks = m_ppLowLODBlocks;
182 }
183
184 auto pBlock = ppBlocks[ uiAllocAtBlock ];
185 auto pMatlibJob = ATerrainInterface::GetSingleton()->GetFreeMatlibLoaderJob();
186
187 if ( a_eLODType == ATerrainLODType_High )
188 {
189 m_pMatLibHighTRB = new ( pBlock->GetMemBlock() ) TTRB();
190 pBlock->SetupTRB( m_pMatLibHighTRB, pBlock );
191
192 pMatlibJob->InitJob( m_szHighMatLibFilename, m_pMatLibHighTRB, m_pMatLibHigh, pBlock->GetMemBlock() );
193 }
194 else
195 {
196 m_pMatLibLowTRB = new ( pBlock->GetMemBlock() ) TTRB();
197 pBlock->SetupTRB( m_pMatLibLowTRB, pBlock );
198
199 pMatlibJob->InitJob( m_szLowMatLibFilename, m_pMatLibLowTRB, m_pMatLibLow, pBlock->GetMemBlock() );
200 }
201
202 AAssetStreaming::GetSingleton()->AddMainThreadJob( pMatlibJob );
203}
204
206{
207 TASSERT( a_eLODType == ATerrainLODType_High || a_eLODType == ATerrainLODType_Low );
208
209 if ( a_eLODType == ATerrainLODType_High )
210 {
211 if ( m_pMatLibHigh )
212 {
213 AMaterialLibraryManager::GetSingleton()->UnloadTexturesOfLibrary( m_pMatLibHigh );
214 m_pMatLibHigh->Destroy();
215 m_pMatLibHigh = TNULL;
216 }
217
218 if ( m_pMatLibHighTRB )
219 {
220 delete m_pMatLibHighTRB;
221 m_pMatLibHighTRB = TNULL;
222 }
223 }
224 else
225 {
226 if ( m_pMatLibLow )
227 {
228 AMaterialLibraryManager::GetSingleton()->UnloadTexturesOfLibrary( m_pMatLibLow );
229 m_pMatLibLow->Destroy();
230 m_pMatLibLow = TNULL;
231 }
232
233 if ( m_pMatLibLowTRB )
234 {
235 delete m_pMatLibLowTRB;
236 m_pMatLibLowTRB = TNULL;
237 }
238 }
239}
240
242{
243 TASSERT( a_eLODType == ATerrainLODType_High || a_eLODType == ATerrainLODType_Low );
244
245 auto pTerrain = ATerrainInterface::GetSingleton();
246 TINT iNumLODs = GetLODCount( a_eLODType );
247
248 for ( TINT i = 0; i < iNumLODs; i++ )
249 {
250 if ( m_ppLODModelsData[ a_eLODType ][ i ] )
251 {
252 pTerrain->DestroyModelData( m_ppLODModelsData[ a_eLODType ][ i ] );
253 m_ppLODModelsData[ a_eLODType ][ i ] = TNULL;
254 }
255 }
256
257 UnloadMatlib( a_eLODType );
258
259 TUINT32 eNewFlags;
260
261 if ( a_eLODType == ATerrainLODType_High )
262 {
263 if ( m_pCollisionModelData && pTerrain->IsCollisionStreamed() )
264 {
265 pTerrain->DestroyModelData( m_pCollisionModelData );
266 m_pCollisionModelData = TNULL;
267 }
268
269 for ( TUINT i = 0; i < m_iNumHighMemBlocksUsed; i++ )
270 {
271 auto pBlock = m_ppHighLODBlocks[ i ];
272
273 if ( pBlock )
274 {
275 m_ppHighLODBlocks[ i ] = TNULL;
276 pBlock->Assign( TNULL, ATerrainLODType_None );
277 }
278 }
279
281 }
282 else
283 {
284 for ( TUINT i = 0; i < m_iNumLowMemBlocksUsed; i++ )
285 {
286 auto pBlock = m_ppLowLODBlocks[ i ];
287
288 if ( pBlock )
289 {
290 m_ppLowLODBlocks[ i ] = TNULL;
291 pBlock->Assign( TNULL, ATerrainLODType_None );
292 }
293 }
294
296 }
297
298 m_eFlags = eNewFlags;
299 SetLODEmpty( a_eLODType, TFALSE );
300}
301
303{
304 for ( TINT i = 0; i < ATerrainLODType_NUMOF; i++ )
305 {
306 if ( IsLODQueued( i ) )
307 {
308 ATerrainLODBlock** ppLODBlocks;
309 TUINT16 uiNumLODBlocks;
310 GetLODBlocks( i, ppLODBlocks, uiNumLODBlocks );
311
312 for ( TINT k = 0; k < uiNumLODBlocks; k++ )
313 {
314 ppLODBlocks[ k ]->Assign( TNULL, ATerrainLODType_None );
315 }
316
317 SetLODQueued( i, TFALSE );
318 }
319 }
320}
321
323{
324 TASSERT( a_eLODType == ATerrainLODType_High || a_eLODType == ATerrainLODType_Low );
325
326 if ( a_eLODType == ATerrainLODType_High )
327 {
328 return m_pMatLibHigh != TNULL;
329 }
330 else
331 {
332 return m_pMatLibLow != TNULL;
333 }
334}
335
337{
338 TASSERT( a_eLODType == ATerrainLODType_High || a_eLODType == ATerrainLODType_Low );
339
340 if ( a_bQueued )
341 {
342 m_eFlags |= ( 16 << a_eLODType );
343 }
344 else
345 {
346 m_eFlags &= ~( 16 << a_eLODType );
347 }
348}
349
351{
352 TASSERT( a_eLODType == ATerrainLODType_High || a_eLODType == ATerrainLODType_Low );
353
354 if ( a_bLoaded )
355 {
356 m_eFlags |= ( 1 << ( a_eLODType ) );
357 }
358 else
359 {
360 m_eFlags &= ~( 1 << ( a_eLODType ) );
361 }
362}
363
365{
366 TASSERT( a_eLODType == ATerrainLODType_High || a_eLODType == ATerrainLODType_Low );
367
368 if ( a_bLoading )
369 {
370 m_eFlags |= ( 1 << ( a_eLODType + ATerrainLODType_NUMOF ) );
371 }
372 else
373 {
374 m_eFlags &= ~( 1 << ( a_eLODType + ATerrainLODType_NUMOF ) );
375 }
376}
377
379{
380 TASSERT( a_eLODType == ATerrainLODType_High || a_eLODType == ATerrainLODType_Low );
381
382 if ( a_bEmpty )
383 {
384 m_eFlags |= ( 64 << a_eLODType );
385 }
386 else
387 {
388 m_eFlags &= ~( 64 << a_eLODType );
389 }
390}
391
397
399{
400 TIMPLEMENT_D( "Destroy collision data" );
401
402 if ( m_pSceneObject )
403 {
404 m_pSceneObject->Delete();
405 }
406}
407
409{
410 if ( m_bCreated )
411 {
413
414 if ( pAnimatedMaterial )
415 {
416 TScheduler* pScheduler = g_oSystemManager.GetScheduler();
417
418 pAnimatedMaterial->AddUVOffsetY( 1, pScheduler->GetCurrentDeltaTime() * 0.02f );
419
420 if ( 1.0 <= pAnimatedMaterial->GetUVOffsetY( 1 ) )
421 pAnimatedMaterial->AddUVOffsetY( 1, -1.0f );
422 }
423
424 ATerrainInterface* pTerrain = ATerrainInterface::GetSingleton();
425 AWorldShaderHAL* pShader = TSTATICCAST( AWorldShaderHAL, AWorldShader::GetSingleton() );
426
428 pShader->SetColours( pTerrain->GetLitShadowColor(), pTerrain->GetLitAmbientColor() );
429
430 m_pSceneObject->EnableSkeletonUpdate();
431 m_pSceneObject->RenderIfVisible();
432
434 pShader->SetColours( pTerrain->GetDefaultShadowColor(), pTerrain->GetDefaultAmbientColor() );
435 }
436}
437
439{
440 if ( a_bUseLighting )
442 else
444}
445
447{
448 if ( a_bIsGlow )
450 else
452
453 if ( TNULL != m_pSceneObject )
454 {
455 auto pModel = m_pSceneObject->GetModelRef()->GetModel();
456
457 for ( TINT i = 0; i < pModel->GetNumLODs(); i++ )
458 {
459 auto& rLOD = pModel->GetLOD( i );
460
461 for ( TINT k = 0; k < rLOD.iNumMeshes; k++ )
462 {
463 auto pMesh = rLOD.ppMeshes[ k ];
464 auto pMaterial = TSTATICCAST( AWorldMaterial, pMesh->GetMaterial() );
465
466 pMesh->SetFlags( TMesh::State_Glow, TTRUE );
467 pMaterial->SetFlags( TMaterial::FLAGS_GLOW, a_bIsGlow );
468 pMaterial->SetBlendMode( 3 );
469 }
470 }
471 }
472}
#define TASSERT(X,...)
Definition Defines.h:138
#define TSTATICCAST(POINTERTYPE, VALUE)
Definition Defines.h:69
#define TIMPLEMENT_D(DESC)
Definition Defines.h:137
#define TOSHI_NAMESPACE_USING
Definition Defines.h:46
#define TDYNAMICCAST(T, OBJECT)
Definition TObject.h:227
uint16_t TUINT16
Definition Typedefs.h:15
unsigned int TUINT
Definition Typedefs.h:8
char TCHAR
Definition Typedefs.h:20
uint8_t TUINT8
Definition Typedefs.h:17
#define TNULL
Definition Typedefs.h:23
uint32_t TUINT32
Definition Typedefs.h:13
int TINT
Definition Typedefs.h:7
#define TFALSE
Definition Typedefs.h:24
#define TTRUE
Definition Typedefs.h:25
bool TBOOL
Definition Typedefs.h:6
@ ATerrainLODType_None
@ ATerrainLODType_NUMOF
@ ATerrainLODType_High
@ ATerrainLODType_Low
TINT8 ATerrainLODType
TSystemManager g_oSystemManager
Definition TSystem.cpp:15
Definition TTRB.h:253
@ State_Glow
Definition TMesh.h:21
TFLOAT GetCurrentDeltaTime() const
Definition TScheduler.h:62
void AddUVOffsetY(TUINT a_uiTextureIndex, TFLOAT a_fOffset)
TFLOAT GetUVOffsetY(TUINT a_uiTextureIndex)
void SetColours(const Toshi::TVector4 &a_rShadowColour, const Toshi::TVector4 a_rAmbientColour)
const Toshi::TVector4 & GetDefaultAmbientColor() const
const Toshi::TVector4 & GetLitShadowColor() const
const Toshi::TVector4 & GetLitAmbientColor() const
const Toshi::TVector4 & GetDefaultShadowColor() const
void Assign(ATerrainSection *a_pVISGroup, ATerrainLODType a_eLODType)
friend class ATerrainInterface
void LoadMatlib(ATerrainLODType a_eLODType)
void GetLODNames(ATerrainLODType a_eLODType, const TCHAR **&a_rLODs, TINT &a_rNumLODs)
void UnloadMatlib(ATerrainLODType a_eLODType)
TBOOL IsLODQueued(ATerrainLODType a_eLODType) const
void SetLODLoaded(ATerrainLODType a_eLODType, TBOOL a_bLoaded)
TINT GetLODCount(ATerrainLODType a_eLODType)
void DestroyLOD(ATerrainLODType a_eLODType)
void SetLODQueued(ATerrainLODType a_eLODType, TBOOL a_bQueued)
void LoadModels(ATerrainLODType a_eLODType)
TBOOL IsLODLoaded(ATerrainLODType a_eLODType) const
void SetLODEmpty(ATerrainLODType a_eLODType, TBOOL a_bEmpty)
TBOOL IsMatLibLoaded(ATerrainLODType a_eLODType) const
TBOOL IsLODLoading(ATerrainLODType a_eLODType) const
void SetLODLoading(ATerrainLODType a_eLODType, TBOOL a_bLoading)
void GetLODBlocks(ATerrainLODType a_eLODType, ATerrainLODBlock **&a_rMemBlocks, TUINT16 &a_rNumMemBlocks)
void Draw(ATerrainLODType a_eLODType)
AWorldMaterial * m_pAnimatedMaterial
void SetGlow(TBOOL a_bIsGlow)
Toshi::TSceneObject * m_pSceneObject
void SetUseLighting(TBOOL a_bUseLighting)
char m_szType[TYPE_NAME_MAX_SIZE+1]