mirror of
https://github.com/tribes2/engine.git
synced 2026-01-19 19:24:45 +00:00
503 lines
15 KiB
C++
503 lines
15 KiB
C++
//-----------------------------------------------------------------------------
|
|
// V12 Engine
|
|
//
|
|
// Copyright (c) 2001 GarageGames.Com
|
|
// Portions Copyright (c) 2001 by Sierra Online, Inc.
|
|
//-----------------------------------------------------------------------------
|
|
|
|
#ifndef _SCENEOBJECT_H_
|
|
#define _SCENEOBJECT_H_
|
|
|
|
#ifndef _PLATFORM_H_
|
|
#include "platform/platform.h"
|
|
#endif
|
|
#ifndef _NETOBJECT_H_
|
|
#include "sim/netObject.h"
|
|
#endif
|
|
#ifndef _COLLISION_H_
|
|
#include "collision/collision.h"
|
|
#endif
|
|
#ifndef _POLYHEDRON_H_
|
|
#include "collision/polyhedron.h"
|
|
#endif
|
|
#ifndef _ABSTRACTPOLYLIST_H_
|
|
#include "collision/abstractPolyList.h"
|
|
#endif
|
|
#ifndef _OBJECTTYPES_H_
|
|
#include "game/objectTypes.h"
|
|
#endif
|
|
#ifndef _COLOR_H_
|
|
#include "core/color.h"
|
|
#endif
|
|
#ifndef _LIGHTMANAGER_H_
|
|
#include "scenegraph/lightManager.h"
|
|
#endif
|
|
|
|
//-------------------------------------- Forward declarations...
|
|
class SceneObject;
|
|
class SceneGraph;
|
|
class SceneState;
|
|
class SceneRenderImage;
|
|
class Box3F;
|
|
class Point3F;
|
|
class LightManager;
|
|
class Convex;
|
|
|
|
//----------------------------------------------------------------------------
|
|
struct RayInfo: public Collision {
|
|
// The collision struct has object, point, normal & material.
|
|
F32 t;
|
|
};
|
|
|
|
//--------------------------------------------------------------------------
|
|
// There are two indiscretions here. First is the name, which refers rather
|
|
// blatantly to the container bin system. A hygine issue. Next is the
|
|
// user defined U32, which is added solely for the zoning system. This should
|
|
// properly be split up into two structures, for the disparate purposes, especially
|
|
// since it's not nice to force the container bin to use 20 bytes structures when
|
|
// it could get away with a 16 byte version.
|
|
class SceneObjectRef
|
|
{
|
|
public:
|
|
SceneObject* object;
|
|
SceneObjectRef* nextInBin;
|
|
SceneObjectRef* prevInBin;
|
|
SceneObjectRef* nextInObj;
|
|
|
|
U32 zone;
|
|
};
|
|
|
|
// A scope frustum describes a pyramid to clip new portals against. It is
|
|
// rooted at the root position of the scoping query, which is not stored
|
|
// here.
|
|
class ScopeFrustum
|
|
{
|
|
public:
|
|
enum Constants {
|
|
TopLeft = 0,
|
|
TopRight = 1,
|
|
BottomLeft = 2,
|
|
BottomRight = 3
|
|
};
|
|
|
|
Point3F frustumPoints[4];
|
|
};
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
class Container
|
|
{
|
|
public:
|
|
struct Link
|
|
{
|
|
Link* next;
|
|
Link* prev;
|
|
Link();
|
|
void unlink();
|
|
void linkAfter(Link* ptr);
|
|
};
|
|
|
|
struct CallbackInfo {
|
|
AbstractPolyList* polyList;
|
|
Box3F boundingBox;
|
|
SphereF boundingSphere;
|
|
S32 key;
|
|
};
|
|
|
|
static const U32 csmNumBins;
|
|
static const F32 csmBinSize;
|
|
static const F32 csmTotalBinSize;
|
|
static const U32 csmRefPoolBlockSize;
|
|
static U32 smCurrSeqKey;
|
|
|
|
private:
|
|
Link mStart,mEnd;
|
|
|
|
SceneObjectRef* mFreeRefPool;
|
|
Vector<SceneObjectRef*> mRefPoolBlocks;
|
|
|
|
SceneObjectRef* mBinArray;
|
|
SceneObjectRef mOverflowBin;
|
|
|
|
public:
|
|
Container();
|
|
~Container();
|
|
|
|
// Basic database operations
|
|
typedef void (*FindCallback)(SceneObject*,S32 key);
|
|
void findObjects(U32 mask, FindCallback, S32 key = 0);
|
|
void findObjects(const Box3F& box, U32 mask, FindCallback, S32 key = 0);
|
|
void polyhedronFindObjects(const Polyhedron& polyhedron, U32 mask,
|
|
FindCallback, S32 key = 0);
|
|
|
|
// Line intersection
|
|
bool castRay(const Point3F &start, const Point3F &end, U32 mask, RayInfo* info);
|
|
bool collideBox(const Point3F &start, const Point3F &end, U32 mask, RayInfo* info);
|
|
|
|
// Poly list
|
|
bool buildPolyList(const Box3F& box, U32 mask, AbstractPolyList*,FindCallback=0,S32 key = 0);
|
|
bool buildCollisionList(const Box3F& box, const Point3F& start, const Point3F& end, const VectorF& velocity,
|
|
U32 mask,CollisionList* collisionList,FindCallback = 0,S32 key = 0,const Box3F *queryExpansion = 0);
|
|
bool buildCollisionList(const Polyhedron& polyhedron,
|
|
const Point3F& start, const Point3F& end,
|
|
const VectorF& velocity,
|
|
U32 mask, CollisionList* collisionList,
|
|
FindCallback callback = 0, S32 key = 0);
|
|
|
|
//
|
|
bool addObject(SceneObject*);
|
|
bool removeObject(SceneObject*);
|
|
|
|
void addRefPoolBlock();
|
|
SceneObjectRef* allocateObjectRef();
|
|
void freeObjectRef(SceneObjectRef*);
|
|
void insertIntoBins(SceneObject*);
|
|
void removeFromBins(SceneObject*);
|
|
|
|
// Checkbins makes sure that we're not just sticking the object right back
|
|
// where it came from. The overloaded insertInto is so we don't calculate
|
|
// the ranges twice.
|
|
void checkBins(SceneObject*);
|
|
void insertIntoBins(SceneObject*, U32, U32, U32, U32);
|
|
|
|
// Object searches to support console querying of the database. ONLY WORKS ON SERVER
|
|
private:
|
|
Vector<SimObjectPtr<SceneObject>*> mSearchList;
|
|
S32 mCurrSearchPos;
|
|
Point3F mSearchReferencePoint;
|
|
void cleanupSearchVectors();
|
|
|
|
public:
|
|
void initRadiusSearch(const Point3F& searchPoint,
|
|
const F32 searchRadius,
|
|
const U32 searchMask);
|
|
U32 containerSearchNext();
|
|
F32 containerSearchCurrDist();
|
|
F32 containerSearchCurrRadDamageDist();
|
|
};
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
// For simple queries. Simply creates a vector of the objects
|
|
//
|
|
class SimpleQueryList
|
|
{
|
|
public:
|
|
Vector<SceneObject*> mList;
|
|
|
|
public:
|
|
SimpleQueryList() {
|
|
VECTOR_SET_ASSOCIATION(mList);
|
|
}
|
|
|
|
void insertObject(SceneObject* obj) { mList.push_back(obj); }
|
|
static void insertionCallback(SceneObject* obj, S32 key);
|
|
};
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
class SceneObject : public NetObject, public Container::Link
|
|
{
|
|
typedef NetObject Parent;
|
|
friend class Container;
|
|
friend class SceneGraph;
|
|
friend class SceneState;
|
|
|
|
//-------------------------------------- Public constants
|
|
public:
|
|
enum {
|
|
MaxObjectZones = 128
|
|
};
|
|
enum TraverseColor {
|
|
White = 0,
|
|
Grey = 1,
|
|
Black = 2
|
|
};
|
|
|
|
//-------------------------------------- Public interfaces
|
|
// C'tors and D'tors
|
|
private:
|
|
SceneObject(const SceneObject&); // disallowed
|
|
public:
|
|
SceneObject();
|
|
virtual ~SceneObject();
|
|
|
|
// Scripting interface
|
|
const char* scriptThis();
|
|
|
|
// Collision and transform related interface
|
|
public:
|
|
virtual void disableCollision();
|
|
virtual void enableCollision();
|
|
bool isCollisionEnabled() const { return mCollisionCount == 0; }
|
|
|
|
virtual bool isDisplacable() const;
|
|
virtual Point3F getMomentum() const;
|
|
virtual void setMomentum(const Point3F&);
|
|
virtual F32 getMass() const;
|
|
virtual bool displaceObject(const Point3F& displaceVector);
|
|
|
|
const MatrixF& getTransform() const { return mObjToWorld; }
|
|
const MatrixF& getWorldTransform() const { return mWorldToObj; }
|
|
const VectorF& getScale() const { return mObjScale; }
|
|
|
|
const Box3F& getObjBox() const { return mObjBox; }
|
|
const Box3F& getWorldBox() const { return mWorldBox; }
|
|
const SphereF& getWorldSphere() const { return mWorldSphere; }
|
|
Point3F getBoxCenter() const { return (mWorldBox.min + mWorldBox.max) * 0.5f; }
|
|
|
|
virtual void setTransform(const MatrixF&);
|
|
virtual void setScale(const VectorF & scale);
|
|
|
|
virtual void setRenderTransform(const MatrixF&);
|
|
const MatrixF& getRenderTransform() const { return mRenderObjToWorld; }
|
|
const MatrixF& getRenderWorldTransform() const { return mRenderWorldToObj; }
|
|
const Box3F& getRenderWorldBox() const { return mRenderWorldBox; }
|
|
|
|
virtual void buildConvex(const Box3F& box,Convex* convex);
|
|
virtual bool buildPolyList(AbstractPolyList* polyList, const Box3F &box, const SphereF &sphere);
|
|
virtual BSPNode* buildCollisionBSP(BSPTree *tree, const Box3F &box, const SphereF &sphere);
|
|
|
|
virtual bool castRay(const Point3F &start, const Point3F &end, RayInfo* info);
|
|
virtual bool collideBox(const Point3F &start, const Point3F &end, RayInfo* info);
|
|
|
|
Point3F getPosition() const;
|
|
Point3F getRenderPosition() const;
|
|
void setPosition(const Point3F &pos);
|
|
|
|
// Rendering and zone interface
|
|
public:
|
|
bool isManagingZones() const;
|
|
U32 getZoneRangeStart() const { return mZoneRangeStart; }
|
|
U32 getNumCurrZones() const { return mNumCurrZones; }
|
|
U32 getCurrZone(const U32 index) const;
|
|
|
|
virtual bool getOverlappingZones(SceneObject* obj, U32* zones, U32* numZones);
|
|
virtual U32 getPointZone(const Point3F& p);
|
|
|
|
virtual void renderObject(SceneState*, SceneRenderImage*);
|
|
virtual bool prepRenderImage(SceneState*, const U32 stateKey, const U32 startZone,
|
|
const bool modifyBaseZoneState = false);
|
|
virtual bool scopeObject(const Point3F& rootPosition,
|
|
const F32 rootDistance,
|
|
bool* zoneScopeState);
|
|
|
|
void addToScene();
|
|
void removeFromScene();
|
|
|
|
//-------------------------------------- Derived class interface
|
|
// Overrides
|
|
protected:
|
|
bool onAdd();
|
|
void onRemove();
|
|
void inspectPostApply();
|
|
|
|
// Overrideables
|
|
protected:
|
|
virtual bool onSceneAdd(SceneGraph*);
|
|
virtual void onSceneRemove();
|
|
|
|
// Portal functions.
|
|
virtual void transformModelview(const U32 portalIndex, const MatrixF& oldMV, MatrixF* newMV);
|
|
virtual void transformPosition(const U32 portalIndex, Point3F& point);
|
|
virtual bool computeNewFrustum(const U32 portalIndex,
|
|
const F64* oldFrustum,
|
|
const F64 nearPlane,
|
|
const F64 farPlane,
|
|
const RectI& oldViewport,
|
|
F64* newFrustum,
|
|
RectI& newViewport,
|
|
const bool flippedMatrix);
|
|
virtual void openPortal(const U32 portalIndex,
|
|
SceneState* pCurrState,
|
|
SceneState* pParentState);
|
|
virtual void closePortal(const U32 portalIndex,
|
|
SceneState* pCurrState,
|
|
SceneState* pParentState);
|
|
public:
|
|
virtual void getWSPortalPlane(const U32 portalIndex, PlaneF*);
|
|
|
|
protected:
|
|
void setLastState(SceneState*, U32);
|
|
bool isLastState(SceneState*, U32) const;
|
|
void setTraverseColor(TraverseColor);
|
|
TraverseColor getTraverseColor() const;
|
|
|
|
// lighting info:
|
|
struct LightingInfo
|
|
{
|
|
LightingInfo();
|
|
|
|
bool mUseInfo;
|
|
bool mDirty;
|
|
ColorF mDefaultColor;
|
|
ColorF mAlarmColor;
|
|
|
|
SimObjectPtr<SceneObject> mInterior;
|
|
|
|
bool mHasLastColor;
|
|
ColorF mLastColor;
|
|
U32 mLastTime;
|
|
|
|
static LightInfo smAmbientLight;
|
|
|
|
enum {
|
|
Interior = 0,
|
|
Terrain,
|
|
};
|
|
U32 mLightSource;
|
|
};
|
|
|
|
virtual void installLights();
|
|
virtual void uninstallLights();
|
|
virtual bool getLightingAmbientColor(ColorF * col);
|
|
LightingInfo mLightingInfo;
|
|
|
|
// Transform and Collision related members
|
|
protected:
|
|
Container* mContainer;
|
|
|
|
MatrixF mObjToWorld; // object transform
|
|
MatrixF mWorldToObj; // inverse transform
|
|
Point3F mObjScale; // object scale
|
|
|
|
Box3F mObjBox;
|
|
Box3F mWorldBox;
|
|
SphereF mWorldSphere;
|
|
|
|
MatrixF mRenderObjToWorld;
|
|
MatrixF mRenderWorldToObj;
|
|
Box3F mRenderWorldBox;
|
|
SphereF mRenderWorldSphere;
|
|
|
|
void resetWorldBox();
|
|
void resetRenderWorldBox();
|
|
|
|
SceneObjectRef* mZoneRefHead;
|
|
SceneObjectRef* mBinRefHead;
|
|
|
|
U32 mBinMinX;
|
|
U32 mBinMaxX;
|
|
U32 mBinMinY;
|
|
U32 mBinMaxY;
|
|
|
|
U32 mContainerSeqKey;
|
|
U32 getContainerSeqKey() const { return mContainerSeqKey; }
|
|
void setContainerSeqKey(const U32 key) { mContainerSeqKey = key; }
|
|
|
|
public:
|
|
Container* getContainer() { return mContainer; }
|
|
|
|
protected:
|
|
S32 mCollisionCount;
|
|
|
|
public:
|
|
U32 getTypeMask() { return(mTypeMask); }
|
|
|
|
// Rendering related members
|
|
protected:
|
|
SceneGraph* mSceneManager;
|
|
U32 mZoneRangeStart; // 0xFFFFFFFF == no zones
|
|
|
|
// U32 mCurrZones[MaxObjectZones];
|
|
// SceneObject* mCurrZoneOwners[MaxObjectZones];
|
|
U32 mNumCurrZones;
|
|
|
|
private:
|
|
TraverseColor mTraverseColor;
|
|
SceneState* mLastState;
|
|
U32 mLastStateKey;
|
|
|
|
|
|
// Persist and console
|
|
public:
|
|
static void initPersistFields();
|
|
static void consoleInit();
|
|
|
|
DECLARE_CONOBJECT(SceneObject);
|
|
};
|
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
extern Container gServerContainer;
|
|
extern Container gClientContainer;
|
|
|
|
//--------------------------------------------------------------------------
|
|
//-------------------------------------- Inlines
|
|
//
|
|
inline bool SceneObject::isManagingZones() const
|
|
{
|
|
return mZoneRangeStart != 0xFFFFFFFF;
|
|
}
|
|
|
|
inline void SceneObject::setLastState(SceneState* state, U32 key)
|
|
{
|
|
mLastState = state;
|
|
mLastStateKey = key;
|
|
}
|
|
|
|
inline bool SceneObject::isLastState(SceneState* state, U32 key) const
|
|
{
|
|
return (mLastState == state && mLastStateKey == key);
|
|
}
|
|
|
|
inline void SceneObject::setTraverseColor(TraverseColor c)
|
|
{
|
|
mTraverseColor = c;
|
|
}
|
|
|
|
inline SceneObject::TraverseColor SceneObject::getTraverseColor() const
|
|
{
|
|
return mTraverseColor;
|
|
}
|
|
|
|
inline U32 SceneObject::getCurrZone(const U32 index) const
|
|
{
|
|
// Not the most efficient way to do this, walking the list,
|
|
// but it's an uncommon call...
|
|
SceneObjectRef* walk = mZoneRefHead;
|
|
for (U32 i = 0; i < index; i++) {
|
|
walk = walk->nextInObj;
|
|
AssertFatal(walk, "Error, too few object refs!");
|
|
}
|
|
AssertFatal(walk, "Error, too few object refs!");
|
|
|
|
return walk->zone;
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
inline SceneObjectRef* Container::allocateObjectRef()
|
|
{
|
|
if (mFreeRefPool == NULL) {
|
|
addRefPoolBlock();
|
|
}
|
|
AssertFatal(mFreeRefPool, "Error, should always have a free reference here!");
|
|
|
|
SceneObjectRef* ret = mFreeRefPool;
|
|
mFreeRefPool = mFreeRefPool->nextInObj;
|
|
|
|
ret->nextInObj = NULL;
|
|
return ret;
|
|
}
|
|
|
|
inline void Container::freeObjectRef(SceneObjectRef* trash)
|
|
{
|
|
trash->nextInBin = NULL;
|
|
trash->prevInBin = NULL;
|
|
trash->nextInObj = mFreeRefPool;
|
|
mFreeRefPool = trash;
|
|
}
|
|
|
|
inline void Container::findObjects(U32 mask, FindCallback callback, S32 key)
|
|
{
|
|
for (Link* itr = mStart.next; itr != &mEnd; itr = itr->next) {
|
|
SceneObject* ptr = static_cast<SceneObject*>(itr);
|
|
if ((ptr->getType() & mask) != 0 && !ptr->mCollisionCount)
|
|
(*callback)(ptr,key);
|
|
}
|
|
}
|
|
|
|
#endif // _H_SCENEOBJECT_
|
|
|