Commit 5c9aac28 by 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 )
#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 }
template < class type >
template < class type, int _node_offset = -1 >
struct NestedListEntry
{
NestedListEntry <type> *next, *prev;
};
template < class type >
template < class type, int _node_offset = -1 >
struct NestedList
{
NestedListEntry <type> root;
......
......@@ -9,6 +9,12 @@ namespace krt
{
class Game;
class EntityReference abstract
{
public:
virtual void Unlink( void ) = 0;
};
struct Entity
{
friend class Game;
......@@ -24,6 +30,8 @@ struct Entity
bool CreateRWObject( void );
void DeleteRWObject( void );
rw::Object* GetRWObject( void ) { return this->rwObject; }
void SetModelling( const rw::Matrix& mat );
const rw::Matrix& GetModelling( void ) const;
const rw::Matrix& GetMatrix( void ) const;
......@@ -43,6 +51,11 @@ struct Entity
inline Game* GetGame( void ) const { return this->ourGame; }
void AddEntityWorldSectorReference( EntityReference *refPtr );
void RemoveEntityFromWorldSectors( void );
void RemoveEntityWorldReference( EntityReference *refPtr );
private:
Game *ourGame;
......@@ -58,6 +71,8 @@ private:
bool isTunnelTransition;
bool isUnimportantToStreamer;
bool isStaticWorldEntity;
rw::Matrix matrix;
bool hasLocalMatrix;
......@@ -70,6 +85,10 @@ private:
NestedListEntry <Entity> worldNode;
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
template <size_t depth, size_t boundDimm, typename DataType>
struct QuadTree
{
inline QuadTree( void )
{
}
inline ~QuadTree( void )
{
}
template <typename numberType, size_t minX, size_t minY, size_t maxX, size_t maxY>
MATH_INLINE static bool IsPointInBounds( numberType x, numberType y )
{
......@@ -32,22 +22,27 @@ struct QuadTree
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 )
{
return ( false ); // TODO.
}
typedef sliceOfData <numberType> qt_slice_t;
template <size_t depth, size_t boundDimm, typename DataType, size_t xOff, size_t yOff>
struct Node
{
inline Node( void )
{
const qt_slice_t width_slice_sector( minX, maxX - minX );
const qt_slice_t height_slice_sector( minY, maxY - minY );
}
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;
private:
......@@ -71,23 +66,41 @@ struct QuadTree
bottomRight.VisitByPoint( x, y, cb );
}
}
};
template <size_t boundDimm, typename DataType, size_t xOff, size_t yOff>
struct Node <0, boundDimm, DataType, xOff, yOff>
{
inline Node( void )
template <typename numberType, typename callbackType>
MATH_INLINE void VisitByBounds( numberType minX, numberType minY, numberType maxX, numberType maxY, callbackType& cb )
{
// 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;
inline Node( void ) : data( xOff, yOff, xOff + boundDimm, yOff + boundDimm )
{
// We want each data to know about its bounds.
return;
}
private:
DataType data;
......@@ -102,6 +115,21 @@ struct QuadTree
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;
......
......@@ -3,6 +3,8 @@
// World class for managing all alive Entities.
#include "Entity.h"
#include "World.SectorGrid.h"
namespace krt
{
......@@ -13,10 +15,46 @@ struct World
World( void );
~World( void );
void DepopulateEntities( void );
void PutEntitiesOnGrid( void );
void RenderWorld( void *gpuDevice );
private:
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 @@
#define MATH_INLINE __forceinline
//#define USE_MATH_VERIFICATION
namespace krt
{
namespace math
......@@ -15,7 +17,16 @@ struct Plane
rw::V3d a;
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
......@@ -23,7 +34,7 @@ struct Sphere
rw::V3d point;
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. :)
......@@ -34,13 +45,23 @@ struct Quader
rw::V3d trl, rw::V3d trr, rw::V3d tfl, rw::V3d tfr
);
inline bool isPointInside( const rw::V3d& point ) const;
inline bool intersectWith( const Quader& right ) const;
inline bool intersectWith( const Sphere& right ) const;
bool isPointInside( const rw::V3d& point ) const;
bool intersectWith( const Quader& right ) const;
bool intersectWith( const Sphere& right ) const;
// Please do not write into those fields directly!
const rw::V3d brl, brr, bfl, bfr; // bottom plane.
const rw::V3d trl, trr, tfl, tfr; // top plane.
rw::V3d brl, brr, bfl, bfr; // bottom 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.
......
......@@ -32,6 +32,8 @@ Entity::Entity( Game *ourGame )
this->rwObject = NULL;
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 )
......@@ -39,6 +41,11 @@ Entity::~Entity( void )
// Make sure we released our RW object.
this->DeleteRWObject();
// Make sure we are not references anywhere anymore.
{
this->RemoveEntityFromWorldSectors();
}
// Remove us from any world.
this->LinkToWorld( NULL );
......@@ -206,7 +213,7 @@ void Entity::SetModelling( const rw::Matrix& mat )
{
this->matrix = mat;
this->hasLocalMatrix = false;
this->hasLocalMatrix = true;
}
else
{
......@@ -299,8 +306,18 @@ bool Entity::GetWorldBoundingSphere( rw::Sphere& sphereOut ) const
{
rw::Object *rwObj = this->rwObject;
if ( !rwObj == NULL )
return false;
if ( rwObj == NULL )
{
// 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 )
{
......@@ -311,17 +328,24 @@ bool Entity::GetWorldBoundingSphere( rw::Sphere& sphereOut ) const
if ( atomicSphere )
{
sphereOut = *atomicSphere;
return true;
hasSphere = true;
}
}
else if ( rwObj->type == rw::Clump::ID )
{
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 )
......@@ -408,4 +432,29 @@ ModelManager::ModelResource* Entity::GetModelInfo( void ) const
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()
// rendering test
if (this->universes.size() > 0)
{
RenderingTest(gfxContext);
//RenderingTest(gfxContext);
theGame->GetWorld()->RenderWorld( gfxContext );
}
// 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