📄 sceneobject.h
字号:
//-----------------------------------------------------------------------------
// 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; }
#ifdef TGE_RPG
/// face to point
///
/// @param mat New transform matrix
virtual void faceTo(const Point3F& ptFace,bool bFaceMe=true);
virtual void moveTo( const Point3F &ptPos){}
#endif
/// 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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -