Skip to content

Commit 63cbae1

Browse files
committed
Update Repo + New IterateDrawablesInRegion Implementation
1 parent dbdcd89 commit 63cbae1

11 files changed

Lines changed: 629 additions & 55 deletions

File tree

GeneralsMD/Code/GameEngine/Include/Common/GlobalData.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -556,6 +556,10 @@ class GlobalData : public SubsystemInterface
556556
//-allAdvice feature
557557
//Bool m_allAdvice;
558558

559+
Bool m_usePartitionManagerToIterateDrawables;
560+
Bool m_usePartitionManagerToIterateDrawablesOnlySelect;
561+
Bool m_useEfficientDrawableScheme;
562+
559563

560564
// the trailing '\' is included!
561565
const AsciiString &getPath_UserData() const { return m_userDataDir; }

GeneralsMD/Code/GameEngine/Include/GameClient/Drawable.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -640,6 +640,7 @@ class Drawable : public Thing,
640640

641641
virtual void reactToTransformChange(const Matrix3D* oldMtx, const Coord3D* oldPos, Real oldAngle);
642642
void updateHiddenStatus();
643+
Bool checkDrawModuleNullptr(DrawModule** dm);
643644

644645
private:
645646

GeneralsMD/Code/GameEngine/Include/GameClient/GameClient.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,10 @@ class GameClient : public SubsystemInterface,
157157
void incrementRenderedObjectCount() { m_renderedObjectCount++; }
158158
virtual void notifyTerrainObjectMoved(Object *obj) = 0;
159159

160+
void informClientNewDrawable(Drawable *draw);
161+
void addDrawableToEfficientList(Drawable *draw);
162+
inline void clearEfficientDrawablesList() { m_drawablesListMarkedForClear = TRUE; }
163+
160164

161165
protected:
162166

GeneralsMD/Code/GameEngine/Include/GameLogic/PartitionManager.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@
5959
#include "Common/Snapshot.h"
6060
#include "Common/Geometry.h"
6161
#include "GameClient/Display.h" // for ShroudLevel
62+
#include "GameClient/Drawable.h"
63+
64+
class Drawable;
6265

6366
//-----------------------------------------------------------------------------
6467
// defines
@@ -1534,6 +1537,10 @@ class PartitionManager : public SubsystemInterface, public Snapshot
15341537
// If saveToFog is false, then we are writing STORE_PERMENANT_REVEAL
15351538
void storeFoggedCells(ShroudStatusStoreRestore &outPartitionStore, Bool storeToFog) const;
15361539
void restoreFoggedCells(const ShroudStatusStoreRestore &inPartitionStore, Bool restoreToFog);
1540+
1541+
std::list<Drawable*> getDrawablesInRegion( IRegion2D *region2D );
1542+
std::list<Drawable*> getDrawablesInRegionEfficient();
1543+
inline Bool hasNoOffset() const { return m_radiusVec.empty(); }
15371544
};
15381545

15391546
// -----------------------------------------------------------------------------

GeneralsMD/Code/GameEngine/Source/Common/GlobalData.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -494,6 +494,10 @@ GlobalData* GlobalData::m_theOriginal = NULL;
494494

495495
{ "PlayStats", INI::parseInt, NULL, offsetof( GlobalData, m_playStats ) },
496496

497+
{ "UsePartitionManagerToIterateDrawables", INI::parseBool, NULL, offsetof(GlobalData, m_usePartitionManagerToIterateDrawables) },
498+
{ "UsePartitionManagerToIterateDrawablesOnlySelect", INI::parseBool, NULL, offsetof(GlobalData, m_usePartitionManagerToIterateDrawablesOnlySelect) },
499+
{ "UseEfficientIterateDrawablesScheme", INI::parseBool, NULL, offsetof(GlobalData, m_useEfficientDrawableScheme) },
500+
497501
#if defined(RTS_DEBUG)
498502
{ "DisableCameraFade", INI::parseBool, NULL, offsetof( GlobalData, m_disableCameraFade ) },
499503
{ "DisableScriptedInputDisabling", INI::parseBool, NULL, offsetof( GlobalData, m_disableScriptedInputDisabling ) },
@@ -1029,6 +1033,10 @@ GlobalData::GlobalData()
10291033

10301034
m_keyboardCameraRotateSpeed = 0.1f;
10311035

1036+
m_usePartitionManagerToIterateDrawables = FALSE;
1037+
m_usePartitionManagerToIterateDrawablesOnlySelect = FALSE;
1038+
m_useEfficientDrawableScheme = FALSE;
1039+
10321040
// Set user data directory based on registry settings instead of INI parameters. This allows us to
10331041
// localize the leaf name.
10341042
char temp[_MAX_PATH + 1];

