#if !defined(HFSLIMMZ_HPP) #define HFSLIMMZ_HPP #include "ImageLib\image.h" #include "terra\terra.hpp" namespace ElementRenderer { class GridElement; class GroupElement; class ListElement; } extern bool doWater; extern Scalar waterLevel; extern bool doBSP; extern bool doPrecise; extern bool doInterest; extern bool doTileCap; extern bool doTileCapYovin; extern bool doDensityMap; extern bool silentMode; struct TriangleAbstract { TriangleAbstract(): plane( Normal3D::Down, 0.0f ) { center = Point3D::Identity; area = 0.0f; centerValid = false; } bool centerValid; Point3D center; Scalar area; Plane plane; virtual Point3D &GetPoint(int) = 0; bool GetSurfaceAreaAndCentroid(); }; // ===================== not so precise =========================== struct ToDrawTriangle : public TriangleAbstract { ToDrawTriangle() : TriangleAbstract() { v[0] = Point3D::Identity; v[1] = Point3D::Identity; v[2] = Point3D::Identity; } Point3D v[3]; void SetPoint(int idx,float x,float y,float z); ToDrawTriangle& operator= (const ToDrawTriangle& tdt) { v[0] = tdt.v[0]; v[1] = tdt.v[1]; v[2] = tdt.v[2]; center = tdt.center; area = tdt.area; plane = tdt.plane; centerValid = tdt.centerValid; return *this; } Point3D &GetPoint(int i) { return v[i]; } }; // ========================== Precision =========================== struct DetailLevelInfo { unsigned short width, height; unsigned char *array; }; struct TriangleStruct; struct TrianglePointAngleStruct { TrianglePointAngleStruct() { tri = NULL; angle = 0.0f; pos = -1; } TriangleStruct *tri; float angle; int pos; }; struct PointStruct { PointStruct() : myTri(16) { p = Point3D::Identity; connectedTo = 0; } Point3D p; int connectedTo; DynamicArrayOf myTri; void Add (TriangleStruct *ts, int pos); void CalculateAngles(); bool CheckAngles(float xmin, float zmin, float xmax, float zmax, float dX, float dZ); bool CheckAngles(); // checks for adjecent triangles with angle of close to 180 float GetAngles(); float GetExpectedAngles(float xmin, float zmin, float xmax, float zmax); void TestInstance() const; }; struct TriangleStruct : public TriangleAbstract { TriangleStruct() : TriangleAbstract() { v[0] = 0; v[1] = 0; v[2] = 0; } static PointStruct *points; int v[3]; bool GetSurfaceAreaAndCentroid() { Verify(points!=NULL); if(v[0]==v[1] || v[0]==v[2] || v[1]==v[2]) { center = GetPoint(0); centerValid = true; area = 0.0f; return false; } return TriangleAbstract::GetSurfaceAreaAndCentroid(); } Point3D &GetPoint(int i) { Verify(points!=NULL); return points[v[i]].p; } }; //======================= Water =================================== struct WaterEdge { int p[2]; Normal3D normal; bool inside[2]; int used; WaterEdge() { p[0] = -1; p[1] = -1; normal = Normal3D::Down; inside[0] = false; inside[1] = false; used = 0; } }; struct WaterEdgePoint { Stuff::Point3D p; int toEdge[8]; int toEdgeCount; int used; int onEdge; WaterEdgePoint() { toEdge[0] = -1; toEdge[1] = -1; used = 0; onEdge = 0; toEdgeCount = 0;} WaterEdgePoint& operator=(const WaterEdgePoint& wep) { p = wep.p; toEdge[0] = wep.toEdge[0]; toEdge[1] = wep.toEdge[1]; used = wep.used; onEdge = wep.onEdge; toEdgeCount = wep.toEdgeCount; return *this; } }; struct WaterPools { Stuff::DynamicArrayOf waterEdge; Stuff::DynamicArrayOf waterEdgePoints; int waterEdgeCount; int waterEdgePointCount; Stuff::Scalar x0, x1, z0, z1, waterLevel; WaterPools(int nr, Scalar wl) : waterEdge(nr), waterEdgePoints(2*nr) { waterEdgeCount = 0; waterEdgePointCount = 0; waterLevel = wl; } void AddEdge(Stuff::Point3D& p0, Stuff::Point3D& p1, const Stuff::Normal3D& n); MidLevelRenderer::MLRPrimitiveBase* LinkEdges(); void SetTileEdges(Stuff::Scalar _x0, Stuff::Scalar _x1, Stuff::Scalar _z0, Stuff::Scalar _z1) {x0 = _x0; x1 = _x1; z0 = _z0; z1 = _z1; } int OnWhatEdge(WaterEdgePoint& wep); int OnWhatEdge(Stuff::Point3D& wep); }; // ============================= Naturals ========================== struct CulturalLoc { Stuff::Point3D loc; BYTE yaw; BYTE nr; }; // ======================== Height field slim ====================== class HFSlimMZ { public: HFSlimMZ(); ~HFSlimMZ(); void FillFromImage(Image &image, int smooth=3); void FillInterestDataFromImage(Image &image); void TestInstance() const {} void SetScale (Stuff::Scalar xs, Stuff::Scalar ys, Stuff::Scalar zs) { Check_Object(this); dX = xs; dY = ys; dZ = zs; } void SetDetailTextureInfo( const char *name, const char *altname, Scalar xOff, Scalar zOff, Scalar xFac, Scalar zFac, Scalar dStart, Scalar dEnd, MLRState::AlphaMode alphaMode ) { detailInfo.name = name; detailInfo.altname = altname; detailInfo.xOff = xOff; detailInfo.zOff = zOff; detailInfo.xFac = xFac; detailInfo.zFac = zFac; detailInfo.dStart = dStart; detailInfo.dEnd = dEnd; detailInfo.alphaMode = alphaMode; } void SetWaterDetailTextureInfo( const char *name, Scalar xOff, Scalar zOff, Scalar xFac, Scalar zFac, Scalar dStart, Scalar dEnd, MLRState::AlphaMode alphaMode, int movieFrames ) { waterDetailInfo.name = name; waterDetailInfo.altname = NULL; waterDetailInfo.xOff = xOff; waterDetailInfo.zOff = zOff; waterDetailInfo.xFac = xFac; waterDetailInfo.zFac = zFac; waterDetailInfo.dStart = dStart; waterDetailInfo.dEnd = dEnd; waterDetailInfo.alphaMode = alphaMode; waterDetailInfo.movieFrames = movieFrames; } void SetBorderPixels(int bp) { borderPixelFun = bp/256.0f; } int GetOptPolyCount() {return OptPolyCount; } Scalar GetXinM() { return (X-1) * dX; } Scalar GetZinM() { return (Z-1) * dZ; } int GetX() { return X; } int GetZ() { return Z; } Stuff::Scalar GetXScale() { return dX; } Stuff::Scalar GetZScale() { return dZ; } Stuff::Scalar GetYScale() { return dY; } Scalar GetX(int x) { return x*dX; } Scalar GetZ(int z) { return z*dZ; } Scalar GetX(Scalar x) { return x; } Scalar GetZ(Scalar z) { return z; } Scalar GetHeight(int, int); Stuff::ExtentBox GetExtents(); void GetZoneDimensions(int *xd, int *zd) { *xd = xDim; *zd = zDim; } Stuff::DynamicArrayOf* GetTerrainArray() { return &simpleTerrainGroup; } Stuff::DynamicArrayOf* GetWaterArray() { return &waterGroup; } void SetOffset(Stuff::Scalar offset) { Offset = offset; }; bool SetMegaTexture( int nrOfLevels, int bucketSize, const char *megaBaseName, const char *output ); void SetWaterInfo(const char *name, Scalar ratio, int movieFrames) { waterTextureName = name; waterTextureRatio = ratio; waterMovieFrames = movieFrames; } void OptimizeHField(int depth=0, int binSize=64, const char *name=NULL); Stuff::Scalar GetOffset() { return Offset; }; void SetAllDepth(int d) { maxAllDepth = d; } void SetCenter(Stuff::Scalar xo, Stuff::Scalar zo) { Check_Object(this); xCenterOffset = xo; zCenterOffset = zo; } Stuff::Scalar GetCenterX() { Check_Object(this); return xCenterOffset; } Stuff::Scalar GetCenterZ() { Check_Object(this); return zCenterOffset; } void SetCulturals(CulturalLoc*, int); void SetCulturalFadeValues(Stuff::Scalar fadeIn, Stuff::Scalar fadeOut) { Check_Object(this); culturalFadeIn = fadeIn; culturalFadeOut = fadeOut; } protected: void Blur2D(int); typedef Stuff::Scalar frameArray[8][4]; bool CreateMesh( ElementRenderer::ListElement *parent, int index, int levDiff, DynamicArrayOf& tdtrilist, frameArray *frame, MidLevelRenderer::MLRState *state = NULL ); bool CreateMesh2( ElementRenderer::ListElement *parent, int index, int levDiff, DynamicArrayOf& tdtrilist, frameArray *frame, MidLevelRenderer::MLRState *state = NULL, bool uw = false ); MLRPrimitiveBase* CreateWater( Scalar x0, Scalar x1, Scalar z0, Scalar z1, Scalar waterLevel ); bool BinSort( ElementRenderer::ListElement *parent, int index, int levDiff, DynamicArrayOf& tdtrilist, int binSize, frameArray *frame, MidLevelRenderer::MLRState *state = NULL ); bool BinSort2( ElementRenderer::ListElement *parent, int index, int levDiff, DynamicArrayOf& tdtrilist, int binSize, frameArray *frame, MidLevelRenderer::MLRState *state = NULL, bool uw = false ); void BuildTile( ElementRenderer::ListElement *, ElementRenderer::GroupElement *, int index, int depth, int maxdepth, DynamicArrayOf& onOffPoints, int maxNumOfTrianglesPerMesh, Scalar xOffset, Scalar zOffset, Scalar xGrid, Scalar zGrid, int tileX, int tileZ, const char *texRoot ); void BuildTile( DynamicArrayOf& tempTrianglesPtr, int index, int depth, int maxdepth, int numOfTriangles, DynamicArrayOf& onOffPoints, int maxNumOfTrianglesPerMesh, Scalar xOffset, Scalar zOffset, Scalar xGrid, Scalar zGrid, int tileX, int tileZ ); void CreateTile( ElementRenderer::ListElement *list, ElementRenderer::GroupElement *waterList, DynamicArrayOf& tempTrianglesPtr, int index, int depth, int maxdepth, int maxNumOfTrianglesPerMesh, Scalar xOffset, Scalar zOffset, Scalar xGrid, Scalar zGrid, int tileX, int tileZ, const char *texRoot ); DynamicArrayOf toSortTriangles; DynamicArrayOf tdtrilist; // X, Z number of points, the length of the terrain would be (X-1)*dX int X, Z, Xoffset, Zoffset, visHeight; Stuff::Scalar dX, dY, dZ; int OptPolyCount; Stuff::DynamicArrayOf field; int side, meshX, meshZ; Stuff::DynamicArrayOf simpleTerrainGroup; Stuff::DynamicArrayOf waterGroup; Stuff::DynamicArrayOf terrain; MidLevelRenderer::MLRState state0, state1, state2; MidLevelRenderer::DetailTextureInfo detailInfo, waterDetailInfo; const char *waterTextureName; Scalar waterTextureRatio; int waterMovieFrames; int waterDetailMovieFrames; Scalar borderPixelFun; unsigned char maxAllDepth; Stuff::Scalar xCenterOffset, zCenterOffset; Stuff::Scalar culturalFadeIn, culturalFadeOut; int xDim, zDim; private: Stuff::DynamicArrayOf interestData; DirectMap *map; GreedySubdivision *mesh; Stuff::Scalar Offset; }; #endif