mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-01-20 12:44:46 +00:00
1173 lines
33 KiB
C++
1173 lines
33 KiB
C++
//-----------------------------------------------------------------------------
|
|
// Copyright (c) 2012 GarageGames, LLC
|
|
//
|
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
// of this software and associated documentation files (the "Software"), to
|
|
// deal in the Software without restriction, including without limitation the
|
|
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
|
// sell copies of the Software, and to permit persons to whom the Software is
|
|
// furnished to do so, subject to the following conditions:
|
|
//
|
|
// The above copyright notice and this permission notice shall be included in
|
|
// all copies or substantial portions of the Software.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
// IN THE SOFTWARE.
|
|
//-----------------------------------------------------------------------------
|
|
|
|
#ifndef _INTERIOR_H_
|
|
#define _INTERIOR_H_
|
|
|
|
#ifndef _COLOR_H_
|
|
#include "core/color.h"
|
|
#endif
|
|
#ifndef _COLLISION_H_
|
|
#include "collision/collision.h"
|
|
#endif
|
|
#ifndef _TVECTOR_H_
|
|
#include "core/util/tVector.h"
|
|
#endif
|
|
#ifndef _MPOINT3_H_
|
|
#include "math/mPoint3.h"
|
|
#endif
|
|
#ifndef _MPLANE_H_
|
|
#include "math/mPlane.h"
|
|
#endif
|
|
#ifndef _MBOX_H_
|
|
#include "math/mBox.h"
|
|
#endif
|
|
#ifndef _MSPHERE_H_
|
|
#include "math/mSphere.h"
|
|
#endif
|
|
#ifndef _CONVEX_H_
|
|
#include "collision/convex.h"
|
|
#endif
|
|
#ifndef _INTERIORLMMANAGER_H_
|
|
#include "interior/interiorLMManager.h"
|
|
#endif
|
|
#ifndef _INTERIORSIMPLEMESH_H_
|
|
#include "interior/interiorSimpleMesh.h"
|
|
#endif
|
|
#ifndef _OPTIMIZEDPOLYLIST_H_
|
|
#include "collision/optimizedPolyList.h"
|
|
#endif
|
|
#ifndef _SCENEDATA_H_
|
|
#include "materials/sceneData.h"
|
|
#endif
|
|
|
|
//-------------------------------------- Forward declarations
|
|
class MatInstance;
|
|
class Stream;
|
|
class EditGeometry;
|
|
class InteriorInstance;
|
|
class GBitmap;
|
|
class RectD;
|
|
class SphereF;
|
|
class MatrixF;
|
|
class SceneRenderState;
|
|
class MaterialList;
|
|
class AbstractPolyList;
|
|
class InteriorSubObject;
|
|
class TranslucentSubObject;
|
|
class BitVector;
|
|
struct RayInfo;
|
|
struct EdgeList;
|
|
class SurfaceHash;
|
|
class InteriorPolytope;
|
|
class LightInfo;
|
|
class PlaneRange;
|
|
class EditInteriorResource;
|
|
class GFXVertexBuffer;
|
|
class GFXPrimitiveBuffer;
|
|
struct RenderInst;
|
|
struct GFXVertexPNTTB;
|
|
struct GFXPrimitiveInfo;
|
|
struct MaterialFeatureData;
|
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
class InteriorConvex : public Convex
|
|
{
|
|
typedef Convex Parent;
|
|
friend class Interior;
|
|
friend class InteriorInstance;
|
|
|
|
protected:
|
|
Interior* pInterior;
|
|
public:
|
|
S32 hullId;
|
|
Box3F box;
|
|
|
|
public:
|
|
InteriorConvex() { mType = InteriorConvexType; }
|
|
InteriorConvex(const InteriorConvex& cv)
|
|
{
|
|
mObject = cv.mObject;
|
|
pInterior = cv.pInterior;
|
|
hullId = cv.hullId;
|
|
box = box;
|
|
}
|
|
|
|
Box3F getBoundingBox() const;
|
|
Box3F getBoundingBox(const MatrixF& mat, const Point3F& scale) const;
|
|
Point3F support(const VectorF& v) const;
|
|
void getFeatures(const MatrixF& mat,const VectorF& n, ConvexFeature* cf);
|
|
void getPolyList(AbstractPolyList* list);
|
|
};
|
|
|
|
class ZoneVisDeterminer
|
|
{
|
|
enum Mode
|
|
{
|
|
FromState,
|
|
FromRects
|
|
};
|
|
|
|
Mode mMode;
|
|
|
|
SceneRenderState* mState;
|
|
U32 mZoneRangeOffset;
|
|
U32 mParentZone;
|
|
|
|
public:
|
|
ZoneVisDeterminer() : mMode(FromRects), mState(NULL) { }
|
|
|
|
void runFromState(SceneRenderState*, U32, U32);
|
|
void runFromRects(SceneRenderState*, U32, U32);
|
|
|
|
bool isZoneVisible(const U32) const;
|
|
};
|
|
|
|
|
|
struct ItrPaddedPoint
|
|
{
|
|
Point3F point;
|
|
union
|
|
{
|
|
F32 fogCoord;
|
|
U8 fogColor[4];
|
|
};
|
|
};
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
//-------------------------------------- CLASS NOTES
|
|
// Interior: Base for all interior geometries. Contains all lighting, poly,
|
|
// portal zone, bsp info, etc. to render an interior.
|
|
//
|
|
// Internal Structure Notes:
|
|
// IBSPNode:
|
|
// planeIndex: Obv.
|
|
// frontIndex/backIndex: Top bit indicates if children are leaves.
|
|
// Next bit indicates if leaf children are solid.
|
|
//
|
|
// IBSPLeafSolid:
|
|
// planeIndex: obv.
|
|
// surfaceIndex/surfaceCount: Polys that are on the faces of this leaf. Only
|
|
// used for collision/surface info detection.
|
|
//
|
|
//------------------------------------------------------------------------------
|
|
|
|
//------------------------------------------------------------------------------
|
|
class Interior
|
|
{
|
|
friend class EditGeometry;
|
|
friend class InteriorInstance;
|
|
friend class InteriorProxy;
|
|
friend class blInteriorProxy;
|
|
friend class TranslucentSubObject;
|
|
friend class MirrorSubObject;
|
|
friend class InteriorConvex;
|
|
friend class EditInteriorResource;
|
|
friend class InteriorLMManager;
|
|
friend class TSShape;
|
|
friend class SceneLighting;
|
|
|
|
//-------------------------------------- Public interfaces
|
|
public:
|
|
Interior();
|
|
~Interior();
|
|
|
|
|
|
private:
|
|
U32 mLightMapBorderSize;
|
|
|
|
public:
|
|
Vector<S32> surfaceZones;
|
|
U32 getLightMapBorderSize() const {return mLightMapBorderSize;}
|
|
void setLightMapBorderSize(U32 value) {mLightMapBorderSize = value;}
|
|
void buildSurfaceZones();
|
|
//void sgSetupLighting(InteriorInstance *intInst, SceneData &sgData);
|
|
//bool sgRenderLights(InteriorInstance *intInst, SceneData &sgData);
|
|
|
|
// Interior Render StateBlock
|
|
GFXStateBlockRef mInteriorSB;
|
|
|
|
MaterialList* mMaterialList;
|
|
|
|
// Misc
|
|
U32 getDetailLevel() const;
|
|
U32 getMinPixels() const;
|
|
const Box3F& getBoundingBox() const;
|
|
S32 getNumZones() const;
|
|
|
|
// Rendering
|
|
bool prepForRendering(const char* path);
|
|
|
|
bool traverseZones( SceneCullingState* state,
|
|
const Frustum& frustum,
|
|
S32 containingZone,
|
|
S32 baseZone,
|
|
U32 zoneOffset,
|
|
const MatrixF& OSToWS,
|
|
const Point3F& objScale,
|
|
const bool dontRestrictOutside,
|
|
const bool flipClipPlanes,
|
|
Frustum& outFrustum );
|
|
|
|
void prepBatchRender( InteriorInstance *intInst, SceneRenderState *state );
|
|
|
|
void setupRenderStates();
|
|
|
|
|
|
bool scopeZones(const S32 baseZone,
|
|
const Point3F& interiorRoot,
|
|
bool* interiorScopingState);
|
|
|
|
ZoneVisDeterminer setupZoneVis( InteriorInstance *intInst, SceneRenderState *state );
|
|
|
|
SceneData setupSceneGraphInfo( InteriorInstance *intInst,
|
|
SceneRenderState *state );
|
|
|
|
void setupRender( InteriorInstance *intInst,
|
|
SceneRenderState *state,
|
|
MeshRenderInst *coreRi,
|
|
const MatrixF* worldToCamera);
|
|
|
|
|
|
//-------------------------------------- Collision Interface and zone scans
|
|
public:
|
|
bool scanZones(const Box3F&, const MatrixF&, U16* zones, U32* numZones);
|
|
bool castRay(const Point3F&, const Point3F&, RayInfo*);
|
|
bool buildPolyList(AbstractPolyList*, const Box3F&, const MatrixF&, const Point3F&);
|
|
|
|
bool getIntersectingHulls(const Box3F&, U16* hulls, U32* numHulls);
|
|
bool getIntersectingVehicleHulls(const Box3F&, U16* hulls, U32* numHulls);
|
|
|
|
protected:
|
|
bool castRay_r(const U32, const U16, const Point3F&, const Point3F&, RayInfo*);
|
|
void buildPolyList_r(InteriorPolytope& polytope,
|
|
SurfaceHash& hash);
|
|
void scanZone_r(const U32 node,
|
|
const Point3F& center,
|
|
const Point3F& axisx,
|
|
const Point3F& axisy,
|
|
const Point3F& axisz,
|
|
U16* zones,
|
|
U32* numZones);
|
|
void scanZoneNew(InteriorPolytope& polytope,
|
|
U16* zones,
|
|
U32* numZones);
|
|
|
|
|
|
/// @name Lightmap Support
|
|
/// @{
|
|
static void _enableLightMapFeature( ProcessedMaterial *mat,
|
|
U32 stageNum,
|
|
MaterialFeatureData &fd,
|
|
const FeatureSet &features );
|
|
/// @}
|
|
|
|
//-------------------------------------- Global rendering control
|
|
public:
|
|
enum RenderModes
|
|
{
|
|
NormalRender = 0,
|
|
NormalRenderLines = 1,
|
|
ShowDetail = 2,
|
|
ShowAmbiguous = 3,
|
|
ShowOrphan = 4,
|
|
ShowLightmaps = 5,
|
|
ShowTexturesOnly = 6,
|
|
ShowPortalZones = 7,
|
|
ShowOutsideVisible = 8,
|
|
ShowCollisionFans = 9,
|
|
ShowStrips = 10,
|
|
ShowNullSurfaces = 11,
|
|
ShowLargeTextures = 12,
|
|
ShowHullSurfaces = 13,
|
|
ShowVehicleHullSurfaces = 14,
|
|
ShowVertexColors = 15,
|
|
ShowDetailLevel = 16
|
|
};
|
|
|
|
enum Constants
|
|
{
|
|
NumCoordBins = 16,
|
|
|
|
BinsXY = 0,
|
|
BinsXZ = 1,
|
|
BinsYZ = 2
|
|
};
|
|
|
|
static U32 smRenderMode;
|
|
static bool smFocusedDebug;
|
|
static bool smUseVertexLighting;
|
|
static U32 smFileVersion;
|
|
static bool smLightingCastRays;
|
|
static bool smLightingBuildPolyList;
|
|
|
|
//-------------------------------------- Persistence interface
|
|
public:
|
|
bool read(Stream& stream);
|
|
bool write(Stream& stream) const;
|
|
|
|
bool readVehicleCollision(Stream& stream);
|
|
bool writeVehicleCollision(Stream& stream) const;
|
|
|
|
private:
|
|
bool writePlaneVector(Stream&) const;
|
|
bool readPlaneVector(Stream&);
|
|
bool readLMapTexGen(Stream&, PlaneF&, PlaneF&);
|
|
bool writeLMapTexGen(Stream&, const PlaneF&, const PlaneF&) const;
|
|
void setupTexCoords();
|
|
void setupZonePlanes();
|
|
|
|
//-------------------------------------- For morian only...
|
|
public:
|
|
void processHullPolyLists();
|
|
void processVehicleHullPolyLists();
|
|
|
|
//-------------------------------------- BSP Structures
|
|
private:
|
|
struct IBSPNode
|
|
{
|
|
U16 planeIndex;
|
|
U32 frontIndex;
|
|
U32 backIndex;
|
|
|
|
U16 terminalZone; // if high bit set, then the lower 15 bits are the zone
|
|
// of any of the subsidiary nodes. Note that this is
|
|
// going to overestimate some, since an object could be
|
|
// completely contained in solid, but it's probably
|
|
// going to turn out alright.
|
|
};
|
|
struct IBSPLeafSolid
|
|
{
|
|
U32 surfaceIndex;
|
|
U16 surfaceCount;
|
|
};
|
|
|
|
bool isBSPLeafIndex(U32 index) const;
|
|
bool isBSPSolidLeaf(U32 index) const;
|
|
bool isBSPEmptyLeaf(U32 index) const;
|
|
U16 getBSPSolidLeafIndex(U32 index) const;
|
|
U16 getBSPEmptyLeafZone(U32 index) const;
|
|
|
|
void setupAveTexGenLength();
|
|
|
|
void truncateZoneTree();
|
|
void truncateZoneNode(const U32);
|
|
bool getUnifiedZone(const U32, S32*);
|
|
|
|
public:
|
|
static U16 getPlaneIndex(U16 index);
|
|
static bool planeIsFlipped(U16 index);
|
|
const PlaneF& getPlane(U16 index) const;
|
|
PlaneF getFlippedPlane(const U16 index) const;
|
|
|
|
const Point3F getPointNormal(const U32 surfaceIndex, const U32 pointOffset) const;
|
|
|
|
private:
|
|
bool areEqualPlanes(U16, U16) const;
|
|
|
|
bool isNullSurfaceIndex(const U32 index) const;
|
|
bool isVehicleNullSurfaceIndex(const U32 index) const;
|
|
U32 getNullSurfaceIndex(const U32 index) const;
|
|
U32 getVehicleNullSurfaceIndex(const U32 index) const;
|
|
|
|
//-------------------------------------- Portals and Zone structures
|
|
private:
|
|
struct Zone
|
|
{
|
|
U16 portalStart;
|
|
U16 portalCount;
|
|
|
|
U32 surfaceStart;
|
|
U32 planeStart;
|
|
|
|
U16 surfaceCount;
|
|
U16 planeCount;
|
|
|
|
U32 staticMeshStart;
|
|
U32 staticMeshCount;
|
|
|
|
U16 flags;
|
|
U16 zoneId; // This is ephemeral, not persisted out.
|
|
};
|
|
|
|
struct Portal
|
|
{
|
|
U16 planeIndex;
|
|
|
|
U16 triFanCount;
|
|
U32 triFanStart; // portals can have multiple windings
|
|
|
|
U16 zoneFront;
|
|
U16 zoneBack;
|
|
};
|
|
|
|
//-------------------------------------- Poly/Surface structures
|
|
public:
|
|
enum SurfaceFlags
|
|
{
|
|
SurfaceDetail = BIT(0),
|
|
SurfaceAmbiguous = BIT(1),
|
|
SurfaceOrphan = BIT(2),
|
|
SurfaceSharedLMaps = BIT(3), // Indicates that the alarm and normal states share a lightmap (for mission lighter)
|
|
SurfaceOutsideVisible = BIT(4),
|
|
SurfaceStaticMesh = BIT(5), // This surface belongs to a static mesh collision hull
|
|
SurfaceFlagMask = (SurfaceDetail |
|
|
SurfaceAmbiguous |
|
|
SurfaceOrphan |
|
|
SurfaceSharedLMaps |
|
|
SurfaceOutsideVisible |
|
|
SurfaceStaticMesh)
|
|
};
|
|
enum ZoneFlags
|
|
{
|
|
ZoneInside = BIT(0)
|
|
};
|
|
|
|
const bool isSurfaceOutsideVisible(U32 surface) const;
|
|
|
|
public:
|
|
struct TexMatrix
|
|
{
|
|
S32 T;
|
|
S32 N;
|
|
S32 B;
|
|
|
|
TexMatrix()
|
|
: T( -1 ),
|
|
N( -1 ),
|
|
B( -1 )
|
|
{};
|
|
};
|
|
|
|
struct Edge
|
|
{
|
|
S32 vertexes[2];
|
|
S32 faces[2];
|
|
};
|
|
|
|
struct TexGenPlanes
|
|
{
|
|
PlaneF planeX;
|
|
PlaneF planeY;
|
|
};
|
|
|
|
struct TriFan
|
|
{
|
|
U32 windingStart;
|
|
U32 windingCount;
|
|
};
|
|
|
|
struct Surface
|
|
{
|
|
U32 windingStart; // 1
|
|
|
|
U16 planeIndex; // 2
|
|
U16 textureIndex;
|
|
|
|
U32 texGenIndex; // 3
|
|
|
|
U16 lightCount; // 4
|
|
U8 surfaceFlags;
|
|
U32 windingCount;
|
|
|
|
U32 fanMask; // 5
|
|
|
|
U32 lightStateInfoStart; // 6
|
|
|
|
U32 mapOffsetX; // 7
|
|
U32 mapOffsetY;
|
|
U32 mapSizeX;
|
|
U32 mapSizeY;
|
|
|
|
Point3F T,B,N;
|
|
Point3F normal;
|
|
|
|
//U32 VBIndexStart;
|
|
//U32 primIndex;
|
|
GFXPrimitive surfaceInfo;
|
|
|
|
bool unused;
|
|
};
|
|
|
|
struct NullSurface
|
|
{
|
|
U32 windingStart;
|
|
|
|
U16 planeIndex;
|
|
U8 surfaceFlags;
|
|
U32 windingCount;
|
|
};
|
|
|
|
//-------------------------------------- Animated lighting structures
|
|
enum LightFlags
|
|
{
|
|
AnimationAmbient = BIT(0),
|
|
AnimationLoop = BIT(1),
|
|
AnimationFlicker = BIT(2),
|
|
AnimationTypeMask = BIT(3) - 1,
|
|
|
|
AlarmLight = BIT(3)
|
|
};
|
|
|
|
enum LightType
|
|
{
|
|
AmbientLooping = AnimationAmbient | AnimationLoop,
|
|
AmbientFlicker = AnimationAmbient | AnimationFlicker,
|
|
|
|
TriggerableLoop = AnimationLoop,
|
|
TriggerableFlicker = AnimationFlicker,
|
|
TriggerableRamp = 0
|
|
};
|
|
|
|
private:
|
|
bool readSurface(Stream&, Surface&, TexGenPlanes&, const bool);
|
|
|
|
public:
|
|
// this is public because tools/Morian needs this defination
|
|
struct AnimatedLight {
|
|
U32 nameIndex; // Light's name
|
|
U32 stateIndex; // start point in the state list
|
|
|
|
U16 stateCount; // number of states in this light
|
|
U16 flags; // flags (Apply AnimationTypeMask to get type)
|
|
|
|
U32 duration; // total duration of animation (ms)
|
|
};
|
|
private:
|
|
struct LightState {
|
|
U8 red; // state's color
|
|
U8 green;
|
|
U8 blue;
|
|
U8 _color_padding_;
|
|
|
|
U32 activeTime; // Time (ms) at which this state becomes active
|
|
|
|
U32 dataIndex; // StateData count and index for this state
|
|
U16 dataCount;
|
|
|
|
U16 __32bit_padding__;
|
|
};
|
|
struct LightStateData {
|
|
U32 surfaceIndex; // Surface affected by this data
|
|
U32 mapIndex; // Index into StateDataBuffer (0xFFFFFFFF indicates none)
|
|
U16 lightStateIndex; // Entry to modify in InteriorInstance
|
|
U16 __32bit_padding__;
|
|
};
|
|
|
|
// convex hull collision structures...
|
|
protected:
|
|
struct ConvexHull
|
|
{
|
|
F32 minX;
|
|
F32 maxX;
|
|
F32 minY;
|
|
F32 maxY;
|
|
|
|
F32 minZ;
|
|
F32 maxZ;
|
|
U32 hullStart;
|
|
U32 surfaceStart;
|
|
|
|
U32 planeStart;
|
|
U16 hullCount;
|
|
U16 surfaceCount;
|
|
U32 polyListPlaneStart;
|
|
|
|
U32 polyListPointStart;
|
|
U32 polyListStringStart;
|
|
U16 searchTag;
|
|
bool staticMesh;
|
|
};
|
|
|
|
struct CoordBin
|
|
{
|
|
U32 binStart;
|
|
U32 binCount;
|
|
};
|
|
|
|
struct RenderNode
|
|
{
|
|
bool exterior;
|
|
U16 baseTexIndex;
|
|
U8 lightMapIndex;
|
|
S32 primInfoIndex;
|
|
BaseMatInstance *matInst;
|
|
|
|
RenderNode()
|
|
{
|
|
exterior = true;
|
|
baseTexIndex = 0;
|
|
lightMapIndex = U8(-1);
|
|
primInfoIndex = -1;
|
|
matInst = NULL;
|
|
}
|
|
};
|
|
|
|
|
|
// public because InteriorInstance needs access
|
|
public:
|
|
Vector< PlaneF > mReflectPlanes;
|
|
|
|
protected:
|
|
struct ReflectRenderNode
|
|
{
|
|
bool exterior;
|
|
S32 reflectPlaneIndex;
|
|
S32 primInfoIndex;
|
|
U8 lightMapIndex;
|
|
|
|
BaseMatInstance *matInst;
|
|
|
|
|
|
ReflectRenderNode()
|
|
{
|
|
exterior = true;
|
|
reflectPlaneIndex = -1;
|
|
lightMapIndex = U8(-1);
|
|
primInfoIndex = -1;
|
|
matInst = NULL;
|
|
}
|
|
};
|
|
|
|
|
|
struct ZoneRNList
|
|
{
|
|
Vector<RenderNode> renderNodeList;
|
|
};
|
|
|
|
struct ZoneReflectRNList
|
|
{
|
|
Vector<ReflectRenderNode> reflectList;
|
|
};
|
|
|
|
// needs to be exposed in order for on the fly changes
|
|
public:
|
|
Vector<ZoneRNList> mZoneRNList;
|
|
|
|
private:
|
|
|
|
// reflective plane data
|
|
GFXVertexBufferHandle<GFXVertexPNTTB> mReflectVertBuff;
|
|
GFXPrimitiveBufferHandle mReflectPrimBuff;
|
|
Vector<ZoneReflectRNList> mZoneReflectRNList;
|
|
|
|
// standard interior data
|
|
GFXVertexBufferHandle<GFXVertexPNTTB> mVertBuff;
|
|
GFXPrimitiveBufferHandle mPrimBuff;
|
|
|
|
private:
|
|
LM_HANDLE mLMHandle;
|
|
public:
|
|
LM_HANDLE getLMHandle() {return(mLMHandle);}
|
|
|
|
public:
|
|
|
|
// SceneLighting::InteriorProxy interface
|
|
const Surface & getSurface(const U32 surface) const;
|
|
const U32 getSurfaceCount() const;
|
|
const U32 getNormalLMapIndex(const U32 surface) const;
|
|
const U32 getAlarmLMapIndex(const U32 surface) const;
|
|
const U32 getStaticMeshCount() const;
|
|
const InteriorSimpleMesh *getStaticMesh(const U32 index) const;
|
|
const U32 getWinding(const U32 index) const;
|
|
const Point3F & getPoint(const U32 index) const;
|
|
const TexGenPlanes & getLMTexGenEQ(const U32 index) const;
|
|
const TexGenPlanes & getTexGenEQ(const U32 index) const;
|
|
bool hasAlarmState() const;
|
|
const U32 getWindingCount() const;
|
|
S32 getTargetCount() const;
|
|
const String& getTargetName( S32 mapToNameIndex ) const;
|
|
|
|
//-------------------------------------- Instance Data Members
|
|
private:
|
|
U32 mFileVersion;
|
|
U32 mDetailLevel;
|
|
U32 mMinPixels;
|
|
F32 mAveTexGenLength; // Set in Interior::read after loading the texgen planes.
|
|
Box3F mBoundingBox;
|
|
SphereF mBoundingSphere;
|
|
|
|
Vector<PlaneF> mPlanes;
|
|
Vector<ItrPaddedPoint> mPoints;
|
|
Vector<U8> mPointVisibility;
|
|
|
|
Vector<Point3F> mNormals;
|
|
Vector<TexMatrix> mTexMatrices;
|
|
Vector<U32> mTexMatIndices;
|
|
|
|
ColorF mBaseAmbient;
|
|
ColorF mAlarmAmbient;
|
|
|
|
Vector<IBSPNode> mBSPNodes;
|
|
Vector<IBSPLeafSolid> mBSPSolidLeaves;
|
|
|
|
bool mPreppedForRender;
|
|
|
|
bool mHasTranslucentMaterials;
|
|
|
|
Vector<U32> mWindings;
|
|
|
|
Vector<TexGenPlanes> mTexGenEQs;
|
|
Vector<TexGenPlanes> mLMTexGenEQs;
|
|
|
|
Vector<TriFan> mWindingIndices;
|
|
Vector<Surface> mSurfaces;
|
|
Vector<NullSurface> mNullSurfaces;
|
|
Vector<U32> mSolidLeafSurfaces;
|
|
|
|
Vector<Edge> mEdges;
|
|
|
|
// Portals and zones
|
|
Vector<Zone> mZones;
|
|
Vector<U16> mZonePlanes;
|
|
Vector<U16> mZoneSurfaces;
|
|
Vector<U16> mZonePortalList;
|
|
Vector<Portal> mPortals;
|
|
Vector<U32> mZoneStaticMeshes;
|
|
|
|
// Subobjects: Doors, translucencies, mirrors, etc.
|
|
Vector<InteriorSubObject*> mSubObjects;
|
|
|
|
// Lighting info
|
|
bool mHasAlarmState;
|
|
U32 mNumLightStateEntries;
|
|
|
|
Vector<GBitmap*> mLightmaps;
|
|
Vector<bool> mLightmapKeep;
|
|
Vector<U32> mNormalLMapIndices;
|
|
Vector<U32> mAlarmLMapIndices;
|
|
|
|
U32 mNumTriggerableLights; // Note: not persisted
|
|
|
|
// Persistent animated light structures
|
|
Vector<AnimatedLight> mAnimatedLights;
|
|
Vector<LightState> mLightStates;
|
|
Vector<LightStateData> mStateData;
|
|
Vector<U8> mStateDataBuffer;
|
|
|
|
Vector<char> mNameBuffer;
|
|
|
|
Vector<ConvexHull> mConvexHulls;
|
|
Vector<U8> mConvexHullEmitStrings;
|
|
Vector<U32> mHullIndices;
|
|
Vector<U32> mHullEmitStringIndices;
|
|
Vector<U32> mHullSurfaceIndices;
|
|
Vector<U16> mHullPlaneIndices;
|
|
Vector<U16> mPolyListPlanes;
|
|
Vector<U32> mPolyListPoints;
|
|
Vector<U8> mPolyListStrings;
|
|
CoordBin mCoordBins[NumCoordBins * NumCoordBins];
|
|
Vector<U16> mCoordBinIndices;
|
|
U32 mCoordBinMode;
|
|
|
|
Vector<ConvexHull> mVehicleConvexHulls;
|
|
Vector<U8> mVehicleConvexHullEmitStrings;
|
|
Vector<U32> mVehicleHullIndices;
|
|
Vector<U32> mVehicleHullEmitStringIndices;
|
|
Vector<U32> mVehicleHullSurfaceIndices;
|
|
Vector<U16> mVehicleHullPlaneIndices;
|
|
Vector<U16> mVehiclePolyListPlanes;
|
|
Vector<U32> mVehiclePolyListPoints;
|
|
Vector<U8> mVehiclePolyListStrings;
|
|
Vector<ItrPaddedPoint> mVehiclePoints;
|
|
Vector<NullSurface> mVehicleNullSurfaces;
|
|
Vector<PlaneF> mVehiclePlanes;
|
|
Vector<U32> mVehicleWindings;
|
|
Vector<TriFan> mVehicleWindingIndices;
|
|
|
|
VectorPtr<InteriorSimpleMesh*> mStaticMeshes;
|
|
|
|
U16 mSearchTag;
|
|
Vector<BaseMatInstance*> mMatInstCleanupList;
|
|
|
|
//-------------------------------------- Private interface
|
|
private:
|
|
|
|
#ifndef TORQUE_SHIPPING
|
|
GFXShaderRef mDebugShader;
|
|
GFXTexHandle mDebugTexture;
|
|
|
|
GFXStateBlockRef mInteriorDebugNoneSB;
|
|
GFXStateBlockRef mInteriorDebugPortalSB;
|
|
GFXStateBlockRef mInteriorDebugTextureSB;
|
|
GFXStateBlockRef mInteriorDebugTwoTextureSB;
|
|
|
|
// Debug Render ConstantBuffers
|
|
GFXShaderConstBufferRef mDebugShaderConsts;
|
|
|
|
GFXShaderConstHandle* mDebugShaderModelViewSC;
|
|
GFXShaderConstHandle* mDebugShaderShadeColorSC;
|
|
#endif
|
|
|
|
const char* getName(const U32 nameIndex) const;
|
|
static const char* getLightTypeString(const LightType);
|
|
S32 getZoneForPoint(const Point3F&) const;
|
|
|
|
#ifndef TORQUE_SHIPPING
|
|
void debugRender(const ZoneVisDeterminer& zoneVis, SceneData &sgData, InteriorInstance *intInst, MatrixF& modelview);
|
|
// render debug utility functions
|
|
void preDebugRender();
|
|
void debugDefaultRender(const ZoneVisDeterminer& zoneVis, SceneData &sgData, InteriorInstance *intInst);
|
|
// show all surfaces with flag set as color c
|
|
void debugShowSurfaceFlag(const ZoneVisDeterminer& zoneVis, const U32 flag, const ColorF& c);
|
|
// render brushes
|
|
void debugNormalRenderLines(const ZoneVisDeterminer& zoneVis);
|
|
// next 4 use debugShowSurfaceFlag to show surface info
|
|
void debugShowDetail(const ZoneVisDeterminer& zoneVis);
|
|
void debugShowAmbiguous(const ZoneVisDeterminer& zoneVis);
|
|
void debugShowOrphan(const ZoneVisDeterminer& zoneVis);
|
|
void debugShowOutsideVisible(const ZoneVisDeterminer& zoneVis);
|
|
void debugShowPortalZones(const ZoneVisDeterminer& zoneVis);
|
|
void debugRenderPortals();
|
|
void debugShowCollisionFans(const ZoneVisDeterminer& zoneVis);
|
|
void debugShowStrips(const ZoneVisDeterminer& zoneVis);
|
|
void debugShowDetailLevel(const ZoneVisDeterminer& zoneVis);
|
|
void debugShowHullSurfaces();
|
|
void debugShowNullSurfaces(const ZoneVisDeterminer& zoneVis, SceneData &sgData, InteriorInstance *intInst);
|
|
void debugShowVehicleHullSurfaces(const ZoneVisDeterminer& zoneVis, SceneData &sgData, InteriorInstance *intInst);
|
|
void debugShowTexturesOnly(const ZoneVisDeterminer& zoneVis, SceneData &sgData, InteriorInstance *intInst);
|
|
void debugShowLightmaps(const ZoneVisDeterminer& zoneVis, SceneData &sgData, InteriorInstance *intInst);
|
|
void debugShowLargeTextures(const ZoneVisDeterminer& zoneVis, SceneData &sgData, InteriorInstance *intInst);
|
|
// void debugShowVertexColors(MaterialList* pMaterials);
|
|
#endif
|
|
|
|
public:
|
|
void collisionFanFromSurface(const Surface&, U32* fan, U32* numIndices) const;
|
|
void fillSurfaceTexMats();
|
|
void createZoneVBs();
|
|
void cloneMatInstances();
|
|
void initMatInstances();
|
|
void createReflectPlanes();
|
|
|
|
private:
|
|
void fullWindingFromSurface(const Surface&, U32* fan, U32* numIndices) const;
|
|
bool projectClipAndBoundFan(U32 fanIndex, F64* pResult);
|
|
void zoneTraversal(S32 baseZone, const bool flipClipPlanes);
|
|
void createZoneRectVectors();
|
|
void destroyZoneRectVectors();
|
|
void traverseZone(const RectD* inRects, const U32 numInputRects, U32 currZone, Vector<U32>& zoneStack);
|
|
|
|
void fillVertex( GFXVertexPNTTB &vert, Surface &surface, U32 surfaceIndex );
|
|
void getTexMat(U32 surfaceIndex, U32 pointOffset, Point3F& T, Point3F& N, Point3F& B);
|
|
|
|
|
|
void storeRenderNode( RenderNode &node,
|
|
ZoneRNList &RNList,
|
|
Vector<GFXPrimitive> &primInfoList,
|
|
Vector<U16> &indexList,
|
|
Vector<GFXVertexPNTTB> &verts,
|
|
U32 &startIndex,
|
|
U32 &startVert );
|
|
|
|
void renderZoneNode( SceneRenderState *state,
|
|
RenderNode &node,
|
|
InteriorInstance *intInst,
|
|
SceneData &sgData,
|
|
MeshRenderInst *coreRi );
|
|
|
|
void renderReflectNode( SceneRenderState *state,
|
|
ReflectRenderNode &node,
|
|
InteriorInstance *intInst,
|
|
SceneData &sgData,
|
|
MeshRenderInst *coreRi );
|
|
|
|
void renderLights(SceneRenderState* state, InteriorInstance *intInst, SceneData &sgData, MeshRenderInst *coreRi, const ZoneVisDeterminer &zonevis);
|
|
|
|
|
|
/// Used to maintain point and normal relationship (which use
|
|
/// dissimilar index lookups) for verts when building vertex buffer.
|
|
struct VertexBufferTempIndex
|
|
{
|
|
U16 index;
|
|
Point3F normal;
|
|
|
|
VertexBufferTempIndex()
|
|
{
|
|
index = 0;
|
|
normal.set(0.0f, 0.0f, 0.0f);
|
|
}
|
|
VertexBufferTempIndex(const U16 ind, const Point3F &norm)
|
|
{
|
|
index = ind;
|
|
normal = norm;
|
|
}
|
|
};
|
|
|
|
void storeSurfVerts( Vector<U16> &masterIndexList,
|
|
Vector<VertexBufferTempIndex> &tempIndexList,
|
|
Vector<GFXVertexPNTTB> &verts,
|
|
U32 numIndices,
|
|
Surface &surface,
|
|
U32 surfaceIndex );
|
|
|
|
public:
|
|
void purgeLODData();
|
|
|
|
void buildExportPolyList(OptimizedPolyList& polys, MatrixF* mat = NULL, Point3F* scale = NULL);
|
|
};
|
|
|
|
//------------------------------------------------------------------------------
|
|
inline bool Interior::isBSPLeafIndex(U32 index) const
|
|
{
|
|
if (mFileVersion >= 14)
|
|
return (index & 0x80000) != 0;
|
|
else
|
|
return (index & 0x8000) != 0;
|
|
}
|
|
|
|
inline bool Interior::isBSPSolidLeaf(U32 index) const
|
|
{
|
|
AssertFatal(isBSPLeafIndex(index) == true, "Error, only call for leaves!");
|
|
|
|
if (mFileVersion >= 14)
|
|
return (index & 0x40000) != 0;
|
|
else
|
|
return (index & 0x4000) != 0;
|
|
}
|
|
|
|
inline bool Interior::isBSPEmptyLeaf(U32 index) const
|
|
{
|
|
AssertFatal(isBSPLeafIndex(index) == true, "Error, only call for leaves!");
|
|
|
|
if (mFileVersion >= 14)
|
|
return (index & 0x40000) == 0;
|
|
else
|
|
return (index & 0x4000) == 0;
|
|
}
|
|
|
|
inline U16 Interior::getBSPSolidLeafIndex(U32 index) const
|
|
{
|
|
AssertFatal(isBSPSolidLeaf(index) == true, "Error, only call for leaves!");
|
|
|
|
if (mFileVersion >= 14)
|
|
return U16(index & ~0xC0000);
|
|
else
|
|
return U16(index & ~0xC000);
|
|
}
|
|
|
|
inline U16 Interior::getBSPEmptyLeafZone(U32 index) const
|
|
{
|
|
AssertFatal(isBSPEmptyLeaf(index) == true, "Error, only call for leaves!");
|
|
|
|
if (mFileVersion >= 14)
|
|
return U16(index & ~0xC0000);
|
|
else
|
|
return U16(index & ~0xC000);
|
|
}
|
|
|
|
inline const PlaneF& Interior::getPlane(U16 index) const
|
|
{
|
|
AssertFatal(U32(index & ~0x8000) < mPlanes.size(),
|
|
"Interior::getPlane: planeIndex out of range");
|
|
|
|
return mPlanes[index & ~0x8000];
|
|
}
|
|
|
|
inline PlaneF Interior::getFlippedPlane(const U16 index) const
|
|
{
|
|
PlaneF plane = getPlane(index);
|
|
if(Interior::planeIsFlipped(index))
|
|
plane.neg();
|
|
|
|
return plane;
|
|
}
|
|
|
|
inline U16 Interior::getPlaneIndex(U16 index)
|
|
{
|
|
return U16(index & ~0x8000);
|
|
}
|
|
|
|
inline bool Interior::planeIsFlipped(U16 index)
|
|
{
|
|
return (index >> 15)!=0;
|
|
}
|
|
|
|
inline bool Interior::areEqualPlanes(U16 o, U16 t) const
|
|
{
|
|
return (o & ~0x8000) == (t & ~0x8000);
|
|
}
|
|
|
|
inline const Point3F Interior::getPointNormal(const U32 surfaceIndex, const U32 pointOffset) const
|
|
{
|
|
Surface rSurface = mSurfaces[surfaceIndex];
|
|
|
|
Point3F normal(0.0f, 0.0f, 0.0f);
|
|
|
|
if (mFileVersion >= 11)
|
|
{
|
|
U32 texMatIndex = mTexMatIndices[rSurface.windingStart + pointOffset];
|
|
TexMatrix texMat = mTexMatrices[texMatIndex];
|
|
|
|
if (texMat.N > -1)
|
|
normal = mNormals[texMat.N];
|
|
}
|
|
else
|
|
normal = getFlippedPlane(rSurface.planeIndex);
|
|
|
|
return normal;
|
|
}
|
|
|
|
inline U32 Interior::getDetailLevel() const
|
|
{
|
|
return mDetailLevel;
|
|
}
|
|
|
|
inline U32 Interior::getMinPixels() const
|
|
{
|
|
return mMinPixels;
|
|
}
|
|
|
|
inline const Box3F& Interior::getBoundingBox() const
|
|
{
|
|
return mBoundingBox;
|
|
}
|
|
|
|
inline S32 Interior::getNumZones() const
|
|
{
|
|
return mZones.size();
|
|
}
|
|
|
|
inline bool Interior::isNullSurfaceIndex(const U32 index) const
|
|
{
|
|
return (index & 0x80000000) != 0;
|
|
}
|
|
|
|
inline bool Interior::isVehicleNullSurfaceIndex(const U32 index) const
|
|
{
|
|
return (index & 0x40000000) != 0;
|
|
}
|
|
|
|
inline U32 Interior::getNullSurfaceIndex(const U32 index) const
|
|
{
|
|
AssertFatal(isNullSurfaceIndex(index), "Not a proper index!");
|
|
AssertFatal(!isVehicleNullSurfaceIndex(index), "Not a proper index");
|
|
return (index & ~0x80000000);
|
|
}
|
|
|
|
inline U32 Interior::getVehicleNullSurfaceIndex(const U32 index) const
|
|
{
|
|
AssertFatal(isVehicleNullSurfaceIndex(index), "Not a proper index!");
|
|
return (index & ~(0x80000000 | 0x40000000));
|
|
}
|
|
|
|
inline const char* Interior::getLightTypeString(const LightType type)
|
|
{
|
|
switch (type) {
|
|
case AmbientLooping:
|
|
return "AmbientLooping";
|
|
case AmbientFlicker:
|
|
return "AmbientFlicker";
|
|
case TriggerableLoop:
|
|
return "TriggerableLoop";
|
|
case TriggerableFlicker:
|
|
return "TriggerableFlicker";
|
|
case TriggerableRamp:
|
|
return "TriggerableRamp";
|
|
|
|
default:
|
|
return "<UNKNOWN>";
|
|
}
|
|
}
|
|
|
|
inline const char* Interior::getName(const U32 nameIndex) const
|
|
{
|
|
return &mNameBuffer[nameIndex];
|
|
}
|
|
|
|
inline const U32 Interior::getSurfaceCount() const
|
|
{
|
|
return(mSurfaces.size());
|
|
}
|
|
|
|
inline const Interior::Surface & Interior::getSurface(const U32 surface) const
|
|
{
|
|
AssertFatal(surface < mSurfaces.size(), "invalid index");
|
|
return(mSurfaces[surface]);
|
|
}
|
|
|
|
inline const U32 Interior::getStaticMeshCount() const
|
|
{
|
|
return mStaticMeshes.size();
|
|
}
|
|
|
|
inline const InteriorSimpleMesh *Interior::getStaticMesh(const U32 index) const
|
|
{
|
|
AssertFatal(index < mStaticMeshes.size(), "invalid index");
|
|
return mStaticMeshes[index];
|
|
}
|
|
|
|
inline const U32 Interior::getNormalLMapIndex(const U32 surface) const
|
|
{
|
|
AssertFatal(surface < mNormalLMapIndices.size(), "invalid index");
|
|
return(mNormalLMapIndices[surface]);
|
|
}
|
|
|
|
inline const U32 Interior::getAlarmLMapIndex(const U32 surface) const
|
|
{
|
|
AssertFatal(surface < mAlarmLMapIndices.size(), "invalid index");
|
|
return(mAlarmLMapIndices[surface]);
|
|
}
|
|
|
|
inline const U32 Interior::getWinding(const U32 index) const
|
|
{
|
|
AssertFatal(index < mWindings.size(), "invalid index");
|
|
return(mWindings[index]);
|
|
}
|
|
|
|
inline const Point3F & Interior::getPoint(const U32 index) const
|
|
{
|
|
AssertFatal(index < mPoints.size(), "invalid index");
|
|
return(mPoints[index].point);
|
|
}
|
|
|
|
inline const Interior::TexGenPlanes & Interior::getLMTexGenEQ(const U32 index) const
|
|
{
|
|
AssertFatal(index < mLMTexGenEQs.size(), "invalid index");
|
|
return(mLMTexGenEQs[index]);
|
|
}
|
|
|
|
inline const Interior::TexGenPlanes & Interior::getTexGenEQ(const U32 index) const
|
|
{
|
|
AssertFatal(index < mTexGenEQs.size(), "invalid index");
|
|
return(mTexGenEQs[index]);
|
|
}
|
|
|
|
inline bool Interior::hasAlarmState() const
|
|
{
|
|
return(mHasAlarmState);
|
|
}
|
|
|
|
inline const bool Interior::isSurfaceOutsideVisible(U32 surface) const
|
|
{
|
|
AssertFatal(surface < mSurfaces.size(), "Interior::isSurfaceOutsideVisible: Invalid surface index");
|
|
return ((mSurfaces[surface].surfaceFlags & SurfaceOutsideVisible)!=0);
|
|
}
|
|
|
|
inline const U32 Interior::getWindingCount() const
|
|
{
|
|
return(mWindings.size());
|
|
}
|
|
|
|
#endif //_INTERIOR_H_
|