GeneralsMD/Code/GameEngine/Source/Common/Thing/Thing.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
#include "Common/Team.h"
4646
#include "Lib/trig.h"
4747
#include "GameLogic/TerrainLogic.h"
48+
#include "GameClient/GameClient.h"
4849

4950

5051
static constexpr const Real InitialThingPosX = 0.0f;
@@ -169,6 +170,8 @@ void Thing::setPositionZ( Real z )
169170
setTransformMatrix(&mtx);
170171
}
171172
DEBUG_ASSERTCRASH(!(_isnan(getPosition()->x) || _isnan(getPosition()->y) || _isnan(getPosition()->z)), ("Drawable/Object position NAN! '%s'", m_template->getName().str() ));
173+
if(TheGameClient && TheGlobalData->m_useEfficientDrawableScheme && AsObject(this) && AsObject(this)->getDrawable())
174+
TheGameClient->informClientNewDrawable(AsObject(this)->getDrawable());
172175
}
173176

174177
//=============================================================================
@@ -198,6 +201,8 @@ void Thing::setPosition( const Coord3D *pos )
198201
setTransformMatrix(&mtx);
199202
}
200203
DEBUG_ASSERTCRASH(!(_isnan(getPosition()->x) || _isnan(getPosition()->y) || _isnan(getPosition()->z)), ("Drawable/Object position NAN! '%s'", m_template->getName().str() ));
204+
if(TheGameClient && TheGlobalData->m_useEfficientDrawableScheme && AsObject(this) && AsObject(this)->getDrawable())
205+
TheGameClient->informClientNewDrawable(AsObject(this)->getDrawable());
201206
}
202207

203208
//=============================================================================

GeneralsMD/Code/GameEngine/Source/GameClient/Drawable.cpp

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2653,7 +2653,7 @@ void Drawable::draw()
26532653
applyPhysicsXform(&transformMtx);
26542654
}
26552655

