Initial commit
This commit is contained in:
867
Torque/SDK/engine/sim/sceneObject.h
Normal file
867
Torque/SDK/engine/sim/sceneObject.h
Normal file
@@ -0,0 +1,867 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, 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;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
/// Extension of the collision structore to allow use with raycasting.
|
||||
///
|
||||
/// @see Collision
|
||||
struct RayInfo: public Collision
|
||||
{
|
||||
// The collision struct has object, point, normal & material.
|
||||
F32 t;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/// Reference to a scene object.
|
||||
///
|
||||
/// @note There are two indiscretions here. First is the name, which refers rather
|
||||
/// blatantly to the container bin system. A hygiene 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;
|
||||
void *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();
|
||||
|
||||
/// @name Basic database operations
|
||||
/// @{
|
||||
|
||||
///
|
||||
typedef void (*FindCallback)(SceneObject*,void *key);
|
||||
void findObjects(U32 mask, FindCallback, void *key = NULL);
|
||||
void findObjects(const Box3F& box, U32 mask, FindCallback, void *key = NULL);
|
||||
void polyhedronFindObjects(const Polyhedron& polyhedron, U32 mask,
|
||||
FindCallback, void *key = NULL);
|
||||
/// @}
|
||||
|
||||
/// @name 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);
|
||||
/// @}
|
||||
|
||||
/// @name Poly list
|
||||
/// @{
|
||||
|
||||
///
|
||||
bool buildPolyList(const Box3F& box, U32 mask, AbstractPolyList*,FindCallback=0,void *key = NULL);
|
||||
bool buildCollisionList(const Box3F& box, const Point3F& start, const Point3F& end, const VectorF& velocity,
|
||||
U32 mask,CollisionList* collisionList,FindCallback = 0,void *key = NULL,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, void *key = NULL);
|
||||
/// @}
|
||||
|
||||
///
|
||||
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);
|
||||
|
||||
|
||||
private:
|
||||
Vector<SimObjectPtr<SceneObject>*> mSearchList;///< Object searches to support console querying of the database. ONLY WORKS ON SERVER
|
||||
S32 mCurrSearchPos;
|
||||
Point3F mSearchReferencePoint;
|
||||
void cleanupSearchVectors();
|
||||
|
||||
public:
|
||||
void initRadiusSearch(const Point3F& searchPoint,
|
||||
const F32 searchRadius,
|
||||
const U32 searchMask);
|
||||
U32 containerSearchNext();
|
||||
F32 containerSearchCurrDist();
|
||||
F32 containerSearchCurrRadiusDist();
|
||||
};
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
/// 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, void *key);
|
||||
};
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
/// A 3D object.
|
||||
///
|
||||
/// @section SceneObject_intro Introduction
|
||||
///
|
||||
/// SceneObject exists as a foundation for 3D objects in Torque. It provides the
|
||||
/// basic functionality for:
|
||||
/// - A scene graph (in the Zones and Portals sections), allowing efficient
|
||||
/// and robust rendering of the game scene.
|
||||
/// - Various helper functions, including functions to get bounding information
|
||||
/// and momentum/velocity.
|
||||
/// - Collision detection, as well as ray casting.
|
||||
/// - Lighting. SceneObjects can register lights both at lightmap generation time,
|
||||
/// and dynamic lights at runtime (for special effects, such as from flame or
|
||||
/// a projectile, or from an explosion).
|
||||
/// - Manipulating scene objects, for instance varying scale.
|
||||
///
|
||||
/// @section SceneObject_example An Example
|
||||
///
|
||||
/// Melv May has written a most marvelous example object deriving from SceneObject.
|
||||
/// Unfortunately this page is too small to contain it.
|
||||
///
|
||||
/// @see http://www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=3217
|
||||
/// for a copy of Melv's example.
|
||||
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 TraversalState
|
||||
{
|
||||
Pending = 0,
|
||||
Working = 1,
|
||||
Done = 2
|
||||
};
|
||||
|
||||
enum SceneObjectMasks
|
||||
{
|
||||
ScaleMask = BIT(0),
|
||||
NextFreeMask = BIT(1)
|
||||
};
|
||||
|
||||
//-------------------------------------- Public interfaces
|
||||
// C'tors and D'tors
|
||||
private:
|
||||
SceneObject(const SceneObject&); ///< @deprecated disallowed
|
||||
|
||||
public:
|
||||
SceneObject();
|
||||
virtual ~SceneObject();
|
||||
|
||||
/// Returns a value representing this object which can be passed to script functions.
|
||||
const char* scriptThis();
|
||||
|
||||
public:
|
||||
/// @name Collision and transform related interface
|
||||
///
|
||||
/// The Render Transform is the interpolated transform with respect to the
|
||||
/// frame rate. The Render Transform will differ from the object transform
|
||||
/// because the simulation is updated in fixed intervals, which controls the
|
||||
/// object transform. The framerate is, most likely, higher than this rate,
|
||||
/// so that is why the render transform is interpolated and will differ slightly
|
||||
/// from the object transform.
|
||||
///
|
||||
/// @{
|
||||
|
||||
/// Disables collisions for this object including raycasts
|
||||
virtual void disableCollision();
|
||||
|
||||
/// Enables collisions for this object
|
||||
virtual void enableCollision();
|
||||
|
||||
/// Returns true if collisions are enabled
|
||||
bool isCollisionEnabled() const { return mCollisionCount == 0; }
|
||||
|
||||
/// Returns true if this object allows itself to be displaced
|
||||
/// @see displaceObject
|
||||
virtual bool isDisplacable() const;
|
||||
|
||||
/// Returns the momentum of this object
|
||||
virtual Point3F getMomentum() const;
|
||||
|
||||
/// Sets the momentum of this object
|
||||
/// @param momentum Momentum
|
||||
virtual void setMomentum(const Point3F &momentum);
|
||||
|
||||
/// Returns the mass of this object
|
||||
virtual F32 getMass() const;
|
||||
|
||||
/// Displaces this object by a vector
|
||||
/// @param displaceVector Displacement vector
|
||||
virtual bool displaceObject(const Point3F& displaceVector);
|
||||
|
||||
/// Returns the transform which can be used to convert object space
|
||||
/// to world space
|
||||
const MatrixF& getTransform() const { return mObjToWorld; }
|
||||
|
||||
/// Returns the transform which can be used to convert world space
|
||||
/// into object space
|
||||
const MatrixF& getWorldTransform() const { return mWorldToObj; }
|
||||
|
||||
/// Returns the scale of the object
|
||||
const VectorF& getScale() const { return mObjScale; }
|
||||
|
||||
/// Returns the bounding box for this object in local coordinates
|
||||
const Box3F& getObjBox() const { return mObjBox; }
|
||||
|
||||
/// Returns the bounding box for this object in world coordinates
|
||||
const Box3F& getWorldBox() const { return mWorldBox; }
|
||||
|
||||
/// Returns the bounding sphere for this object in world coordinates
|
||||
const SphereF& getWorldSphere() const { return mWorldSphere; }
|
||||
|
||||
/// Returns the center of the bounding box in world coordinates
|
||||
Point3F getBoxCenter() const { return (mWorldBox.min + mWorldBox.max) * 0.5f; }
|
||||
|
||||
/// Sets the Object -> World transform
|
||||
///
|
||||
/// @param mat New transform matrix
|
||||
virtual void setTransform(const MatrixF & mat);
|
||||
|
||||
/// Sets the scale for the object
|
||||
/// @param scale Scaling values
|
||||
virtual void setScale(const VectorF & scale);
|
||||
|
||||
/// This sets the render transform for this object
|
||||
/// @param mat New render transform
|
||||
virtual void setRenderTransform(const MatrixF &mat);
|
||||
|
||||
/// Returns the render transform
|
||||
const MatrixF& getRenderTransform() const { return mRenderObjToWorld; }
|
||||
|
||||
/// Returns the render transform to convert world to local coordinates
|
||||
const MatrixF& getRenderWorldTransform() const { return mRenderWorldToObj; }
|
||||
|
||||
/// Returns the render world box
|
||||
const Box3F& getRenderWorldBox() const { return mRenderWorldBox; }
|
||||
|
||||
/// Builds a convex hull for this object.
|
||||
///
|
||||
/// Think of a convex hull as a low-res mesh which covers, as tightly as
|
||||
/// possible, the object mesh, and is used as a collision mesh.
|
||||
/// @param box
|
||||
/// @param convex Convex mesh generated (out)
|
||||
virtual void buildConvex(const Box3F& box,Convex* convex);
|
||||
|
||||
/// Builds a list of polygons which intersect a bounding volume.
|
||||
///
|
||||
/// This will use either the sphere or the box, not both, the
|
||||
/// SceneObject implimentation ignores sphere.
|
||||
///
|
||||
/// @see AbstractPolyList
|
||||
/// @param polyList Poly list build (out)
|
||||
/// @param box Box bounding volume
|
||||
/// @param sphere Sphere bounding volume
|
||||
virtual bool buildPolyList(AbstractPolyList* polyList, const Box3F &box, const SphereF &sphere);
|
||||
|
||||
/// Builds a collision tree of all the polygons which collide with a bounding volume.
|
||||
///
|
||||
/// @note Not implemented in SceneObject. @see TerrainBlock::buildCollisionBSP
|
||||
/// @param tree BSP tree built (out)
|
||||
/// @param box Box bounding volume
|
||||
/// @param sphere Sphere bounding volume
|
||||
virtual BSPNode* buildCollisionBSP(BSPTree *tree, const Box3F &box, const SphereF &sphere);
|
||||
|
||||
/// Casts a ray and obtain collision information, returns true if RayInfo is modified.
|
||||
///
|
||||
/// @param start Start point of ray
|
||||
/// @param end End point of ray
|
||||
/// @param info Collision information obtained (out)
|
||||
virtual bool castRay(const Point3F &start, const Point3F &end, RayInfo* info);
|
||||
|
||||
virtual bool collideBox(const Point3F &start, const Point3F &end, RayInfo* info);
|
||||
|
||||
/// Returns the position of the object.
|
||||
Point3F getPosition() const;
|
||||
|
||||
/// Returns the render-position of the object.
|
||||
///
|
||||
/// @see getRenderTransform
|
||||
Point3F getRenderPosition() const;
|
||||
|
||||
/// Sets the position of the object
|
||||
void setPosition(const Point3F &pos);
|
||||
|
||||
/// Gets the velocity of the object
|
||||
virtual Point3F getVelocity() const;
|
||||
|
||||
/// Sets the velocity of the object
|
||||
/// @param v Velocity
|
||||
virtual void setVelocity(const Point3F &v);
|
||||
|
||||
/// @}
|
||||
|
||||
public:
|
||||
/// @name Zones
|
||||
///
|
||||
/// A zone is a portalized section of an InteriorInstance, and an InteriorInstance can manage more than one zone.
|
||||
/// There is always at least one zone in the world, zone 0, which represens the whole world. Any
|
||||
/// other zone will be in an InteriorInstance. Torque keeps track of the zones containing an object
|
||||
/// as it moves throughout the world. An object can exists in multiple zones at once.
|
||||
/// @{
|
||||
|
||||
/// Returns true if this object is managing zones.
|
||||
///
|
||||
/// This is only true in the case of InteriorInstances which have zones in them.
|
||||
bool isManagingZones() const;
|
||||
|
||||
/// Gets the index of the first zone this object manages in the collection of zones.
|
||||
U32 getZoneRangeStart() const { return mZoneRangeStart; }
|
||||
|
||||
/// Gets the number of zones containing this object.
|
||||
U32 getNumCurrZones() const { return mNumCurrZones; }
|
||||
|
||||
/// Returns the nth zone containing this object.
|
||||
U32 getCurrZone(const U32 index) const;
|
||||
|
||||
/// If an object exists in multiple zones, this method will give you the
|
||||
/// number and indices of these zones (storing them in the provided variables).
|
||||
///
|
||||
/// @param obj Object in question.
|
||||
/// @param zones Indices of zones containing the object. (out)
|
||||
/// @param numZones Number of elements in the returned array. (out)
|
||||
virtual bool getOverlappingZones(SceneObject* obj, U32* zones, U32* numZones);
|
||||
|
||||
/// Returns the zone containing p.
|
||||
///
|
||||
/// @param p Point to test.
|
||||
virtual U32 getPointZone(const Point3F& p);
|
||||
|
||||
/// This is called on a zone managing object to scope all the zones managed.
|
||||
///
|
||||
/// @param rootPosition Camera position
|
||||
/// @param rootDistance Camera visible distance
|
||||
/// @param zoneScopeState Array of booleans which line up with the collection of zones, marked true if that zone is scoped (out)
|
||||
virtual bool scopeObject(const Point3F& rootPosition,
|
||||
const F32 rootDistance,
|
||||
bool* zoneScopeState);
|
||||
/// @}
|
||||
|
||||
/// Called when the object is supposed to render itself.
|
||||
///
|
||||
/// @param state Current rendering state.
|
||||
/// @see SceneState
|
||||
/// @param image Image associated with this object to render.
|
||||
/// @see SceneRenderImage
|
||||
virtual void renderObject(SceneState *state, SceneRenderImage *image);
|
||||
|
||||
/// Called when the SceneGraph is ready for the registration of RenderImages.
|
||||
///
|
||||
/// @see SceneState
|
||||
///
|
||||
/// @param state SceneState
|
||||
/// @param stateKey State key of the current SceneState
|
||||
/// @param startZone Base zone index
|
||||
/// @param modifyBaseZoneState If true, the object needs to modify the zone state.
|
||||
virtual bool prepRenderImage(SceneState *state, const U32 stateKey, const U32 startZone,
|
||||
const bool modifyBaseZoneState = false);
|
||||
|
||||
/// Adds object to the client or server container depending on the object
|
||||
void addToScene();
|
||||
|
||||
/// Removes the object from the client/server container
|
||||
void removeFromScene();
|
||||
|
||||
//-------------------------------------- Derived class interface
|
||||
// Overrides
|
||||
protected:
|
||||
bool onAdd();
|
||||
void onRemove();
|
||||
|
||||
// Overrideables
|
||||
protected:
|
||||
/// Called when this is added to the SceneGraph.
|
||||
///
|
||||
/// @param graph SceneGraph this is getting added to
|
||||
virtual bool onSceneAdd(SceneGraph *graph);
|
||||
|
||||
/// Called when this is removed from the SceneGraph
|
||||
virtual void onSceneRemove();
|
||||
|
||||
/// Called when the size of the object changes
|
||||
virtual void onScaleChanged();
|
||||
|
||||
/// @name Portals
|
||||
/// @{
|
||||
|
||||
/// This is used by a portal controling object to transform the base-modelview
|
||||
/// used by the scenegraph for rendering to the modelview it needs to render correctly.
|
||||
///
|
||||
/// @see MirrorSubObject
|
||||
///
|
||||
/// @param portalIndex Index of portal in the list of portals controlled by the object.
|
||||
/// @param oldMV Current modelview matrix used by the SceneGraph (in)
|
||||
/// @param newMV New modelview to be used by the SceneGraph (out)
|
||||
virtual void transformModelview(const U32 portalIndex, const MatrixF& oldMV, MatrixF* newMV);
|
||||
|
||||
/// Used to tranform the position of a point based on a portal.
|
||||
///
|
||||
/// @param portalIndex Index of a portal to transform by.
|
||||
/// @param point Point to transform.
|
||||
virtual void transformPosition(const U32 portalIndex, Point3F& point);
|
||||
|
||||
/// Returns a new view frustum for the portal.
|
||||
///
|
||||
/// @param portalIndex Which portal in the list of portals the object controls
|
||||
/// @param oldFrustum Current frustum.
|
||||
/// @param nearPlane Near clipping plane.
|
||||
/// @param farPlane Far clipping plane.
|
||||
/// @param oldViewport Current viewport.
|
||||
/// @param newFrustum New view frustum to use. (out)
|
||||
/// @param newViewport New viewport to use. (out)
|
||||
/// @param flippedMatrix Should the object should use a flipped matrix to calculate viewport and frustum?
|
||||
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);
|
||||
|
||||
/// Called before things are to be rendered from the portals point of view, to set up
|
||||
/// everything the portal needs to render correctly.
|
||||
///
|
||||
/// @param portalIndex Index of portal to use.
|
||||
/// @param pCurrState Current SceneState
|
||||
/// @param pParentState SceneState used before this portal was activated
|
||||
virtual void openPortal(const U32 portalIndex,
|
||||
SceneState* pCurrState,
|
||||
SceneState* pParentState);
|
||||
|
||||
/// Called after rendering of a portal is complete, this resets the states
|
||||
/// the previous call to openPortal() changed.
|
||||
///
|
||||
/// @param portalIndex Index of portal to use.
|
||||
/// @param pCurrState Current SceneState
|
||||
/// @param pParentState SceneState used before this portal was activated
|
||||
virtual void closePortal(const U32 portalIndex,
|
||||
SceneState* pCurrState,
|
||||
SceneState* pParentState);
|
||||
public:
|
||||
|
||||
/// Returns the plane of the portal in world space.
|
||||
///
|
||||
/// @param portalIndex Index of portal to use.
|
||||
/// @param plane Plane of the portal in world space (out)
|
||||
virtual void getWSPortalPlane(const U32 portalIndex, PlaneF *plane);
|
||||
|
||||
/// @}
|
||||
|
||||
protected:
|
||||
/// Sets the mLastState and mLastStateKey.
|
||||
///
|
||||
/// @param state SceneState to set as the last state
|
||||
/// @param key Key to set as the last state key
|
||||
void setLastState(SceneState *state, U32 key);
|
||||
|
||||
/// Returns true if the provided SceneState and key are set as this object's
|
||||
/// last state and key.
|
||||
///
|
||||
/// @param state SceneState in question
|
||||
/// @param key State key in question
|
||||
bool isLastState(SceneState *state, U32 key) const;
|
||||
|
||||
|
||||
/// @name Traversal State
|
||||
///
|
||||
/// The SceneGraph traversal is recursive and the traversal state of an object
|
||||
/// can be one of three things:
|
||||
/// - Pending - The object has not yet been examined for zone traversal.
|
||||
/// - Working - The object is currently having its zones traversed.
|
||||
/// - Done - The object has had all of its zones traversed or doesn't manage zones.
|
||||
///
|
||||
/// @note These states were formerly referred to as TraverseColor, with White, Black, and
|
||||
/// Gray; this was changed in Torque 1.2 by Pat "KillerBunny" Wilson. This code is
|
||||
/// only used internal to this class
|
||||
/// @{
|
||||
|
||||
// These two replaced by TraversalState because that makes more sense -KB
|
||||
//void setTraverseColor(TraverseColor);
|
||||
//TraverseColor getTraverseColor() const;
|
||||
// ph34r teh muskrat! - Travis Colure
|
||||
|
||||
/// This sets the traversal state of the object.
|
||||
///
|
||||
/// @note This is used internally; you should not normally need to call it.
|
||||
/// @param s Traversal state to assign
|
||||
void setTraversalState( TraversalState s );
|
||||
|
||||
/// Returns the traversal state of this object
|
||||
TraversalState getTraversalState() const;
|
||||
|
||||
/// @}
|
||||
|
||||
/// @name Lighting
|
||||
/// @{
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
/// Sets up lighting for the rendering of this object
|
||||
virtual void installLights();
|
||||
|
||||
/// Removes lighting for the rendering of this object
|
||||
virtual void uninstallLights();
|
||||
|
||||
/// Gets the color of the ambient light in the area of the object and
|
||||
/// stores it in the provided ColorF.
|
||||
///
|
||||
/// @param col Ambient color (out)
|
||||
virtual bool getLightingAmbientColor(ColorF * col);
|
||||
|
||||
LightingInfo mLightingInfo; ///< Lighting info for this object
|
||||
|
||||
/// @}
|
||||
|
||||
protected:
|
||||
|
||||
/// @name Transform and Collision Members
|
||||
/// @{
|
||||
|
||||
///
|
||||
Container* mContainer;
|
||||
|
||||
MatrixF mObjToWorld; ///< Transform from object space to world space
|
||||
MatrixF mWorldToObj; ///< Transform from world space to object space (inverse)
|
||||
Point3F mObjScale; ///< Object scale
|
||||
|
||||
Box3F mObjBox; ///< Bounding box in object space
|
||||
Box3F mWorldBox; ///< Bounding box in world space
|
||||
SphereF mWorldSphere; ///< Bounding sphere in world space
|
||||
|
||||
MatrixF mRenderObjToWorld; ///< Render matrix to transform object space to world space
|
||||
MatrixF mRenderWorldToObj; ///< Render matrix to transform world space to object space
|
||||
Box3F mRenderWorldBox; ///< Render bounding box in world space
|
||||
SphereF mRenderWorldSphere; ///< Render bounxing sphere in world space
|
||||
|
||||
/// Regenerates the world-space bounding box and bounding sphere
|
||||
void resetWorldBox();
|
||||
|
||||
/// Regenerates the render-world-space bounding box and sphere
|
||||
void resetRenderWorldBox();
|
||||
|
||||
SceneObjectRef* mZoneRefHead;
|
||||
SceneObjectRef* mBinRefHead;
|
||||
|
||||
U32 mBinMinX;
|
||||
U32 mBinMaxX;
|
||||
U32 mBinMinY;
|
||||
U32 mBinMaxY;
|
||||
|
||||
/// @}
|
||||
|
||||
/// @name Container Interface
|
||||
///
|
||||
/// When objects are searched, we go through all the zones and ask them for
|
||||
/// all of their objects. Because an object can exist in multiple zones, the
|
||||
/// container sequence key is set to the id of the current search. Then, while
|
||||
/// searching, we check to see if an object's sequence key is the same as the
|
||||
/// current search key. If it is, it will NOT be added to the list of returns
|
||||
/// since it has already been processed.
|
||||
///
|
||||
/// @{
|
||||
|
||||
U32 mContainerSeqKey; ///< Container sequence key
|
||||
|
||||
/// Returns the container sequence key
|
||||
U32 getContainerSeqKey() const { return mContainerSeqKey; }
|
||||
|
||||
/// Sets the container sequence key
|
||||
void setContainerSeqKey(const U32 key) { mContainerSeqKey = key; }
|
||||
/// @}
|
||||
|
||||
public:
|
||||
|
||||
/// Returns a pointer to the container that contains this object
|
||||
Container* getContainer() { return mContainer; }
|
||||
|
||||
protected:
|
||||
S32 mCollisionCount;
|
||||
|
||||
bool mGlobalBounds;
|
||||
|
||||
public:
|
||||
/// Returns the type mask for this object
|
||||
U32 getTypeMask() { return(mTypeMask); }
|
||||
|
||||
const bool isGlobalBounds() const
|
||||
{
|
||||
return mGlobalBounds;
|
||||
}
|
||||
|
||||
/// If global bounds are set to be true, then the object is assumed to
|
||||
/// have an infinitely large bounding box for collision and rendering
|
||||
/// purposes.
|
||||
///
|
||||
/// They can't be toggled currently.
|
||||
void setGlobalBounds()
|
||||
{
|
||||
if(mContainer)
|
||||
mContainer->removeFromBins(this);
|
||||
|
||||
mGlobalBounds = true;
|
||||
mObjBox.min.set(-1e10, -1e10, -1e10);
|
||||
mObjBox.max.set( 1e10, 1e10, 1e10);
|
||||
|
||||
if(mContainer)
|
||||
mContainer->insertIntoBins(this);
|
||||
}
|
||||
|
||||
|
||||
/// @name Rendering Members
|
||||
/// @{
|
||||
protected:
|
||||
SceneGraph* mSceneManager; ///< SceneGraph that controls this object
|
||||
U32 mZoneRangeStart; ///< Start of range of zones this object controls, 0xFFFFFFFF == no zones
|
||||
|
||||
U32 mNumCurrZones; ///< Number of zones this object exists in
|
||||
|
||||
private:
|
||||
TraversalState mTraversalState; ///< State of this object in the SceneGraph traversal - DON'T MESS WITH THIS
|
||||
SceneState* mLastState; ///< Last SceneState that was used to render this object.
|
||||
U32 mLastStateKey; ///< Last state key that was used to render this object.
|
||||
|
||||
/// @}
|
||||
|
||||
/// @name Persist and console
|
||||
/// @{
|
||||
public:
|
||||
static void initPersistFields();
|
||||
void inspectPostApply();
|
||||
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::setTraversalState( TraversalState s ) {
|
||||
mTraversalState = s;
|
||||
}
|
||||
|
||||
inline SceneObject::TraversalState SceneObject::getTraversalState() const {
|
||||
return mTraversalState;
|
||||
}
|
||||
|
||||
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!=NULL, "Error, too few object refs!");
|
||||
}
|
||||
AssertFatal(walk!=NULL, "Error, too few object refs!");
|
||||
|
||||
return walk->zone;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
inline SceneObjectRef* Container::allocateObjectRef()
|
||||
{
|
||||
if (mFreeRefPool == NULL)
|
||||
{
|
||||
addRefPoolBlock();
|
||||
}
|
||||
AssertFatal(mFreeRefPool!=NULL, "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->object = NULL;
|
||||
trash->nextInBin = NULL;
|
||||
trash->prevInBin = NULL;
|
||||
trash->nextInObj = mFreeRefPool;
|
||||
mFreeRefPool = trash;
|
||||
}
|
||||
|
||||
inline void Container::findObjects(U32 mask, FindCallback callback, void *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_
|
||||
|
||||
Reference in New Issue
Block a user