Complete disaster-recovery snapshot: engine/game source, game data assets, VC6 toolchain + DX SDKs, build outputs, deployed game, and _UNUSED archive. Large binaries in Git LFS; text preserved byte-for-byte (core.autocrlf=false, no eol attributes). See RECOVERY.md for the one-clone rebuild procedure.
541 lines
12 KiB
C++
541 lines
12 KiB
C++
#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<TrianglePointAngleStruct> 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> waterEdge;
|
|
Stuff::DynamicArrayOf<WaterEdgePoint> 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<ElementRenderer::GridElement*>*
|
|
GetTerrainArray()
|
|
{ return &simpleTerrainGroup; }
|
|
|
|
Stuff::DynamicArrayOf<ElementRenderer::GroupElement*>*
|
|
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<TriangleAbstract*>& tdtrilist,
|
|
frameArray *frame,
|
|
MidLevelRenderer::MLRState *state = NULL
|
|
);
|
|
|
|
bool
|
|
CreateMesh2(
|
|
ElementRenderer::ListElement *parent,
|
|
int index,
|
|
int levDiff,
|
|
DynamicArrayOf<TriangleAbstract*>& 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<TriangleAbstract*>& tdtrilist,
|
|
int binSize,
|
|
frameArray *frame,
|
|
MidLevelRenderer::MLRState *state = NULL
|
|
);
|
|
|
|
bool
|
|
BinSort2(
|
|
ElementRenderer::ListElement *parent,
|
|
int index,
|
|
int levDiff,
|
|
DynamicArrayOf<TriangleAbstract*>& 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<unsigned char>& onOffPoints,
|
|
int maxNumOfTrianglesPerMesh,
|
|
Scalar xOffset,
|
|
Scalar zOffset,
|
|
Scalar xGrid,
|
|
Scalar zGrid,
|
|
int tileX,
|
|
int tileZ,
|
|
const char *texRoot
|
|
);
|
|
|
|
void
|
|
BuildTile(
|
|
DynamicArrayOf<TriangleStruct*>& tempTrianglesPtr,
|
|
int index,
|
|
int depth, int maxdepth,
|
|
int numOfTriangles,
|
|
DynamicArrayOf<unsigned char>& onOffPoints,
|
|
int maxNumOfTrianglesPerMesh,
|
|
Scalar xOffset,
|
|
Scalar zOffset,
|
|
Scalar xGrid,
|
|
Scalar zGrid,
|
|
int tileX,
|
|
int tileZ
|
|
);
|
|
|
|
void
|
|
CreateTile(
|
|
ElementRenderer::ListElement *list,
|
|
ElementRenderer::GroupElement *waterList,
|
|
DynamicArrayOf<TriangleStruct*>& 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<ToDrawTriangle*> toSortTriangles;
|
|
DynamicArrayOf<ToDrawTriangle> 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<float> field;
|
|
|
|
int side, meshX, meshZ;
|
|
|
|
Stuff::DynamicArrayOf<ElementRenderer::GridElement*> simpleTerrainGroup;
|
|
Stuff::DynamicArrayOf<ElementRenderer::GroupElement*> waterGroup;
|
|
|
|
Stuff::DynamicArrayOf<MidLevelRenderer::MLRShape*> 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<BYTE> interestData;
|
|
DirectMap<real> *map;
|
|
GreedySubdivision *mesh;
|
|
Stuff::Scalar Offset;
|
|
};
|
|
#endif
|
|
|