594 lines
16 KiB
C++
594 lines
16 KiB
C++
//-----------------------------------------------------------------------------
|
|
// Torque Game Engine
|
|
// Copyright (C) GarageGames.com, Inc.
|
|
//-----------------------------------------------------------------------------
|
|
|
|
#ifndef _EDITGEOMETRY_H_
|
|
#define _EDITGEOMETRY_H_
|
|
|
|
//Includes
|
|
#ifndef _PLATFORM_H_
|
|
#include "platform/platform.h"
|
|
#endif
|
|
#ifndef _PLATFORMASSERT_H_
|
|
#include "platform/platformAssert.h"
|
|
#endif
|
|
#ifndef _MORIANBASICS_H_
|
|
#include "map2dif plus/morianBasics.h"
|
|
#endif
|
|
#ifndef _MORIANUTIL_H_
|
|
#include "map2dif plus/morianUtil.h"
|
|
#endif
|
|
#ifndef _BSPNODE_H_
|
|
#include "map2dif plus/bspNode.h"
|
|
#endif
|
|
#ifndef _MPLANE_H_
|
|
#include "math/mPlane.h"
|
|
#endif
|
|
#ifndef _COLOR_H_
|
|
#include "core/color.h"
|
|
#endif
|
|
#ifndef _EDITFLOORPLANRES_H_
|
|
#include "map2dif plus/editFloorPlanRes.h"
|
|
#endif
|
|
|
|
#include "interior/interiorMap.h"
|
|
|
|
#include "interior/interiorResObjects.h"
|
|
|
|
class Tokenizer;
|
|
class Interior;
|
|
class CSGBrush;
|
|
class GBitmap;
|
|
class CSGPlane;
|
|
class WorldSpawnEntity;
|
|
class MirrorSurfaceEntity;
|
|
class TriggerEntity;
|
|
class DoorEntity;
|
|
class ForceFieldEntity;
|
|
class PathStartEntity;
|
|
class SpecialNodeEntity;
|
|
class GameEntity;
|
|
class InteriorResource;
|
|
struct TempHullReference;
|
|
|
|
//------------------------------------------------------------------------------
|
|
class EditGeometry
|
|
{
|
|
friend class EditBSPNode;
|
|
friend class Lighting;
|
|
friend void parseBrushList(Vector<CSGBrush*>& Brushes, Tokenizer* pToker);
|
|
|
|
//-------------------------------------- first class structures
|
|
public:
|
|
struct Portal {
|
|
U32 portalId;
|
|
S32 planeEQIndex;
|
|
S32 frontZone;
|
|
S32 backZone;
|
|
bool passAmbientLight;
|
|
|
|
Vector<Winding> windings;
|
|
|
|
Point3D mMin;
|
|
Point3D mMax;
|
|
|
|
Point3D x;
|
|
Point3D y;
|
|
};
|
|
struct Zone {
|
|
U32 zoneId;
|
|
bool active;
|
|
|
|
bool ambientLit;
|
|
|
|
Vector<U32> referencingPortals;
|
|
};
|
|
struct Surface {
|
|
bool isMemberOfZone(U32);
|
|
|
|
U32 uniqueKey;
|
|
U32 planeIndex;
|
|
U32 textureIndex;
|
|
|
|
Winding winding;
|
|
Winding originalWinding;
|
|
|
|
U32 texGenIndex;
|
|
|
|
U32 lMapDimX;
|
|
U32 lMapDimY;
|
|
U32 offsetX;
|
|
U32 offsetY;
|
|
|
|
bool lmapTexGenSwapped;
|
|
F32 lmapTexGenX[4];
|
|
F32 lmapTexGenY[4];
|
|
F32 tempScale[2];
|
|
|
|
GBitmap* pLMap;
|
|
|
|
GBitmap* pNormalLMap;
|
|
GBitmap* pAlarmLMap;
|
|
U32 sheetIndex;
|
|
U32 alarmSheetIndex;
|
|
|
|
U32 flags;
|
|
U32 fanMask;
|
|
|
|
U32 numLights;
|
|
U32 stateDataStart;
|
|
|
|
bool mustPortalExtend;
|
|
U32 temptemptemp;
|
|
};
|
|
struct NullSurface {
|
|
U32 planeIndex;
|
|
Winding winding;
|
|
U32 flags;
|
|
};
|
|
|
|
class Entity {
|
|
public:
|
|
Entity() { }
|
|
virtual ~Entity() { };
|
|
InteriorDict mDictionary;
|
|
|
|
virtual bool parseEntityDescription(InteriorMapResource::Entity* ent) = 0;
|
|
virtual BrushType getBrushType() = 0;
|
|
|
|
virtual bool isPointClass() const = 0;
|
|
virtual const char* getName() const = 0;
|
|
virtual const Point3D& getOrigin() const = 0;
|
|
|
|
virtual void grabSurface(Surface&) { }
|
|
};
|
|
|
|
struct PlaneHashEntry {
|
|
U32 planeIndex;
|
|
PlaneHashEntry* pNext;
|
|
};
|
|
struct PointHashEntry {
|
|
U32 pointIndex;
|
|
PointHashEntry* pNext;
|
|
};
|
|
struct TexGenPlanes {
|
|
PlaneF planeX;
|
|
PlaneF planeY;
|
|
};
|
|
|
|
|
|
//-------------------------------------- animated lighting structures
|
|
public:
|
|
struct StateData {
|
|
GBitmap* pLMap; // 8-Bit intensity map
|
|
U32 surfaceIndex; // Surface affected by this state
|
|
|
|
U32 stateDataIndex; // index
|
|
};
|
|
struct LightState {
|
|
ColorI color;
|
|
F32 duration;
|
|
Vector<StateData> stateData;
|
|
};
|
|
struct AnimatedLight {
|
|
char* name;
|
|
U32 type; // From Interior::LightType
|
|
bool alarm; // entity->mAlarmStatus != NormalOnly
|
|
|
|
Vector<LightState*> states;
|
|
|
|
AnimatedLight() : name(NULL), type(0) { }
|
|
};
|
|
|
|
Vector<AnimatedLight*> mAnimatedLights;
|
|
|
|
//-------------------------------------- arenas
|
|
public:
|
|
class PlaneHashArena {
|
|
Vector<PlaneHashEntry*> mBuffers;
|
|
|
|
U32 arenaSize;
|
|
PlaneHashEntry* currBuffer;
|
|
U32 currPosition;
|
|
|
|
public:
|
|
PlaneHashArena(U32 _arenaSize);
|
|
~PlaneHashArena();
|
|
|
|
PlaneHashEntry* allocateEntry();
|
|
};
|
|
class PointHashArena {
|
|
Vector<PointHashEntry*> mBuffers;
|
|
|
|
U32 arenaSize;
|
|
PointHashEntry* currBuffer;
|
|
U32 currPosition;
|
|
|
|
public:
|
|
PointHashArena(U32 _arenaSize);
|
|
~PointHashArena();
|
|
|
|
PointHashEntry* allocateEntry();
|
|
};
|
|
|
|
//------------------------------------------------------------------------------
|
|
//-------------------------------------- DATA
|
|
private:
|
|
//-------------------------------------- Error variables
|
|
U32 mNumAmbiguousBrushes;
|
|
U32 mNumOrphanPolys;
|
|
|
|
//-------------------------------------- Brushes and texture vars
|
|
public:
|
|
Point3D mMinBound;
|
|
Point3D mMaxBound;
|
|
|
|
public:
|
|
U32 mCurrBrushId;
|
|
U32 mSurfaceKey;
|
|
Vector<CSGBrush*> mStructuralBrushes;
|
|
Vector<CSGBrush*> mDetailBrushes;
|
|
|
|
Vector<CSGBrush*> mSpecialCollisionBrushes;
|
|
|
|
Vector<CSGBrush*> mVehicleCollisionBrushes;
|
|
Vector<NullSurface> mVehicleNullSurfaces;
|
|
|
|
Vector<CSGBrush*> mPortalBrushes;
|
|
Vector<Entity*> mPortalEntities;
|
|
|
|
Vector<char*> mTextureNames;
|
|
Vector<GBitmap*> mTextures;
|
|
|
|
Vector<Portal*> mPortals;
|
|
Vector<Zone*> mZones;
|
|
U32 mOutsideZoneIndex;
|
|
|
|
Vector<TexGenPlanes> mTexGenEQs;
|
|
Vector<Surface> mSurfaces;
|
|
Vector<NullSurface> mNullSurfaces;
|
|
Vector<GBitmap*> mLightmaps;
|
|
bool mHasAlarmState;
|
|
|
|
//-------------------------------------- Nav Graph Generation
|
|
bool mPerformExtrusion;
|
|
bool mGenerateGraph;
|
|
bool mHashPlanes, mHashPoints;
|
|
UniqueVector mGraphSurfacePts;
|
|
EditFloorPlanResource mEditFloorPlanRes;
|
|
|
|
//-------------------------------------- Planes and Points
|
|
PlaneHashEntry mPlaneHashTable[1 << 12];
|
|
Vector<PlaneEQ> mPlaneEQs;
|
|
|
|
Vector<S32> mPlaneRemaps;
|
|
U16 remapPlaneIndex(S32 inPlaneIndex);
|
|
U16 remapVehiclePlaneIndex(S32 inPlaneIndex, Interior*);
|
|
|
|
PointHashEntry mPointHashTable[1 << 12];
|
|
Vector<Point3D> mPoints;
|
|
|
|
struct ExportPointMapEntry {
|
|
U32 originalIndex;
|
|
U32 runtimeIndex;
|
|
};
|
|
Vector<ExportPointMapEntry> mExportPointMap;
|
|
Vector<ExportPointMapEntry> mVehicleExportPointMap;
|
|
|
|
public:
|
|
PlaneHashArena mPlaneHashArena;
|
|
PointHashArena mPointHashArena;
|
|
|
|
//-------------------------------------- BSP info
|
|
public:
|
|
NodeArena mNodeArena;
|
|
VisLinkArena mVisLinkArena;
|
|
|
|
private:
|
|
EditBSPNode* mBSPRoot;
|
|
|
|
//-------------------------------------- Entity information
|
|
public:
|
|
WorldSpawnEntity* mWorldEntity;
|
|
Vector<Entity*> mEntities;
|
|
|
|
//------------------------------------------------------------------------------
|
|
//-------------------------------------- FUNCTIONS
|
|
private:
|
|
Entity* parseEntity(Tokenizer* pToker);
|
|
const Entity* getNamedEntity(const char*) const;
|
|
|
|
public:
|
|
const char* insertTexture(const char*);
|
|
|
|
void fixSparkles();
|
|
void convertToStrips();
|
|
void markSurfaceOriginalPoints();
|
|
void sortSurfaces();
|
|
void sortLitSurfaces();
|
|
|
|
private:
|
|
void createBrushPolys();
|
|
void buildBSP();
|
|
void findOutsideZone();
|
|
void enterPortalZoneRefs();
|
|
void ambientVisitZone(const U32 zone);
|
|
void floodAmbientLight();
|
|
|
|
public:
|
|
void preprocessLighting();
|
|
private:
|
|
void postProcessLighting(Interior*);
|
|
U32 exportIntensityMap(Interior* pRuntime, GBitmap*);
|
|
void exportLightsToRuntime(Interior* pRuntime);
|
|
void exportDMLToRuntime(Interior* pRuntime, Vector<char*>&);
|
|
U16 exportBSPToRuntime(Interior* pRuntime, EditBSPNode* pNode);
|
|
void exportWindingToRuntime(Interior* pRuntime, const Winding& rWinding);
|
|
void exportVehicleWindingToRuntime(Interior* pRuntime, const Winding& rWinding);
|
|
U32 exportPointToRuntime(Interior* pRuntime, const U32 pointIndex);
|
|
void exportHullToRuntime(Interior* pRuntime, CSGBrush* pBrush);
|
|
U32 exportVehiclePointToRuntime(Interior* pRuntime, const U32 pointIndex);
|
|
void exportVehicleHullToRuntime(Interior* pRuntime, CSGBrush* pBrush);
|
|
void exportHullBins(Interior* pRuntime);
|
|
void exportPlanes(Interior*);
|
|
U32 exportEmitStringToRuntime(Interior* pRuntime,
|
|
const U8* pString,
|
|
const U32 stringLen);
|
|
U32 exportVehicleEmitStringToRuntime(Interior* pRuntime,
|
|
const U8* pString,
|
|
const U32 stringLen);
|
|
|
|
bool fixTJuncs();
|
|
void rotateSurfaceToNonColinear(Surface& surface);
|
|
void dumpSurfaceToRuntime(Interior* pRuntime,
|
|
Surface& editSurface);
|
|
void dumpNullSurfaceToRuntime(Interior* pRuntime,
|
|
NullSurface& editSurface);
|
|
void dumpVehicleNullSurfaceToRuntime(Interior* pRuntime,
|
|
NullSurface& editSurface);
|
|
|
|
void dumpMirrorToRuntime(Interior* pRuntime,
|
|
MirrorSurfaceEntity* pEntity);
|
|
void dumpTriggerToRuntime(Interior* pRuntime,
|
|
InteriorResource* pResource,
|
|
TriggerEntity* pEntity);
|
|
void dumpPathToRuntime(Interior* pRuntime,
|
|
InteriorResource* pResource,
|
|
PathStartEntity* pEntity);
|
|
//void dumpAISpecialToRuntime(Interior* pRuntime,
|
|
// InteriorResource* pResource,
|
|
// SpecialNodeEntity* pEntity);
|
|
void dumpGameEntityToRuntime(Interior* pRuntime,
|
|
InteriorResource* pResource,
|
|
GameEntity* pEntity);
|
|
//void dumpDoorToRuntime(Interior* /*pRuntime*/,
|
|
// InteriorResource* pResource,
|
|
// DoorEntity* pEntity);
|
|
//void dumpForceFieldToRuntime(Interior* /*pRuntime*/,
|
|
// InteriorResource* pResource,
|
|
// ForceFieldEntity* pEntity);
|
|
void fillInLightmapInfo(Surface& rSurface);
|
|
void adjustLMapTexGen(Surface&);
|
|
void createBrushSurfaces(const CSGBrush& brush);
|
|
void createBoundingVolumes(Interior* pRuntime);
|
|
|
|
public:
|
|
EditGeometry();
|
|
~EditGeometry();
|
|
|
|
//-------------------------------------- High level functions
|
|
public:
|
|
bool parseMapFile(Tokenizer*);
|
|
bool createBSP();
|
|
|
|
void createSurfaces();
|
|
void markEmptyZones();
|
|
void packLMaps();
|
|
void nudge();
|
|
void computeLightmaps(const bool alarmMode);
|
|
|
|
bool exportToRuntime(Interior*, InteriorResource*);
|
|
|
|
U16 getMaterialIndex(const char* texName) const;
|
|
|
|
//-------------------------------------- Point/Plane buffer functions
|
|
public:
|
|
U32 insertPlaneEQ(const Point3D& normal, const F64);
|
|
const U32 getPlaneInverse(const U32 planeIndex);
|
|
const PlaneEQ& getPlaneEQ(const U32) const;
|
|
bool isCoplanar(const U32, const U32) const;
|
|
U32 insertPoint(const Point3D&);
|
|
const Point3D& getPoint(const U32) const;
|
|
|
|
|
|
void giftWrapPortal(Winding& winding, Portal* portal);
|
|
|
|
//-------------------------------------- NavGraph functions
|
|
public:
|
|
void setGraphGeneration(bool generate=false,bool extrude=false);
|
|
void gatherLinksForGraph(EditBSPNode * pLeafNode);
|
|
U32 writeGraphInfo();
|
|
void doGraphExtrusions(Vector<CSGBrush*> & brushList);
|
|
void xferDetailToStructural();
|
|
|
|
//-------------------------------------- Statistics
|
|
public:
|
|
U32 getTotalNumBrushes() const;
|
|
U32 getNumStructuralBrushes() const;
|
|
U32 getNumDetailBrushes() const;
|
|
U32 getNumPortalBrushes() const;
|
|
U32 getNumAmbiguousBrushes() const;
|
|
U32 getNumOrphanPolys() const;
|
|
U32 getNumUniquePlanes() const;
|
|
U32 getNumUniquePoints() const;
|
|
U32 getNumZones() const;
|
|
U32 getNumSurfaces() const;
|
|
|
|
const Point3D& getMinBound() const;
|
|
const Point3D& getMaxBound() const;
|
|
};
|
|
|
|
extern EditGeometry* gWorkingGeometry;
|
|
|
|
|
|
inline U32 EditGeometry::getNumStructuralBrushes() const
|
|
{
|
|
return mStructuralBrushes.size();
|
|
}
|
|
|
|
inline U32 EditGeometry::getNumDetailBrushes() const
|
|
{
|
|
return mDetailBrushes.size();
|
|
}
|
|
|
|
inline U32 EditGeometry::getNumPortalBrushes() const
|
|
{
|
|
return mPortalBrushes.size();
|
|
}
|
|
|
|
inline U32 EditGeometry::getNumAmbiguousBrushes() const
|
|
{
|
|
return mNumAmbiguousBrushes;
|
|
}
|
|
|
|
inline U32 EditGeometry::getNumOrphanPolys() const
|
|
{
|
|
return mNumOrphanPolys;
|
|
}
|
|
|
|
inline U32 EditGeometry::getTotalNumBrushes() const
|
|
{
|
|
return getNumStructuralBrushes() + getNumDetailBrushes() + getNumPortalBrushes();
|
|
}
|
|
|
|
inline U32 EditGeometry::getNumUniquePlanes() const
|
|
{
|
|
return mPlaneEQs.size() / 2;
|
|
}
|
|
|
|
inline U32 EditGeometry::getNumUniquePoints() const
|
|
{
|
|
return mPoints.size();
|
|
}
|
|
|
|
inline U32 EditGeometry::getNumZones() const
|
|
{
|
|
return mZones.size();
|
|
}
|
|
|
|
inline U32 EditGeometry::getNumSurfaces() const
|
|
{
|
|
return mSurfaces.size();
|
|
}
|
|
|
|
inline const Point3D& EditGeometry::getMinBound() const
|
|
{
|
|
return mMinBound;
|
|
}
|
|
|
|
inline const Point3D& EditGeometry::getMaxBound() const
|
|
{
|
|
return mMaxBound;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
inline const PlaneEQ& EditGeometry::getPlaneEQ(const U32 planeIndex) const
|
|
{
|
|
AssertFatal(planeIndex < mPlaneEQs.size(), "EditGeometry::getPlaneEQ: planeIndex out of range");
|
|
|
|
return mPlaneEQs[planeIndex];
|
|
}
|
|
|
|
inline bool EditGeometry::isCoplanar(const U32 planeIndex1, const U32 planeIndex2) const
|
|
{
|
|
AssertFatal(planeIndex1 < mPlaneEQs.size() && planeIndex2 < mPlaneEQs.size(),
|
|
"EditGeometry::isCoplanar: planeIndex out of range");
|
|
|
|
return (planeIndex1 & ~1) == (planeIndex2 & ~1);
|
|
}
|
|
|
|
inline const Point3D& EditGeometry::getPoint(const U32 index) const
|
|
{
|
|
AssertFatal(index < mPoints.size(), "EditGeometry::getPoint: out of bounds point index");
|
|
|
|
return mPoints[index];
|
|
}
|
|
|
|
inline const U32 EditGeometry::getPlaneInverse(const U32 planeIndex)
|
|
{
|
|
return (planeIndex ^ 0x1);
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
inline EditGeometry::PlaneHashEntry* EditGeometry::PlaneHashArena::allocateEntry()
|
|
{
|
|
if (currPosition < arenaSize)
|
|
return &currBuffer[currPosition++];
|
|
|
|
// Need to add another buffer
|
|
currBuffer = new EditGeometry::PlaneHashEntry[arenaSize];
|
|
currPosition = 1;
|
|
mBuffers.push_back(currBuffer);
|
|
|
|
return currBuffer;
|
|
}
|
|
|
|
inline EditGeometry::PointHashEntry* EditGeometry::PointHashArena::allocateEntry()
|
|
{
|
|
if (currPosition < arenaSize)
|
|
return &currBuffer[currPosition++];
|
|
|
|
// Need to add another buffer
|
|
currBuffer = new EditGeometry::PointHashEntry[arenaSize];
|
|
currPosition = 1;
|
|
mBuffers.push_back(currBuffer);
|
|
|
|
return currBuffer;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
inline F64 PlaneEQ::distanceToPlane(const Point3D& rPoint) const
|
|
{
|
|
return mDot(rPoint, normal) + dist;
|
|
}
|
|
|
|
inline PlaneSide PlaneEQ::whichSide(const Point3D& testPoint) const
|
|
{
|
|
F64 distance = distanceToPlane(testPoint);
|
|
|
|
if (distance < -gcPlaneDistanceEpsilon)
|
|
return PlaneBack;
|
|
else if (distance > gcPlaneDistanceEpsilon)
|
|
return PlaneFront;
|
|
else
|
|
return PlaneOn;
|
|
}
|
|
|
|
inline PlaneSide PlaneEQ::whichSideLow(const Point3D& testPoint) const
|
|
{
|
|
F64 distance = distanceToPlane(testPoint);
|
|
|
|
if (distance < -gcPointEpsilon)
|
|
return PlaneBack;
|
|
else if (distance > gcPointEpsilon)
|
|
return PlaneFront;
|
|
else
|
|
return PlaneOn;
|
|
}
|
|
|
|
inline PlaneSide PlaneEQ::whichSidePerfect(const Point3D& testPoint) const
|
|
{
|
|
F64 distance = distanceToPlane(testPoint);
|
|
|
|
if (distance < 0)
|
|
return PlaneBack;
|
|
else if (distance > 0)
|
|
return PlaneFront;
|
|
else
|
|
return PlaneOn;
|
|
}
|
|
|
|
#endif //_EDITGEOMETRY_H_
|