2656-
for (DrawModule** dm = getDrawModules(); *dm; ++dm)
2656+
for (DrawModule** dm = getDrawModules(); checkDrawModuleNullptr(dm) && *dm; ++dm)
26572657
{
26582658
(*dm)->doDrawModule(&transformMtx);
26592659
}
@@ -3983,7 +3983,7 @@ DrawModule** Drawable::getDrawModules()
39833983
}
39843984
else
39853985
{
3986-
for (DrawModule** dm2 = dm; *dm2; ++dm2)
3986+
for (DrawModule** dm2 = dm; checkDrawModuleNullptr(dm2) && *dm2; ++dm2)
39873987
{
39883988
ObjectDrawInterface* di = (*dm2)->getObjectDrawInterface();
39893989
if (di)
@@ -3998,6 +3998,20 @@ DrawModule** Drawable::getDrawModules()
39983998
return dm;
39993999
}
40004000

4001+
Bool Drawable::checkDrawModuleNullptr(DrawModule** dm)
4002+
{
4003+
if(!TheGlobalData->m_useEfficientDrawableScheme)
4004+
return TRUE;
4005+
4006+
if(dm == nullptr)
4007+
{
4008+
//TheGameClient->removeDrawableFromEfficientList(this);
4009+
//TheGameClient->clearEfficientDrawablesList();
4010+
return FALSE;
4011+
}
4012+
return TRUE;
4013+
}
4014+
40014015
//-------------------------------------------------------------------------------------------------
40024016
DrawModule const** Drawable::getDrawModules() const
40034017
{

GeneralsMD/Code/GameEngine/Source/GameClient/GameClient.cpp

Lines changed: 108 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@
8282
#include "GameLogic/GameLogic.h"
8383
#include "GameLogic/GhostObject.h"
8484
#include "GameLogic/Object.h"
85+
#include "GameLogic/PartitionManager.h"
8586
#include "GameLogic/ScriptEngine.h" // For TheScriptEngine - jkmcd
8687

8788
#define DRAWABLE_HASH_SIZE 8192
@@ -784,21 +785,119 @@ void GameClient::updateHeadless()
784785
*/
785786
void GameClient::iterateDrawablesInRegion( Region3D *region, GameClientFuncPtr userFunc, void *userData )
786787
{
787-
Drawable *draw, *nextDrawable;
788+
if(m_drawablesListMarkedForClear)
789+
{
790+
m_drawablesList.clear();
791+
m_drawablesListMarkedForClear = FALSE;
792+
}
793+
794+
if(region != NULL && TheGlobalData->m_useEfficientDrawableScheme && !m_drawablesList.empty())
795+
{
796+
//IamInnocent - Attempted to use an Efficient Implementation of PartitionManager code to use WorldCell for Finding Drawables - 7/10/2025
797+
for( std::list< Drawable* >::iterator it = m_drawablesList.begin(); it != m_drawablesList.end();)
798+
{
799+
Coord3D pos = *(*it)->getPosition();
800+
if( pos.x >= region->lo.x && pos.x <= region->hi.x &&
801+
pos.y >= region->lo.y && pos.y <= region->hi.y &&
802+
pos.z >= region->lo.z && pos.z <= region->hi.z )
803+
{
804+
(*userFunc)( (*it), userData );
805+
}
806+
else
807+
{
808+
it = m_drawablesList.erase(it);
809+
continue;
810+
}
811+
++it;
812+
}
813+
814+
std::list< Drawable* > newDrawables = ThePartitionManager->getDrawablesInRegionEfficient();
788815

789-
for( draw = m_drawableList; draw; draw=nextDrawable )
816+
if(!newDrawables.empty())
817+
{
818+
for( std::list< Drawable* >::const_iterator it_new = newDrawables.begin(); it_new != newDrawables.end(); ++it_new )
819+
{
820+
Coord3D pos_new = *(*it_new)->getPosition();
821+
if( pos_new.x >= region->lo.x && pos_new.x <= region->hi.x &&
822+
pos_new.y >= region->lo.y && pos_new.y <= region->hi.y &&
823+
pos_new.z >= region->lo.z && pos_new.z <= region->hi.z )
824+
{
825+
addDrawableToEfficientList(*it_new);
826+
(*userFunc)( (*it_new), userData );
827+
}
828+
}
829+
}
830+
}
831+
else if(region == NULL || ThePartitionManager->hasNoOffset() ||
832+
( !TheGlobalData->m_usePartitionManagerToIterateDrawables || TheGlobalData->m_usePartitionManagerToIterateDrawablesOnlySelect ) )
790833
{
791-
nextDrawable = draw->getNextDrawable();
834+
Drawable *draw, *nextDrawable;
792835

793-
Coord3D pos = *draw->getPosition();
794-
if( region == NULL ||
795-
(pos.x >= region->lo.x && pos.x <= region->hi.x &&
796-
pos.y >= region->lo.y && pos.y <= region->hi.y &&
797-
pos.z >= region->lo.z && pos.z <= region->hi.z) )
836+
for( draw = m_drawableList; draw; draw=nextDrawable )
798837
{
799-
(*userFunc)( draw, userData );
838+
nextDrawable = draw->getNextDrawable();
839+
840+
Coord3D pos = *draw->getPosition();
841+
if( region == NULL ||
842+
(pos.x >= region->lo.x && pos.x <= region->hi.x &&
843+
pos.y >= region->lo.y && pos.y <= region->hi.y &&
844+
pos.z >= region->lo.z && pos.z <= region->hi.z) )
845+
{
846+
if(TheGlobalData->m_useEfficientDrawableScheme)
847+
addDrawableToEfficientList(draw);
848+
(*userFunc)( draw, userData );
849+
}
800850
}
801851
}
852+
else
853+
{
854+
//IamInnocent - Attempted to use PartitionManager code to use WorldCell for Finding Drawables - 6/10/2025
855+
std::list< Drawable* > drawables = ThePartitionManager->getDrawablesInRegion( NULL );
856+
857+
for( std::list< Drawable* >::iterator it = drawables.begin(); it != drawables.end(); ++it )
858+
{
859+
Coord3D pos = *(*it)->getPosition();
860+
if( pos.x >= region->lo.x && pos.x <= region->hi.x &&
861+
pos.y >= region->lo.y && pos.y <= region->hi.y &&
862+
pos.z >= region->lo.z && pos.z <= region->hi.z )
863+
{
864+
if(TheGlobalData->m_useEfficientDrawableScheme)
865+
addDrawableToEfficientList(*it);
866+
(*userFunc)( (*it), userData );
867+
}
868+
}
869+
}
870+
}
871+
872+
873+
/** -----------------------------------------------------------------------------------------------
874+
* Inform the Client to add this Unit to the Efficient Drawable Lisst
875+
*/
876+
void GameClient::informClientNewDrawable(Drawable *draw)
877+
{
878+
// sanity
879+
if( draw == NULL )
880+
return;
881+
882+
// Efficient drawing scheme is not on
883+
// Checked on the Thing.cpp
884+
//if(!TheGlobalData->m_useEfficientDrawableScheme)
885+
// return;
886+
887+
// Only inform New Drawable if the drawables are checked at least once.
888+
if(m_drawablesList.empty())
889+
return;
890+
891+
addDrawableToEfficientList(draw);
892+
}
893+
894+
void GameClient::addDrawableToEfficientList(Drawable *draw)
895+
{
896+
std::list< Drawable* >::iterator it = std::find(m_drawablesList.begin(), m_drawablesList.end(), draw);
897+
if (it == m_drawablesList.end())
898+
{
899+
m_drawablesList.push_back( draw );
900+
}
802901
}
803902

804903
/**Helper function to update fake GLA structures to become visible to certain players.

0 commit comments

Comments
 (0)