diff --git a/Generals/Code/GameEngine/Include/Common/ThingTemplate.h b/Generals/Code/GameEngine/Include/Common/ThingTemplate.h index aaf7a2e7c6..2be32629a6 100644 --- a/Generals/Code/GameEngine/Include/Common/ThingTemplate.h +++ b/Generals/Code/GameEngine/Include/Common/ThingTemplate.h @@ -430,6 +430,7 @@ class ThingTemplate : public Overridable Real getFenceXOffset() const { return m_fenceXOffset; } // return fence offset Bool isBridge() const { return m_isBridge; } // return fence offset + Bool isBridgeLike() const { return isBridge() || isKindOf(KINDOF_WALK_ON_TOP_OF_WALL); } // Only Object can ask this. Everyone else should ask the Object. In fact, you really should ask the Object everything. Real friend_getVisionRange() const { return m_visionRange; } ///< get vision range diff --git a/Generals/Code/GameEngine/Source/GameLogic/System/GameLogic.cpp b/Generals/Code/GameEngine/Source/GameLogic/System/GameLogic.cpp index 343f5889e8..1f01c04aa4 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/System/GameLogic.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/System/GameLogic.cpp @@ -1565,14 +1565,7 @@ void GameLogic::startNewGame( Bool saveGame ) if( thingTemplate == NULL ) continue; - Bool isBridgeLikeObject = false; - - if (thingTemplate->isBridge()) - isBridgeLikeObject = true; - if (thingTemplate->isKindOf(KINDOF_WALK_ON_TOP_OF_WALL)) - isBridgeLikeObject = true; - - if (!isBridgeLikeObject) + if (!thingTemplate->isBridgeLike()) continue; Team *team = ThePlayerList->getNeutralPlayer()->getDefaultTeam(); @@ -1679,11 +1672,8 @@ void GameLogic::startNewGame( Bool saveGame ) if( thingTemplate == NULL ) continue; - Bool isBridgeLikeObject = false; - if (thingTemplate->isBridge()) isBridgeLikeObject = true; - if (thingTemplate->isKindOf(KINDOF_WALK_ON_TOP_OF_WALL)) isBridgeLikeObject = true; - if (isBridgeLikeObject) - continue; // bridges have to be added earlier. + if (thingTemplate->isBridgeLike()) + continue; // bridges have to be added earlier. Bool useTrees = TheGlobalData->m_useTrees; if (TheRecorder && TheRecorder->isMultiplayer()) { diff --git a/GeneralsMD/Code/GameEngine/Include/Common/ThingTemplate.h b/GeneralsMD/Code/GameEngine/Include/Common/ThingTemplate.h index aa18d38321..14fbd7a4e7 100644 --- a/GeneralsMD/Code/GameEngine/Include/Common/ThingTemplate.h +++ b/GeneralsMD/Code/GameEngine/Include/Common/ThingTemplate.h @@ -430,6 +430,7 @@ class ThingTemplate : public Overridable Real getFenceXOffset() const { return m_fenceXOffset; } // return fence offset Bool isBridge() const { return m_isBridge; } // return fence offset + Bool isBridgeLike() const { return isBridge() || isKindOf(KINDOF_WALK_ON_TOP_OF_WALL); } // Only Object can ask this. Everyone else should ask the Object. In fact, you really should ask the Object everything. Real friend_calcVisionRange() const { return m_visionRange; } ///< get vision range diff --git a/GeneralsMD/Code/GameEngine/Include/GameLogic/GameLogic.h b/GeneralsMD/Code/GameEngine/Include/GameLogic/GameLogic.h index ddff182fc8..285847aad9 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameLogic/GameLogic.h +++ b/GeneralsMD/Code/GameEngine/Include/GameLogic/GameLogic.h @@ -290,6 +290,8 @@ class GameLogic : public SubsystemInterface, public Snapshot void remakeSleepyUpdate(); void validateSleepyUpdate() const; + static void createOptimizedTree(const ThingTemplate *thingTemplate, Coord3D *pos, Real angle); + private: /** diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/System/GameLogic.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/System/GameLogic.cpp index 0e3e69606f..540731886d 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/System/GameLogic.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/System/GameLogic.cpp @@ -1727,14 +1727,7 @@ void GameLogic::startNewGame( Bool loadingSaveGame ) if( thingTemplate == NULL ) continue; - Bool isBridgeLikeObject = false; - - if (thingTemplate->isBridge()) - isBridgeLikeObject = true; - if (thingTemplate->isKindOf(KINDOF_WALK_ON_TOP_OF_WALL)) - isBridgeLikeObject = true; - - if (!isBridgeLikeObject) + if (!thingTemplate->isBridgeLike()) continue; Team *team = ThePlayerList->getNeutralPlayer()->getDefaultTeam(); @@ -1846,15 +1839,9 @@ void GameLogic::startNewGame( Bool loadingSaveGame ) Coord3D pos = *pMapObj->getLocation(); pos.z += TheTerrainLogic->getGroundHeight( pos.x, pos.y ); Real angle = normalizeAngle(pMapObj->getAngle()); + if (thingTemplate->isKindOf(KINDOF_OPTIMIZED_TREE)) { - // Opt trees and props just get drawables to tell the client about it, then deleted. jba [6/5/2003] - // This way there is no logic object to slow down partition manager and core logic stuff. - Drawable *draw = TheThingFactory->newDrawable(thingTemplate); - if (draw) { - draw->setOrientation(angle); - draw->setPosition( &pos ); - TheGameClient->destroyDrawable(draw); - } + createOptimizedTree(thingTemplate, &pos, angle); } } } @@ -1884,11 +1871,8 @@ void GameLogic::startNewGame( Bool loadingSaveGame ) if( thingTemplate == NULL ) continue; - Bool isBridgeLikeObject = false; - if (thingTemplate->isBridge()) isBridgeLikeObject = true; - if (thingTemplate->isKindOf(KINDOF_WALK_ON_TOP_OF_WALL)) isBridgeLikeObject = true; - if (isBridgeLikeObject) - continue; // bridges have to be added earlier. + if (thingTemplate->isBridgeLike()) + continue; // bridges have to be added earlier. // don't create trees and shrubs if this is one and we have that option off if( thingTemplate->isKindOf( KINDOF_SHRUBBERY ) && !useTrees ) @@ -1897,18 +1881,12 @@ void GameLogic::startNewGame( Bool loadingSaveGame ) Coord3D pos = *pMapObj->getLocation(); pos.z += TheTerrainLogic->getGroundHeight( pos.x, pos.y ); Real angle = normalizeAngle(pMapObj->getAngle()); - if (thingTemplate->isKindOf(KINDOF_OPTIMIZED_TREE)) { - // Opt trees and props just get drawables to tell the client about it, then deleted. jba [6/5/2003] - // This way there is no logic object to slow down partition manager and core logic stuff. - Drawable *draw = TheThingFactory->newDrawable(thingTemplate); - if (draw) { - draw->setOrientation(angle); - draw->setPosition( &pos ); - TheGameClient->destroyDrawable(draw); - } + if (thingTemplate->isKindOf(KINDOF_OPTIMIZED_TREE)) { + createOptimizedTree(thingTemplate, &pos, angle); continue; } + #if 1 Bool isProp = thingTemplate->isKindOf(KINDOF_PROP); Bool isFluff = false; @@ -2428,6 +2406,20 @@ void GameLogic::startNewGame( Bool loadingSaveGame ) } +//----------------------------------------------------------------------------------------- +void GameLogic::createOptimizedTree(const ThingTemplate *thingTemplate, Coord3D *pos, Real angle) +{ + // Opt trees and props just get drawables to tell the client about it, then deleted. jba [6/5/2003] + // This way there is no logic object to slow down partition manager and core logic stuff. + // TheSuperHackers @info Destroying the drawable will register the tree in the tree buffer. + Drawable *draw = TheThingFactory->newDrawable(thingTemplate); + if (draw) { + draw->setOrientation(angle); + draw->setPosition(pos); + TheGameClient->destroyDrawable(draw); + } +} + //----------------------------------------------------------------------------------------- static void findAndSelectCommandCenter(Object *obj, void* alreadyFound) { diff --git a/GeneralsMD/Code/GameEngineDevice/Include/W3DDevice/GameClient/Module/W3DTreeDraw.h b/GeneralsMD/Code/GameEngineDevice/Include/W3DDevice/GameClient/Module/W3DTreeDraw.h index 26b6303e42..6e9190d82f 100644 --- a/GeneralsMD/Code/GameEngineDevice/Include/W3DDevice/GameClient/Module/W3DTreeDraw.h +++ b/GeneralsMD/Code/GameEngineDevice/Include/W3DDevice/GameClient/Module/W3DTreeDraw.h @@ -84,16 +84,17 @@ class W3DTreeDraw : public DrawModule W3DTreeDraw( Thing *thing, const ModuleData* moduleData ); // virtual destructor prototype provided by memory pool declaration - virtual void doDrawModule(const Matrix3D* transformMtx); - virtual void setShadowsEnabled(Bool enable) { } - virtual void releaseShadows(void) {}; ///< we don't care about preserving temporary shadows. - virtual void allocateShadows(void) {}; ///< we don't care about preserving temporary shadows. - virtual void setFullyObscuredByShroud(Bool fullyObscured) { } - virtual void reactToTransformChange(const Matrix3D* oldMtx, const Coord3D* oldPos, Real oldAngle); - virtual void reactToGeometryChange() { } + virtual void doDrawModule(const Matrix3D* transformMtx) {} + virtual void setShadowsEnabled(Bool enable) {} + virtual void releaseShadows(void) {} ///< we don't care about preserving temporary shadows. + virtual void allocateShadows(void) {} ///< we don't care about preserving temporary shadows. + virtual void setFullyObscuredByShroud(Bool fullyObscured) {} + virtual void reactToTransformChange(const Matrix3D* oldMtx, const Coord3D* oldPos, Real oldAngle) {} + virtual void reactToGeometryChange() {} protected: - Bool m_treeAdded; + + void addToTreeBuffer(); }; diff --git a/GeneralsMD/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DTreeBuffer.h b/GeneralsMD/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DTreeBuffer.h index 134affac93..3b2b5892de 100644 --- a/GeneralsMD/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DTreeBuffer.h +++ b/GeneralsMD/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DTreeBuffer.h @@ -144,29 +144,31 @@ typedef struct { // // W3DTreeBuffer: Draw buffer for the trees. // +// TheSuperHackers @info This class acts as a bootstrap for adding a new tree +// instance to the tree buffer. It does not do anything useful until it is deleted. // class W3DTreeBuffer : public Snapshot { //friend class BaseHeightMapRenderObjClass; -//----------------------------------------------------------------------------- -// W3DTreeTextureClass -//----------------------------------------------------------------------------- -class W3DTreeTextureClass : public TextureClass -{ - W3DMPO_GLUE(W3DTreeTextureClass) -protected: - virtual void Apply(unsigned int stage); - -public: - /// Create texture. - W3DTreeTextureClass(unsigned width, unsigned height); - - // just use default destructor. ~TerrainTextureClass(void); -public: - int update(W3DTreeBuffer *buffer); ///< Sets the pixels, and returns the actual height of the texture. - void setLOD(Int LOD) const; -}; + //----------------------------------------------------------------------------- + // W3DTreeTextureClass + //----------------------------------------------------------------------------- + class W3DTreeTextureClass : public TextureClass + { + W3DMPO_GLUE(W3DTreeTextureClass) + protected: + virtual void Apply(unsigned int stage); + + public: + /// Create texture. + W3DTreeTextureClass(unsigned width, unsigned height); + + // just use default destructor. ~TerrainTextureClass(void); + public: + int update(W3DTreeBuffer *buffer); ///< Sets the pixels, and returns the actual height of the texture. + void setLOD(Int LOD) const; + }; public: diff --git a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/Drawable/Draw/W3DTreeDraw.cpp b/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/Drawable/Draw/W3DTreeDraw.cpp index 44b4317164..a90cef1d9b 100644 --- a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/Drawable/Draw/W3DTreeDraw.cpp +++ b/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/Drawable/Draw/W3DTreeDraw.cpp @@ -24,7 +24,7 @@ // FILE: W3DTreeDraw.cpp //////////////////////////////////////////////////////////////////////// // Author: Colin Day, December 2001 -// Desc: Tracer drawing +// Desc: Tree draw /////////////////////////////////////////////////////////////////////////////////////////////////// // INCLUDES /////////////////////////////////////////////////////////////////////////////////////// @@ -109,51 +109,31 @@ void W3DTreeDrawModuleData::buildFieldParse(MultiIniFieldParse& p) //------------------------------------------------------------------------------------------------- //------------------------------------------------------------------------------------------------- -W3DTreeDraw::W3DTreeDraw( Thing *thing, const ModuleData* moduleData ) : DrawModule( thing, moduleData ), -m_treeAdded(false) +W3DTreeDraw::W3DTreeDraw( Thing *thing, const ModuleData* moduleData ) : DrawModule( thing, moduleData ) { - } - //------------------------------------------------------------------------------------------------- //------------------------------------------------------------------------------------------------- W3DTreeDraw::~W3DTreeDraw( void ) { + addToTreeBuffer(); } //------------------------------------------------------------------------------------------------- -void W3DTreeDraw::reactToTransformChange( const Matrix3D *oldMtx, - const Coord3D *oldPos, - Real oldAngle ) +void W3DTreeDraw::addToTreeBuffer() { - Drawable *draw = getDrawable(); - if (m_treeAdded) { - return; - } - if (draw->getPosition()->x==0.0f && draw->getPosition()->y == 0.0f) { - return; - } - m_treeAdded = true; const W3DTreeDrawModuleData *moduleData = getW3DTreeDrawModuleData(); - if (!moduleData) { - return; - } + const Drawable *draw = getDrawable(); + + DEBUG_ASSERTCRASH(draw->getPosition()->x == 0.0f && draw->getPosition()->y == 0.0f, + ("W3DTreeDraw::addToTreeBuffer - Why place tree at x:0 y:0 ?")); + Real scale = draw->getScale(); Real scaleRandomness = draw->getTemplate()->getInstanceScaleFuzziness(); scaleRandomness = 0.0f; // We use the scale fuzziness inside WB to generate random scales, so they don't change at load time. jba. [4/22/2003] TheTerrainRenderObject->addTree(draw->getID(), *draw->getPosition(), scale, draw->getOrientation(), scaleRandomness, moduleData); - -} - -//------------------------------------------------------------------------------------------------- -//------------------------------------------------------------------------------------------------- -void W3DTreeDraw::doDrawModule(const Matrix3D* transformMtx) -{ - - return; - } // ------------------------------------------------------------------------------------------------ diff --git a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DTreeBuffer.cpp b/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DTreeBuffer.cpp index e418aaef20..b2c9153b90 100644 --- a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DTreeBuffer.cpp +++ b/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DTreeBuffer.cpp @@ -344,10 +344,7 @@ Int W3DTreeBuffer::getPartitionBucket(const Coord3D &pos) const } //============================================================================= -// W3DTreeBuffer::cull -//============================================================================= -/** Culls the trees, marking the visible flag. If a tree becomes visible, it sets -it's sortKey */ +// W3DTreeBuffer::updateSway //============================================================================= void W3DTreeBuffer::updateSway(const BreezeInfo& info) { @@ -1443,7 +1440,7 @@ void W3DTreeBuffer::addTree(DrawableID id, Coord3D location, Real scale, Real an m_trees[m_numTrees].bounds.Center *= m_trees[m_numTrees].scale; m_trees[m_numTrees].bounds.Radius *= m_trees[m_numTrees].scale; m_trees[m_numTrees].bounds.Center += m_trees[m_numTrees].location; - // Initially set it invisible. cull will update it's visiblity flag. + // Initially set it invisible. cull will update it's visibility flag. m_trees[m_numTrees].visible = false; m_trees[m_numTrees].drawableID = id;