Commit 5c9aac28 authored by Martin Turski's avatar Martin Turski

header files + random fixes; to use the world render test, use the "pgrid"...

header files + random fixes; to use the world render test, use the "pgrid" command in the console; this populates the world grid with entities so they render
parent 23912053
Pipeline #61 skipped
...@@ -46,12 +46,12 @@ template <typename listType> inline bool LIST_EMPTY( listType& link ) ...@@ -46,12 +46,12 @@ template <typename listType> inline bool LIST_EMPTY( listType& link )
#define LIST_FOREACH_BEGIN(type, root, node) for ( NestedListEntry <type> *iter = (root).next, *niter; iter != &(root); iter = niter ) { type *item = LIST_GETITEM(type, iter, node); niter = iter->next; #define LIST_FOREACH_BEGIN(type, root, node) for ( NestedListEntry <type> *iter = (root).next, *niter; iter != &(root); iter = niter ) { type *item = LIST_GETITEM(type, iter, node); niter = iter->next;
#define LIST_FOREACH_END } #define LIST_FOREACH_END }
template < class type > template < class type, int _node_offset = -1 >
struct NestedListEntry struct NestedListEntry
{ {
NestedListEntry <type> *next, *prev; NestedListEntry <type> *next, *prev;
}; };
template < class type > template < class type, int _node_offset = -1 >
struct NestedList struct NestedList
{ {
NestedListEntry <type> root; NestedListEntry <type> root;
......
...@@ -9,6 +9,12 @@ namespace krt ...@@ -9,6 +9,12 @@ namespace krt
{ {
class Game; class Game;
class EntityReference abstract
{
public:
virtual void Unlink( void ) = 0;
};
struct Entity struct Entity
{ {
friend class Game; friend class Game;
...@@ -24,6 +30,8 @@ struct Entity ...@@ -24,6 +30,8 @@ struct Entity
bool CreateRWObject( void ); bool CreateRWObject( void );
void DeleteRWObject( void ); void DeleteRWObject( void );
rw::Object* GetRWObject( void ) { return this->rwObject; }
void SetModelling( const rw::Matrix& mat ); void SetModelling( const rw::Matrix& mat );
const rw::Matrix& GetModelling( void ) const; const rw::Matrix& GetModelling( void ) const;
const rw::Matrix& GetMatrix( void ) const; const rw::Matrix& GetMatrix( void ) const;
...@@ -43,6 +51,11 @@ struct Entity ...@@ -43,6 +51,11 @@ struct Entity
inline Game* GetGame( void ) const { return this->ourGame; } inline Game* GetGame( void ) const { return this->ourGame; }
void AddEntityWorldSectorReference( EntityReference *refPtr );
void RemoveEntityFromWorldSectors( void );
void RemoveEntityWorldReference( EntityReference *refPtr );
private: private:
Game *ourGame; Game *ourGame;
...@@ -58,6 +71,8 @@ private: ...@@ -58,6 +71,8 @@ private:
bool isTunnelTransition; bool isTunnelTransition;
bool isUnimportantToStreamer; bool isUnimportantToStreamer;
bool isStaticWorldEntity;
rw::Matrix matrix; rw::Matrix matrix;
bool hasLocalMatrix; bool hasLocalMatrix;
...@@ -70,6 +85,10 @@ private: ...@@ -70,6 +85,10 @@ private:
NestedListEntry <Entity> worldNode; NestedListEntry <Entity> worldNode;
World *onWorld; World *onWorld;
mutable float cachedBoundSphereRadius; // if we have no model we need to have a way to detect visibility
std::list <EntityReference*> worldSectorReferences;
}; };
} }
\ No newline at end of file
...@@ -13,16 +13,6 @@ namespace krt ...@@ -13,16 +13,6 @@ namespace krt
template <size_t depth, size_t boundDimm, typename DataType> template <size_t depth, size_t boundDimm, typename DataType>
struct QuadTree struct QuadTree
{ {
inline QuadTree( void )
{
}
inline ~QuadTree( void )
{
}
template <typename numberType, size_t minX, size_t minY, size_t maxX, size_t maxY> template <typename numberType, size_t minX, size_t minY, size_t maxX, size_t maxY>
MATH_INLINE static bool IsPointInBounds( numberType x, numberType y ) MATH_INLINE static bool IsPointInBounds( numberType x, numberType y )
{ {
...@@ -32,22 +22,27 @@ struct QuadTree ...@@ -32,22 +22,27 @@ struct QuadTree
template <typename numberType, size_t minX, size_t minY, size_t maxX, size_t maxY> template <typename numberType, size_t minX, size_t minY, size_t maxX, size_t maxY>
MATH_INLINE static bool IsBoundsInBounds( numberType box_minX, numberType box_minY, numberType box_maxX, numberType box_maxY ) MATH_INLINE static bool IsBoundsInBounds( numberType box_minX, numberType box_minY, numberType box_maxX, numberType box_maxY )
{ {
return ( false ); // TODO. typedef sliceOfData <numberType> qt_slice_t;
}
template <size_t depth, size_t boundDimm, typename DataType, size_t xOff, size_t yOff> const qt_slice_t width_slice_sector( minX, maxX - minX );
struct Node const qt_slice_t height_slice_sector( minY, maxY - minY );
{
inline Node( void )
{
} const qt_slice_t width_slice_box( box_minX, box_maxX - box_minX );
const qt_slice_t height_slice_box( box_minY, box_maxY - box_minY );
inline ~Node( void ) qt_slice_t::eIntersectionResult width_intersect_result = width_slice_sector.intersectWith( width_slice_box );
{ qt_slice_t::eIntersectionResult height_intersect_result = height_slice_sector.intersectWith( height_slice_box );
} bool isIntersecting =
qt_slice_t::isFloatingIntersect( width_intersect_result ) == false &&
qt_slice_t::isFloatingIntersect( height_intersect_result ) == false;
return isIntersecting;
}
template <size_t depth, size_t boundDimm, typename DataType, size_t xOff, size_t yOff>
struct Node
{
static size_t constexpr boundDimm = boundDimm; static size_t constexpr boundDimm = boundDimm;
private: private:
...@@ -71,23 +66,41 @@ struct QuadTree ...@@ -71,23 +66,41 @@ struct QuadTree
bottomRight.VisitByPoint( x, y, cb ); bottomRight.VisitByPoint( x, y, cb );
} }
} }
};
template <size_t boundDimm, typename DataType, size_t xOff, size_t yOff> template <typename numberType, typename callbackType>
struct Node <0, boundDimm, DataType, xOff, yOff> MATH_INLINE void VisitByBounds( numberType minX, numberType minY, numberType maxX, numberType maxY, callbackType& cb )
{
inline Node( void )
{ {
// Taking care of our bounds ourselves.
if ( IsBoundsInBounds <numberType, xOff, yOff, xOff + boundDimm, yOff + boundDimm> ( minX, minY, maxX, maxY ) )
{
topLeft.VisitByBounds( minX, minY, maxX, maxY, cb );
topRight.VisitByBounds( minX, minY, maxX, maxY, cb );
bottomLeft.VisitByBounds( minX, minY, maxX, maxY, cb );
bottomRight.VisitByBounds( minX, minY, maxX, maxY, cb );
}
} }
inline ~Node( void ) template <typename callbackType>
MATH_INLINE void ForAllEntries( callbackType& cb )
{ {
topLeft.ForAllEntries( cb );
topRight.ForAllEntries( cb );
bottomLeft.ForAllEntries( cb );
bottomRight.ForAllEntries( cb );
} }
};
template <size_t boundDimm, typename DataType, size_t xOff, size_t yOff>
struct Node <0, boundDimm, DataType, xOff, yOff>
{
static size_t constexpr boundDimm = boundDimm; static size_t constexpr boundDimm = boundDimm;
inline Node( void ) : data( xOff, yOff, xOff + boundDimm, yOff + boundDimm )
{
// We want each data to know about its bounds.
return;
}
private: private:
DataType data; DataType data;
...@@ -102,6 +115,21 @@ struct QuadTree ...@@ -102,6 +115,21 @@ struct QuadTree
cb( this->data ); cb( this->data );
} }
} }
template <typename numberType, typename callbackType>
MATH_INLINE void VisitByBounds( numberType minX, numberType minY, numberType maxX, numberType maxY, callbackType& cb )
{
if ( IsBoundsInBounds <numberType, xOff, yOff, xOff + boundDimm, yOff + boundDimm> ( minX, minY, maxX, maxY ) )
{
cb( this->data );
}
}
template <typename callbackType>
MATH_INLINE void ForAllEntries( callbackType& cb )
{
cb( this->data );
}
}; };
Node <depth, boundDimm, DataType, 0, 0> root; Node <depth, boundDimm, DataType, 0, 0> root;
......
...@@ -3,6 +3,8 @@ ...@@ -3,6 +3,8 @@
// World class for managing all alive Entities. // World class for managing all alive Entities.
#include "Entity.h" #include "Entity.h"
#include "World.SectorGrid.h"
namespace krt namespace krt
{ {
...@@ -13,10 +15,46 @@ struct World ...@@ -13,10 +15,46 @@ struct World
World( void ); World( void );
~World( void ); ~World( void );
void DepopulateEntities( void );
void PutEntitiesOnGrid( void ); void PutEntitiesOnGrid( void );
void RenderWorld( void *gpuDevice );
private: private:
NestedList <Entity> entityList; NestedList <Entity> entityList;
// World sectors for optimized entity rendering.
struct StaticEntitySector
{
inline StaticEntitySector( void )
{
}
void Clear( void )
{
return;
}
void AddEntity( Entity *theEntity )
{
this->entitiesOnSector.push_back( theEntity );
}
void RemoveEntity( Entity *theEntity )
{
auto findIter = std::find( entitiesOnSector.begin(), entitiesOnSector.end(), theEntity );
if ( findIter != entitiesOnSector.end() )
{
entitiesOnSector.erase( findIter );
}
}
std::list <Entity*> entitiesOnSector;
};
SectorGrid <StaticEntitySector, 3000, 3> staticEntityGrid;
}; };
}; };
\ No newline at end of file
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
#define MATH_INLINE __forceinline #define MATH_INLINE __forceinline
//#define USE_MATH_VERIFICATION
namespace krt namespace krt
{ {
namespace math namespace math
...@@ -15,7 +17,16 @@ struct Plane ...@@ -15,7 +17,16 @@ struct Plane
rw::V3d a; rw::V3d a;
rw::V3d b; rw::V3d b;
inline bool intersectWith( const Plane& right ) const; bool intersectWith( const Plane& right ) const;
};
struct TrianglePlane
{
rw::V3d pos;
rw::V3d a;
rw::V3d b;
bool intersectWith( const TrianglePlane& right ) const;
}; };
struct Sphere struct Sphere
...@@ -23,7 +34,7 @@ struct Sphere ...@@ -23,7 +34,7 @@ struct Sphere
rw::V3d point; rw::V3d point;
float radius; float radius;
inline bool intersectLine( const rw::V3d& pos, const rw::V3d& dir, double& first, double& second ) const; bool intersectLine( const rw::V3d& pos, const rw::V3d& dir, double& first, double& second ) const;
}; };
// Don't mind the German names. :) // Don't mind the German names. :)
...@@ -34,13 +45,23 @@ struct Quader ...@@ -34,13 +45,23 @@ struct Quader
rw::V3d trl, rw::V3d trr, rw::V3d tfl, rw::V3d tfr rw::V3d trl, rw::V3d trr, rw::V3d tfl, rw::V3d tfr
); );
inline bool isPointInside( const rw::V3d& point ) const; bool isPointInside( const rw::V3d& point ) const;
inline bool intersectWith( const Quader& right ) const; bool intersectWith( const Quader& right ) const;
inline bool intersectWith( const Sphere& right ) const; bool intersectWith( const Sphere& right ) const;
// Please do not write into those fields directly! // Please do not write into those fields directly!
const rw::V3d brl, brr, bfl, bfr; // bottom plane. rw::V3d brl, brr, bfl, bfr; // bottom plane.
const rw::V3d trl, trr, tfl, tfr; // top plane. rw::V3d trl, trr, tfl, tfr; // top plane.
private:
rw::Matrix inv_localSpace_bottom, inv_localSpace_top;
rw::Matrix leftPlane_inv_planeSpace_bottom, leftPlane_inv_planeSpace_top;
rw::Matrix rightPlane_inv_planeSpace_bottom, rightPlane_inv_planeSpace_top;
rw::Matrix topPlane_inv_planeSpace_bottom, topPlane_inv_planeSpace_top;
rw::Matrix bottomPlane_inv_planeSpace_bottom, bottomPlane_inv_planeSpace_top;
rw::Matrix frontPlane_inv_planeSpace_bottom, frontPlane_inv_planeSpace_top;
rw::Matrix rearPlane_inv_planeSpace_bottom, rearPlane_inv_planeSpace_top;
}; };
// A function to test our math. // A function to test our math.
......
...@@ -32,6 +32,8 @@ Entity::Entity( Game *ourGame ) ...@@ -32,6 +32,8 @@ Entity::Entity( Game *ourGame )
this->rwObject = NULL; this->rwObject = NULL;
this->onWorld = NULL; // we are not part of a world. this->onWorld = NULL; // we are not part of a world.
this->cachedBoundSphereRadius = 300.0f; // TODO: cache the real bounding sphere radius in some file so we dont need the model
} }
Entity::~Entity( void ) Entity::~Entity( void )
...@@ -39,6 +41,11 @@ Entity::~Entity( void ) ...@@ -39,6 +41,11 @@ Entity::~Entity( void )
// Make sure we released our RW object. // Make sure we released our RW object.
this->DeleteRWObject(); this->DeleteRWObject();
// Make sure we are not references anywhere anymore.
{
this->RemoveEntityFromWorldSectors();
}
// Remove us from any world. // Remove us from any world.
this->LinkToWorld( NULL ); this->LinkToWorld( NULL );
...@@ -206,7 +213,7 @@ void Entity::SetModelling( const rw::Matrix& mat ) ...@@ -206,7 +213,7 @@ void Entity::SetModelling( const rw::Matrix& mat )
{ {
this->matrix = mat; this->matrix = mat;
this->hasLocalMatrix = false; this->hasLocalMatrix = true;
} }
else else
{ {
...@@ -299,8 +306,18 @@ bool Entity::GetWorldBoundingSphere( rw::Sphere& sphereOut ) const ...@@ -299,8 +306,18 @@ bool Entity::GetWorldBoundingSphere( rw::Sphere& sphereOut ) const
{ {
rw::Object *rwObj = this->rwObject; rw::Object *rwObj = this->rwObject;
if ( !rwObj == NULL ) if ( rwObj == NULL )
return false; {
// Even if we have no model we need a bounding sphere.
const rw::Matrix& curMatrix = this->GetMatrix();
sphereOut.center = curMatrix.pos;
sphereOut.radius = this->cachedBoundSphereRadius;
return true;
}
bool hasSphere = false;
if ( rwObj->type == rw::Atomic::ID ) if ( rwObj->type == rw::Atomic::ID )
{ {
...@@ -311,17 +328,24 @@ bool Entity::GetWorldBoundingSphere( rw::Sphere& sphereOut ) const ...@@ -311,17 +328,24 @@ bool Entity::GetWorldBoundingSphere( rw::Sphere& sphereOut ) const
if ( atomicSphere ) if ( atomicSphere )
{ {
sphereOut = *atomicSphere; sphereOut = *atomicSphere;
return true;
hasSphere = true;
} }
} }
else if ( rwObj->type == rw::Clump::ID ) else if ( rwObj->type == rw::Clump::ID )
{ {
rw::Clump *clump = (rw::Clump*)rwObj; rw::Clump *clump = (rw::Clump*)rwObj;
return RpClumpCalculateBoundingSphere( clump, sphereOut ); hasSphere = RpClumpCalculateBoundingSphere( clump, sphereOut );
} }
return false; if ( hasSphere )
{
// Store the last calculated bounding sphere radius for later.
this->cachedBoundSphereRadius = sphereOut.radius;
}
return hasSphere;
} }
void Entity::LinkToWorld( World *theWorld ) void Entity::LinkToWorld( World *theWorld )
...@@ -408,4 +432,29 @@ ModelManager::ModelResource* Entity::GetModelInfo( void ) const ...@@ -408,4 +432,29 @@ ModelManager::ModelResource* Entity::GetModelInfo( void ) const
return theGame->GetModelManager().GetModelByID( this->modelID ); return theGame->GetModelManager().GetModelByID( this->modelID );
} }
void Entity::AddEntityWorldSectorReference( EntityReference *refPtr )
{
this->worldSectorReferences.push_back( refPtr );
}
void Entity::RemoveEntityFromWorldSectors( void )
{
while ( this->worldSectorReferences.empty() == false )
{
EntityReference *refPtr = this->worldSectorReferences.front();
refPtr->Unlink();
}
}
void Entity::RemoveEntityWorldReference( EntityReference *refPtr )
{
auto find_iter = std::find( this->worldSectorReferences.begin(), this->worldSectorReferences.end(), refPtr );
if ( find_iter == this->worldSectorReferences.end() )
return;
this->worldSectorReferences.erase( find_iter );
}
} }
\ No newline at end of file
...@@ -166,7 +166,8 @@ void Game::Run() ...@@ -166,7 +166,8 @@ void Game::Run()
// rendering test // rendering test
if (this->universes.size() > 0) if (this->universes.size() > 0)
{ {
RenderingTest(gfxContext); //RenderingTest(gfxContext);
theGame->GetWorld()->RenderWorld( gfxContext );
} }
// whatever else might come to mind // whatever else might come to mind
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment