tge/engine/sceneGraph/sceneState.h
2017-04-17 06:17:10 -06:00

478 lines
18 KiB
C++
Executable File

//-----------------------------------------------------------------------------
// Torque Game Engine
// Copyright (C) GarageGames.com, Inc.
//-----------------------------------------------------------------------------
#ifndef _SCENESTATE_H_
#define _SCENESTATE_H_
#ifndef _PLATFORM_H_
#include "platform/platform.h"
#endif
#ifndef _PLATFORMASSERT_H_
#include "platform/platformAssert.h"
#endif
#ifndef _TVECTOR_H_
#include "core/tVector.h"
#endif
#ifndef _MRECT_H_
#include "math/mRect.h"
#endif
#ifndef _MMATRIX_H_
#include "math/mMatrix.h"
#endif
#ifndef _COLOR_H_
#include "core/color.h"
#endif
#ifndef _GTEXMANAGER_H_
#include "dgl/gTexManager.h"
#endif
class SceneObject;
/// A SceneRenderImage is used by the SceneState/SceneGraph to sort objects for rendering
/// order.
///
/// The scene graph calls prepRenderImage on every SceneObject it intends to render
/// every frame. The SceneObject will then insert one or more SceneRenderImages. These images
/// describe what will be rendered by the object, whether it will have transparency,
/// what type of object it is, etc.
/// These images are sorted by SortType, and then rendered. If any images are
/// translucent, the SceneState builds a BSP tree and then evaluates it back to front.
class SceneRenderImage
{
public:
/// Sort type indicates when the image should be rendered and how
/// it should be sorted.
///
/// The rendering order is this:
/// - Sky
/// - BeginSort
/// - Terrain
/// - Normal
/// - Point
/// - Plane
/// - EndSort
///
/// Point and Plane are only valid if the object is translucent.
/// The variables 'plane' and 'poly' are used for these sort types.
/// If the point type is used, the actual point is specified in poly[0]
enum SortType
{
Sky = 0,
Terrain = 1,
Normal = 2,
Point,
Plane,
EndSort,
BeginSort
};
SceneRenderImage()
: sortType(Normal),
isTranslucent(false),
tieBreaker(false),
useSmallTextures(false),
textureSortKey(0)
{
//
}
virtual ~SceneRenderImage();
SceneObject* obj; ///< The SceneObject this image represents.
bool isTranslucent; ///< Is this image translucent?
bool tieBreaker; ///< If two objects have the same points, this is used to determine sorting order.
bool useSmallTextures; ///< If this is set to true, the object will render using a low-res version of its textures.
SortType sortType;
PlaneF plane; ///< The plane if SortType::Plane is used.
Point3F poly[4]; ///< If SortType::Plane is used, this is the quad that defines the bounds for the
/// plane. If SortType::Point is used, then poly[0] is the point, and the rest is ignored.
F32 polyArea; ///< Area of the polygon defined by poly[].
F32 pointDistSq; ///< Distance from camera to poly[0] squared.
///
/// @note This is set inside SceneState.
U32 textureSortKey; ///< This is used to sort objects of the same SortType into order if the objects have
/// no translucency.
/// Linked list implementation.
///
/// @note NEVER set this. This is managed by Torque.
SceneRenderImage* pNext;
};
//--------------------------------------------------------------------------
//-------------------------------------- SceneState
//
struct FogVolume;
/// The SceneState describes the state of the scene being rendered. It keeps track
/// of the information that objects need to render properly with regard to the
/// camera position, any fog information, viewing frustum, the global environment
/// map for reflections, viewable distance and portal information.
class SceneState
{
friend class SceneGraph;
public:
struct FogBand
{
bool isFog;
float cap;
float factor;
ColorF color;
};
struct ZoneState {
bool render;
F64 frustum[4]; ///< Winding order is: left, right, bottom, top.
RectI viewport;
bool clipPlanesValid;
PlaneF clipPlanes[5];
};
/// Sets up the clipping planes using the parameters from a ZoneState.
///
/// @param zone ZoneState to initalize clipping to
void setupClipPlanes(ZoneState &zone);
/// Used to represent a portal which inserts a transformation into the scene.
struct TransformPortal {
SceneObject* owner;
U32 portalIndex;
U32 globalZone;
Point3F traverseStart;
bool flipCull;
};
public:
/// Constructor
///
/// @see SceneGraph::renderScene
SceneState(SceneState* parent,
const U32 numZones,
F64 left,
F64 right,
F64 bottom,
F64 top,
F64 nearPlane,
F64 farPlane,
RectI viewport,
const Point3F& camPos,
const MatrixF& modelview,
F32 fogDistance,
F32 visibleDistance,
ColorF fogColor,
U32 numFogVolumes,
FogVolume *fogVolumes,
TextureHandle environmentMap,
F32 visFactor);
~SceneState();
/// Sets the active portal.
///
/// @param owner Object which owns the portal (portalized object)
/// @param idx Index of the portal in the list of portal planes
void setPortal(SceneObject *owner, const U32 idx);
/// Assigns the reference point of the SceneRenderImage. For use with
/// translucent images.
///
/// @param obj SceneObject that belongs to the SceneRenderImage being manipulated
/// @param image SceneRenderImage being manipulated
void setImageRefPoint(SceneObject *obj, SceneRenderImage *image) const;
/// Returns the camera position this SceneState is using.
const Point3F& getCameraPosition() const { return mCamPosition; }
/// Returns the minimum distance something must be from the camera to not be culled.
F64 getNearPlane() const { return mNearPlane; }
/// Returns the maximum distance something can be from the camera to not be culled.
F64 getFarPlane() const { return mFarPlane; }
void setFarPlane(F64 farPlane) { mFarPlane = farPlane; }
/// Returns the base ZoneState.
///
/// @see ZoneState
const ZoneState& getBaseZoneState() const;
/// Returns the base ZoneState as a non-const reference.
///
/// @see getBaseZoneState
ZoneState& getBaseZoneStateNC();
/// Returns the ZoneState for a particular zone ID.
///
/// @param zoneId ZoneId
const ZoneState& getZoneState(const U32 zoneId) const;
/// Returns the ZoneState for a particular zone ID as a non-const reference.
///
/// @see getZoneState
/// @param zoneId ZoneId
ZoneState& getZoneStateNC(const U32 zoneId);
/// Adds an image to be rendered by this SceneState into the proper category.
///
/// @param image Image to add
void insertRenderImage(SceneRenderImage *image);
/// Adds a new transform portal to the SceneState.
///
/// @param owner SceneObject owner of the portal (portalized object).
/// @param portalIndex Index of the portal in the list of portal planes.
/// @param globalZone Index of the zone this portal is in in the list of ZoneStates.
/// @param traversalStartPoint Start point of the zone traversal.
/// @see SceneGraph::buildSceneTree
/// @see SceneGraph::findZone
///
/// @param flipCull If true, the portal plane will be flipped
void insertTransformPortal(SceneObject* owner, U32 portalIndex,
U32 globalZone, const Point3F& traversalStartPoint,
const bool flipCull);
/// This enables terrain to be drawn inside interiors.
void enableTerrainOverride();
/// Returns true if terrain is allowed to be drawn inside interiors.
bool isTerrainOverridden() const;
/// Sorts the list of images, builds the translucency BSP tree,
/// sets up the portal, then renders all images in the state.
void renderCurrentImages();
/// Returns true if the object in question is going to be rendered
/// as opposed to being culled out.
///
/// @param obj Object in question.
bool isObjectRendered(const SceneObject *obj);
/// Sets the viewport and projection up for the given zone.
///
/// @param zone Zone for which we want to set up a viewport/projection.
void setupZoneProjection(const U32 zone);
/// Sets up the projection matrix based on the zone the specified object is in.
///
/// @param object Object to use.
void setupObjectProjection(const SceneObject *object);
/// Sets up the projection matrix based on the base ZoneState.
void setupBaseProjection();
/// Returns the scale of the distance based fog [used for haze]
F32 getFogScale() const { return mFogScale; }
/// Returns the distance at which objects are no longer visible.
F32 getVisibleDistance() const;
/// Returns how far away fog is (ie, when objects will be fully fogged).
F32 getFogDistance() const;
/// Returns the color of the fog in the scene.
ColorF getFogColor() const;
/// Returns a texture handle to the environment map in use.
TextureHandle getEnvironmentMap() { return mEnvironmentMap; }
/// Sets up all the fog volumes in the Scene.
void setupFog();
/// Returns true if the box specified is visible, taking fog into account.
///
/// @param dist The length of the vector, projected on to the horizontal plane of the world, from the camera to the nearest point on the box
/// @param top The maximum z-value of the box
/// @param bottom The minimum z-value of the box
bool isBoxFogVisible(F32 dist, F32 top, F32 bottom);
/// Returns a value between 0.0 and 1.0 which indicates how obscured a point is by haze and fog.
///
/// @param dist Length of vector, projected onto horizontal world plane, from camera to the point.
/// @param deltaZ Z-offset of the camera.
F32 getHazeAndFog(float dist, float deltaZ) const;
/// Returns a value between 0.0 and 1.0 which indicates how obscured a point is by fog only.
///
/// @param dist Length of vector, projected onto horizontal world plane, from camera to the point.
/// @param deltaZ Z-offset of the camera.
F32 getFog(float dist, float deltaZ);
/// Returns a value between 0.0 and 1.0 which indicates how obscured a point is by fog only.
///
/// @param dist Length of vector, projected onto horizontal world plane, from camera to the point.
/// @param deltaZ Z-offset of the camera.
/// @param volKey Index of a particular band of volumetric fog.
F32 getFog(float dist, float deltaZ, S32 volKey);
/// Returns all fogs at a point.
///
/// @param dist Length of vector, projected onto horizontal world plane, from camera to the point.
/// @param deltaZ Z-offset of the camera.
/// @param array Array of fog colors at the point.
/// @param numFogs Number of fogs in the array.
void getFogs(float dist, float deltaZ, ColorF *array, U32 &numFogs);
/// Returns a value between 0.0 and 1.0 which indicates how obscured a point is by haze only.
///
/// @param dist Length of vector, projected onto horizontal world plane, from camera to the point.
F32 getHaze(F32 dist) const;
private:
/// Used to construct the BSP tree for sorting translucent images.
struct RenderBSPNode
{
PlaneF plane;
SceneRenderImage* riList;
U16 frontIndex;
U16 backIndex;
SceneRenderImage* rimage;
};
Vector<RenderBSPNode> mTranslucentBSP; ///< The BSP tree for translucent objects.
Vector<ZoneState> mZoneStates; ///< Collection of ZoneStates in the scene.
Vector<SceneRenderImage*> mRenderImages; ///< Collection of images to render.
Vector<SceneRenderImage*> mTranslucentPlaneImages; ///< Collection of SortType::Plane images.
Vector<SceneRenderImage*> mTranslucentPointImages; ///< Collection of SortType::Point images.
Vector<SceneRenderImage*> mTranslucentBeginImages; ///< Collection of SortType::BeginImage images.
Vector<SceneRenderImage*> mTranslucentEndImages; ///< Collection of SortType::EndImage images.
/// Sorts the render images.
void sortRenderImages();
/// Builds the BSP tree of translucent images.
void buildTranslucentBSP();
/// Inserts a translucent image into the translucent BSP tree.
///
/// @param rNode Root node.
/// @param image Image to insert.
/// @param rendered Used in recursion, don't mess with this!
void insertIntoNode(RenderBSPNode &rNode, SceneRenderImage *image, bool rendered = true);
/// Renders the translucency BSP tree.
///
/// @param rNode Root node.
void renderNode(RenderBSPNode &rNode);
bool mTerrainOverride; ///< If true, terrain is allowed to render inside interiors
Vector<SceneState*> mSubsidiaries; ///< Transform portals which have been processed by the scene traversal process
///
/// @note Closely related. Transform portals are turned into sorted mSubsidiaries
/// by the traversal process...
Vector<TransformPortal> mTransformPortals; ///< Collection of TransformPortals
Vector<FogBand> mPosFogBands; ///< Fog bands above the world plane
Vector<FogBand> mNegFogBands; ///< Fog bands below the world plane
ZoneState mBaseZoneState; ///< ZoneState of the base zone of the scene
Point3F mCamPosition; ///< Camera position in this state
F64 mNearPlane; ///< Minimum distance an object must be from the camera to get rendered
F64 mFarPlane; ///< Maximum distance an object can be from the camera to get rendered
F32 mVisFactor; ///< Visibility factor of the scene, used to modify fog
SceneState* mParent; ///< This is used for portals, if this is not NULL, then this SceneState belongs to a portal, and not the main SceneState
SceneObject* mPortalOwner; ///< SceneObject which owns the current portal
U32 mPortalIndex; ///< Index the current portal is in the list of portals
ColorF mFogColor; ///< Distance based, not volumetric, fog color
F32 mFogDistance; ///< Distance to distance-fog
F32 mVisibleDistance; ///< Visible distance of the scene
F32 mFogScale; ///< Fog scale of the distance based fog
U32 mNumFogVolumes; ///< Number of fog volumes in the scene
FogVolume *mFogVolumes; ///< Pointer to the array of fog volumes in the scene
TextureHandle mEnvironmentMap; ///< Current environment map
public:
bool mFlipCull; ///< If true the portal clipping plane will be reversed
MatrixF mModelview; ///< Modelview matrix this scene is based off of
/// Returns the fog bands above the world plane
Vector<FogBand> *getPosFogBands() { return &mPosFogBands; }
/// Returns the fog bands above the world plane [const]
const Vector<FogBand> *getPosFogBands() const { return &mPosFogBands; }
/// Returns the fog bands below the world planes
Vector<FogBand> *getNegFogBands() { return &mNegFogBands; }
/// Returns the fog bands below the world planes [const]
const Vector<FogBand> *getNegFogBands() const { return &mNegFogBands; }
};
inline F32 SceneState::getHaze(F32 dist) const
{
if(dist <= mFogDistance)
return 0.0f;
if (dist > mVisibleDistance)
return 1.0f;
F32 distFactor = (dist - mFogDistance) * mFogScale - 1.0f;
return 1.0f - distFactor * distFactor;
}
inline F32 SceneState::getVisibleDistance() const
{
return mVisibleDistance;
}
inline F32 SceneState::getFogDistance() const
{
return mFogDistance;
}
inline ColorF SceneState::getFogColor() const
{
return mFogColor;
}
inline const SceneState::ZoneState& SceneState::getBaseZoneState() const
{
return mBaseZoneState;
}
inline SceneState::ZoneState& SceneState::getBaseZoneStateNC()
{
return mBaseZoneState;
}
inline const SceneState::ZoneState& SceneState::getZoneState(const U32 zoneId) const
{
AssertFatal(zoneId < (U32)mZoneStates.size(), "Error, out of bounds zone!");
return mZoneStates[zoneId];
}
inline SceneState::ZoneState& SceneState::getZoneStateNC(const U32 zoneId)
{
AssertFatal(zoneId < (U32)mZoneStates.size(), "Error, out of bounds zone!");
return mZoneStates[zoneId];
}
inline void SceneState::enableTerrainOverride()
{
mTerrainOverride = true;
}
inline bool SceneState::isTerrainOverridden() const
{
return mTerrainOverride;
}
#endif // _H_SCENESTATE_