// NeL - MMORPG Framework
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see .
#ifndef __RYKOL_PATCH_MESH_H
#define __RYKOL_PATCH_MESH_H
#pragma warning (disable : 4786)
#include "nel/misc/types_nl.h"
#include
#include
#include
#include
#include "nel/misc/debug.h"
#include "nel/3d/tile_bank.h"
#include "nel/misc/file.h"
#include "nel/misc/rgba.h"
#include "path_mesh_alloc.h"
//#define USE_CACHE
namespace NL3D
{
class CZone;
class CZoneSymmetrisation;
};
typedef unsigned int uint;
#define RYKOLPATCHOBJ_CLASS_ID Class_ID(0x368c679f, 0x711c22ee)
extern TCHAR *GetString(int id);
extern HINSTANCE hInstance;
extern ClassDesc* GetRPODesc();
#define RPATCHMESH_SERIALIZE_VERSION_9 9
#define RPATCHMESH_SERIALIZE_VERSION_8 8
#define RPATCHMESH_SERIALIZE_VERSION_7 7
#define RPATCHMESH_SERIALIZE_VERSION_6 6
#define RPATCHMESH_SERIALIZE_VERSION_5 5
#define RPATCHMESH_SERIALIZE_VERSION_4 4
#define RPATCHMESH_SERIALIZE_VERSION_3 3
#define RPATCHMESH_SERIALIZE_VERSION_2 2
#define RPATCHMESH_SERIALIZE_VERSION_1 1
#define RPATCHMESH_SERIALIZE_VERSION RPATCHMESH_SERIALIZE_VERSION_9
#define EP_OBJECT 0
#define EP_VERTEX 1
#define EP_EDGE 2
#define EP_PATCH 3
#define EP_TILE 4
#define PO_TILE 4
#define PATCH_HIT_TILE (PATCH_HIT_INTERIOR+1)
#define MAX_TILE_IN_PATCH 16
#define NUM_TILE_SEL (MAX_TILE_IN_PATCH*MAX_TILE_IN_PATCH)
#define NEL3D_APPDATA_ZONE_ROTATE 1266703978
#define NEL3D_APPDATA_ZONE_SYMMETRY 1266703979
#pragma warning (disable : 4786)
// ------------------------------------------------------------------------------------------------------------------------------------------------
/*
Here the user infos (UI) for face, edge, vertex, vertex-face.
All these infos are stored in one class (RPO_UI) through vectors
*/
class CVertexNeighborhood;
int CheckBind (int nVert, int nSeg, int& v0, int& v1, int& v2, int& v3, const CVertexNeighborhood& tab, const PatchMesh& patch, bool bAssert, bool bCreate);
std::string GetBankPathName ();
int GetBankTileSetSet ();
void SetBankPathName (const std::string& path);
void SetBankTileSetSet (int);
int WhereIsTheEdge (int nPatch, int nEdge, const PatchMesh& patch);
extern NL3D::CTileBank bank;
#define RPO_DEFAULT_TESSEL 4
enum typeBind { BIND_25=0, BIND_75, BIND_50, BIND_SINGLE, BIND_COUNT, BIND_ALIGN=0xffffffff };
extern float bindWhere[BIND_COUNT];
class bindingDesc
{
public:
uint8 bBinded; // true, this vertex is binded, false, is not. default 0
uint8 nType; // Type of the vertex
uint16 nPatch; // # of the patch on which the vertex is binded. Valid only if bBinded==true.
uint16 nEdge; // # of the edge in the patch on which the vertex is binded. Valid only if bBinded==true.
uint16 nPrimVert; // # of the primary vertex in this bind
uint16 nBefore; // # of the before tangant
uint16 nBefore2; // # of the before tangant
uint16 nAfter; // # of the after tangant
uint16 nAfter2; // # of the after tangant
uint16 nT; // # of the tangant of the binded edge
uint16 fnslmq;
//float fWhere; // Where on the edge the vertex is binded. Value must be 0.25f, 0.5f or 0.75f.
// Valid only if bBinded==true.
};
class tileIndex
{
public:
tileIndex ()
{}
tileIndex (int tile, int rotate)
{
Tile=tile;
Rotate=rotate;
}
uint Tile:16;
int Rotate:8;
};
class tileDesc
{
#define CASE_MASK 0x0007
#define DISPLACE_SHIFT 3
#define DISPLACE_COUNT 16
#define DISPLACE_MASK ((DISPLACE_COUNT-1)<=0)&&(nCase<5));
_Flags&=~CASE_MASK;
_Flags|=nCase;
}
uint8 getDisplace () const
{
return (uint8)((_Flags&DISPLACE_MASK)>>DISPLACE_SHIFT);
}
void setDisplace (uint8 nDisplace)
{
nlassert ((nDisplace>=0)&&(nDisplace=0)&&(edge<4));
return (_Edges[edge].Flags&UI_EDGE_FLAGS_NO_SMOOTH_MASK)!=0;
}
// Set edge flags
void setEdgeFlag (uint edge, bool flags)
{
nlassert ((edge>=0)&&(edge<4));
// Erase and set the flag
_Edges[edge].Flags&=~UI_EDGE_FLAGS_NO_SMOOTH_MASK;
_Edges[edge].Flags|=(uint32)flags;
}
// Get edge
CEdgeInfo& getEdge (uint edge)
{
return _Edges[edge];
}
// Get edge
const CEdgeInfo& getEdge (uint edge) const
{
return _Edges[edge];
}
public:
void Init (int nU=RPO_DEFAULT_TESSEL, int nV=RPO_DEFAULT_TESSEL, bool bKeep=false)
{
// Copy old patch infos
UI_PATCH old=*this;
// New size
int nOldU=old.NbTilesU;
int nOldV=old.NbTilesV;
int nNewU=1< AllocPatch; // 100 patch by mesh
CPathMeshAlloc AllocVertex; // 100 vertices by mesh
CPathMeshAlloc AllocInt;
};
struct RPOTess
{
int TileTesselLevel;
bool ModeTile;
bool KeepMapping;
int TransitionType;
};
class CBankManager
{
public:
CBankManager ()
{
_lastPath="";
}
const NL3D::CTileBank& getBank (std::string& path=GetBankPathName ())
{
if (path!=_lastPath)
{
try
{
NLMISC::CIFile file;
if (file.open (path))
{
_bank.clear();
_bank.serial (file);
}
}
catch (NLMISC::EStream& excp)
{
MessageBox (NULL, excp.what(), "Load error", MB_OK|MB_ICONEXCLAMATION);
}
}
return _bank;
}
private:
NL3D::CTileBank _bank;
std::string _lastPath;
};
// Class container of data with copy operator
class CPatchMeshData
{
public:
// Default constructor, allocate the array
CPatchMeshData ();
// Copy constructor, allocate the array
CPatchMeshData (const CPatchMeshData& src);
// Destructor
~CPatchMeshData ();
// Copy
CPatchMeshData& operator= (const CPatchMeshData& src);
// The pointers
std::vector *_UIPatch;
std::vector *_UIVertex;
std::vector *_MapHitToTileIndex;
};
class RPatchMesh
{
friend class RPO;
public:
RPatchMesh ();
~RPatchMesh ();
// Info per patch
private:
CPatchMeshData _Data;
private:
// Remap the map hit size
void resizeMapHit (uint size)
{
_Data._MapHitToTileIndex->resize (size);
}
// Remap the map hit size
void setRemapEntry (uint iD, uint remap)
{
(*_Data._MapHitToTileIndex)[iD]=remap;
}
// Resize the user info size
void resizeUIPatch (uint size)
{
_Data._UIPatch->resize (size);
}
// Resize the user info size
void resizeUIVertex (uint size)
{
_Data._UIVertex->resize (size);
}
public:
// Get map hit size
uint getMapHitSize () const
{
return (uint)_Data._MapHitToTileIndex->size ();
}
// Remap a triangle
uint remapTriangle (uint iD) const
{
nlassert (iDsize();
}
// Get a patch user info
UI_PATCH& getUIPatch (uint iD)
{
// Check
nlassert (iDsize();
}
// Get a vertex user info
UI_VERTEX& getUIVertex (uint iD)
{
// Check
nlassert (iD=0);
nlassert (nU=0);
nlassert (nV>24;
dest.R=(encodedColor>>16)&0xff;
dest.G=(encodedColor>>8)&0xff;
dest.B=encodedColor&0xff;
}
// Set the vertex color of a patch
void setVertexColor (int patch, int s, int t, const NLMISC::CRGBA& newColor)
{
// Get the color
uint encodedColor=(newColor.A<<24)|(newColor.R<<16)|(newColor.G<<8)|newColor.B;
// Store the color
getUIPatch (patch).setColor (t*((1<