//----------------------------------------------------------------------------- // Torque Game Engine // Copyright (C) GarageGames.com, Inc. //----------------------------------------------------------------------------- #ifndef _INTERIOR_H_ #define _INTERIOR_H_ //Includes #ifndef _PLATFORM_H_ #include "platform/platform.h" #endif #ifndef _COLOR_H_ #include "core/color.h" #endif #ifndef _COLLISION_H_ #include "collision/collision.h" #endif #ifndef _RESMANAGER_H_ #include "core/resManager.h" #endif #ifndef _TVECTOR_H_ #include "core/tVector.h" #endif #ifndef _MPOINT_H_ #include "math/mPoint.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 _CONSTRUCTORSIMPLEMESH_H_ #include "constructor/constructorSimpleMesh.h" #endif #include "lightingSystem/sgDetailMapping.h" //-------------------------------------- Forward declarations class Stream; class EditGeometry; class InteriorInstance; class GBitmap; class TextureHandle; class RectD; class SphereF; class MatrixF; class SceneState; class MaterialList; class AbstractPolyList; class InteriorSubObject; class TranslucentSubObject; class BitVector; struct RayInfo; struct EdgeList; class SurfaceHash; class InteriorPolytope; class FloorPlan; class LightInfo; class PlaneRange; class EditInteriorResource; //-------------------------------------------------------------------------- class InteriorConvex : public Convex { typedef Convex Parent; friend class Interior; friend class InteriorInstance; protected: Interior* pInterior; public: S32 hullId; Box3F box; 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; SceneState* mState; U32 mZoneRangeOffset; U32 mParentZone; public: ZoneVisDeterminer() : mMode(FromRects), mState(NULL) { } void runFromState(SceneState*, U32, U32); void runFromRects(SceneState*, 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 FloorPlan; friend class EditGeometry; friend class InteriorInstance; friend class SceneLighting; friend class InteriorProxy; friend class TranslucentSubObject; friend class MirrorSubObject; friend class InteriorConvex; friend class InteriorLMManager; friend class EditInteriorResource; public: Interior(); ~Interior(); // Support for interior light map border sizes. private: U32 mLightMapBorderSize; public: sgDetailMapping detailMapping; U32 getLightMapBorderSize() const {return mLightMapBorderSize;} void setLightMapBorderSize(U32 value) {mLightMapBorderSize = value;} void buildSurfaceZones(); //void sgSetupLighting(InteriorInstance *intInst, SceneGraphData &sgData); //bool sgRenderLights(InteriorInstance *intInst, SceneGraphData &sgData); // Misc U32 getDetailLevel() const; U32 getMinPixels() const; const Box3F& getBoundingBox() const; S32 getNumZones() const; // Rendering bool prepForRendering(const char* path); void rebuildVertexColors(LM_HANDLE instanceHandle, Vector<ColorI>* normal, Vector<ColorI>* alarm); bool prepRender(SceneState* state, S32 containingZone, S32 baseZone, U32 zoneOffset, const MatrixF& OSToWS, const Point3F& objScale, const bool modifyBaseState, const bool dontRestrictOutside, const bool flipClipPlanes); void prepTempRender(SceneState* state, S32 containingZone, S32 baseZone, const MatrixF& OSToWS, const Point3F& objScale, const bool flipClipPlanes); void render(const bool useAlarmLighting, MaterialList* pMaterials, const LM_HANDLE instanceHandle, const Vector<ColorI>* normalVLights, const Vector<ColorI>* alarmVLights); void render_vc_tf(const bool useAlarmLighting, MaterialList* pMaterials, const LM_HANDLE instanceHandle, const Vector<ColorI>* normalVLights, const Vector<ColorI>* alarmVLights); void render_vc_fc(const bool useAlarmLighting, MaterialList* pMaterials, const LM_HANDLE instanceHandle, const Vector<ColorI>* normalVLights, const Vector<ColorI>* alarmVLights); void renderARB_vc_tf(const bool useAlarmLighting, MaterialList* pMaterials, const LM_HANDLE instanceHandle, const Vector<ColorI>* normalVLights, const Vector<ColorI>* alarmVLights); void renderARB(const bool useAlarmLighting, MaterialList* pMaterials, const LM_HANDLE instanceHandle); void renderARB_FC(const bool useAlarmLighting, MaterialList* pMaterials, const LM_HANDLE instanceHandle); void renderLights(LightInfo* pInfo, const MatrixF& transform, const Point3F& scale, Vector<U32> surfaces); void renderAsShape(); void renderStaticMeshes(bool texture, bool lightmap, LM_HANDLE instancelmhandle); bool useFogCoord(); bool scopeZones(const S32 baseZone, const Point3F& interiorRoot, bool* interiorScopingState); //-------------------------------------- Collision Interface and zone scans 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 buildLightPolyList(U32* lightSurfaces, U32* numLightSurfaces, 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 U16, const U16, const Point3F&, const Point3F&, RayInfo*); void buildPolyList_r(InteriorPolytope& polytope, SurfaceHash& hash); void scanZone_r(const U16 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); void scopeZone(const U32 currZone, bool* interiorScopingState, const Point3F& interiorRoot, Vector<U32>& zoneStack, Vector<PlaneF>& planeStack, Vector<PlaneRange>& planeRangeStack); //-------------------------------------- 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 smRenderEnvironmentMaps; static bool smUseVertexLighting; static bool smUseTexturedFog; static bool smLockArrays; static U32 smFileVersion; static bool smLightingCastRays; //-------------------------------------- Persistence interface bool read(Stream& stream); bool write(Stream& stream) const; bool readVehicleCollision(Stream& stream); bool writeVehicleCollision(Stream& stream) const; protected: 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 protected: struct IBSPNode { U16 planeIndex; U16 frontIndex; U16 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(U16 index) const; bool isBSPSolidLeaf(U16 index) const; bool isBSPEmptyLeaf(U16 index) const; U16 getBSPSolidLeafIndex(U16 index) const; U16 getBSPEmptyLeafZone(U16 index) const; void setupAveTexGenLength(); void truncateZoneTree(); void truncateZoneNode(const U16); bool getUnifiedZone(const U16, S32*); public: static U16 getPlaneIndex(const U16 index); static bool planeIsFlipped(const U16 index); const PlaneF& getPlane(const U16 index) const; PlaneF getFlippedPlane(const U16 index) const; const Point3F getPointNormal(const U32 surfaceIndex, const U32 pointOffset) const; protected: 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 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; struct TexMatrix { S32 T; S32 N; S32 B; TexMatrix::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; 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 }; 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) }; protected: 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; }; protected: LM_HANDLE mLMHandle; public: LM_HANDLE getLMHandle() {return(mLMHandle);} // 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 ConstructorSimpleMesh *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; bool hasAlarmState() const; const U32 getWindingCount() const; //-------------------------------------- Instance Data Members protected: 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; MaterialList* mMaterialList; TextureHandle* mWhite; TextureHandle* mWhiteRGB; TextureHandle* mLightFalloff; Vector<TextureHandle*> mEnvironMaps; Vector<F32> mEnvironFactors; U32 mValidEnvironMaps; 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; Vector<S32> mSurfaceZone; // Subobjects: Doors, translucencies, mirrors, etc. Vector<InteriorSubObject*> mSubObjects; // Lighting info bool mHasAlarmState; U32 mNumLightStateEntries; //Vector<TextureHandle> mLightDirMapsTex; Vector<GBitmap*> mLightDirMaps; 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<ConstructorSimpleMesh*> mStaticMeshes; // Some data used only by Constructor during export Vector<U32> mBspNodeList; U16 mSearchTag; //-------------------------------------- Private interface protected: const char* getName(const U32 nameIndex) const; static const char* getLightTypeString(const LightType); S32 getZoneForPoint(const Point3F&) const; void debugRender(MaterialList* pMaterials, LM_HANDLE instanceHandle); void debugRenderPortals(); void debugNormalRenderLines(); void debugShowDetail(); void debugShowAmbiguous(); void debugShowLightmaps(LM_HANDLE instanceHandle); void debugShowPortalZones(); void debugShowCollisionFans(); void debugShowOrphan(); void debugShowStrips(); void debugShowTexturesOnly(MaterialList* pMaterials); void debugShowLargeTextures(MaterialList* pMaterials); void debugShowNullSurfaces(MaterialList* pMaterials); void debugShowOutsideVisible(); void debugShowHullSurfaces(); void debugShowVehicleHullSurfaces(MaterialList* pMaterials); // void debugShowVertexColors(MaterialList* pMaterials); void debugShowDetailLevel(); void debugShowOrphansFinish(); public: void collisionFanFromSurface(const Surface&, U32* fan, U32* numIndices) const; 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 doFogActive( const bool environmentActive, const SceneState* state, const U32 mergeArrayCount, const U16* mergeArray, const PlaneF &distPlane, const F32 distOffset, const Point3F &worldP, const Point3F &osZVec, const F32 worldZ ); void setupActivePolyList(ZoneVisDeterminer&, SceneState*, const Point3F&, const Point3F& rViewVector, const Point3F&, const F32 worldz, const Point3F& scale); void setupFog(SceneState* state); void clearFog(); void setOSCamPosition(const Point3F&); public: void purgeLODData(); }; //------------------------------------------------------------------------------ inline bool Interior::isBSPLeafIndex(U16 index) const { return (index & 0x8000) != 0; } inline bool Interior::isBSPSolidLeaf(U16 index) const { AssertFatal(isBSPLeafIndex(index) == true, "Error, only call for leaves!"); return (index & 0x4000) != 0; } inline bool Interior::isBSPEmptyLeaf(U16 index) const { AssertFatal(isBSPLeafIndex(index) == true, "Error, only call for leaves!"); return (index & 0x4000) == 0; } inline U16 Interior::getBSPSolidLeafIndex(U16 index) const { AssertFatal(isBSPSolidLeaf(index) == true, "Error, only call for leaves!"); return U16(index & ~0xC000); } inline U16 Interior::getBSPEmptyLeafZone(U16 index) const { AssertFatal(isBSPEmptyLeaf(index) == true, "Error, only call for leaves!"); return U16(index & ~0xC000); } inline const PlaneF& Interior::getPlane(const 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(const U16 index) { return U16(index & ~0x8000); } inline bool Interior::planeIsFlipped(const 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 = getPlane(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 ConstructorSimpleMesh *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 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_