thug/Code/Sk/ParkEditor2/ParkGen.h
2016-02-14 08:39:12 +11:00

498 lines
12 KiB
C++

#ifndef __SK_PARKEDITOR2_PARKGEN_H
#define __SK_PARKEDITOR2_PARKGEN_H
#include <core/math/vector.h>
#include <sk/parkeditor/edrail.h>
#define DEBUG_THIS_DAMN_THING 0
#if defined ( __PLAT_XBOX__ ) || defined ( __PLAT_WN32__ )
inline void ParkEd(const char* A ...) {};
#else
#if DEBUG_THIS_DAMN_THING
#define ParkEd(A...) printf("PARKED: "); printf(##A); printf("\n")
#else
#define ParkEd(A...)
#endif
#endif
namespace Image
{
struct RGBA;
}
namespace Nx
{
class CScene;
class CSector;
}
namespace Script
{
class CArray;
}
namespace Ed
{
class CSourcePiece;
class CClonedPiece;
class CMapListNode;
struct MapArea // Mick - OLD
{
int x, y, z;
int w, h, l;
};
enum
{
H = 4,
L = 5
};
/*
Describes a 3D box in cell coordinates. Sometimes only the position part or only the area part is used.
*/
class GridDims
{
public:
GridDims(uint8 x = 0, sint8 y = 0, uint8 z = 0, uint8 w = 0, uint8 h = 0, uint8 l = 0);
void SetXYZ(uint8 x, sint8 y, uint8 z) {m_dims[0] = x; m_dims[1] = (uint8) y; m_dims[2] = z;}
void SetWHL(uint8 w, uint8 h, uint8 l) {m_dims[3] = w; m_dims[4] = h; m_dims[5] = l;}
uint8 & operator[](sint i);
uint8 GetX() const {return m_dims[0];}
sint8 GetY() const {return (sint8) m_dims[1];}
uint8 GetZ() const {return m_dims[2];}
uint8 GetW() const {return m_dims[3];}
uint8 GetH() const {return m_dims[4];}
uint8 GetL() const {return m_dims[5];}
void MakeInfinitelyHigh();
void MakeInfiniteOnY();
void PrintContents() const;
private:
uint8 m_dims[6];
};
/*
Roles of CPiece:
-wraps object placed in park
-wraps fluid object contained in world (cursor)
Class hierarchy:
-CPiece
-CSourcePiece (dims)
-CClonedPiece (pos, rot, pointer to master)
Rotations:
-Hard: underlying verts are flipped around directly, stored dims changed to match
-Soft: matrix sent down directly, not stored with piece
Relationship with metapiece:
-pieces contained by metapiece must be of the same type, all hard pieces or all soft pieces
*/
class CPiece
{
friend class CParkGenerator;
friend class CMetaPiece;
friend class CConcreteMetaPiece;
public:
enum EFlags
{
mNO_FLAGS = 0,
// only one of following can be set
mSOURCE_PIECE = (1<<0),
mCLONED_PIECE = (1<<1),
// Applied to a cloned piece. Set if an animated piece, like part of cursor
mSOFT_PIECE = (1<<2),
// set if piece is being displayed
mIN_WORLD = (1<<3),
mSHELL = (1<<4),
mFLOOR = (1<<5),
mGAP = (1<<6),
mRESTART = (1<<7),
mNO_RAILS = (1<<8),
};
EFlags GetFlags() {return m_flags;}
virtual Mth::Vector GetDims() = 0;
void GetCellDims(GridDims *pDims);
CSourcePiece * CastToCSourcePiece();
CClonedPiece * CastToCClonedPiece();
Mth::Vector GetDimsWithRot(Mth::ERot90 rot);
protected:
/*
Hard rotation: flipping of verts
Soft: rotation of underlying piece, matrix is set for CSector directly.
*/
CPiece();
virtual ~CPiece();
void set_flag(EFlags flag) {m_flags = EFlags(m_flags | flag);}
void clear_flag(EFlags flag) {m_flags = EFlags(m_flags & ~flag);}
union
{
uint32 m_sector_checksum; // probably will refer to CSectors this way
// mp_other_thing // for soft pieces
};
EFlags m_flags;
CPiece * mp_next_in_list;
//CPiece * mp_next_in_metapiece;
};
class CSourcePiece : public CPiece
{
friend class CParkGenerator;
friend class CMetaPiece;
friend class CClonedPiece;
public:
/*
pieces in different domains can coexist at same GRID coordinates
*/
enum EDomain
{
mREGULAR = (1<<0),
mOFFSET_RAIL = (1<<1),
mGAP = (1<<2),
};
uint32 GetType();
Mth::Vector GetDims() {return m_dims;}
protected:
CSourcePiece();
~CSourcePiece();
Mth::Vector m_dims;
EDomain m_domain;
uint32 m_triggerScriptId; // Checksum of trigger script associated with this node (for stuff like chainlink fence SFX)
int m_num_rail_points;
int m_num_linked_rail_points;
};
class CClonedPiece : public CPiece
{
friend class CParkGenerator;
friend class CMetaPiece;
friend class CConcreteMetaPiece;
public:
uint32 GetID();
enum ESectorEffect
{
MARKER_ONLY,
CHANGE_SECTOR,
};
void SetDesiredPos(const Mth::Vector& pos, ESectorEffect sectorEffect);
void SetDesiredRot(Mth::ERot90 rot, ESectorEffect sectorEffect);
void SetSoftRot(float rot); // in degrees
void SetScaleX(float scaleX);
void Highlight(bool on, bool makePurple = false);
void SetActive(bool active);
void SetVisibility(bool visible);
CSourcePiece * GetSourcePiece() {return mp_source_piece;}
Mth::Vector GetPos() {return m_pos;}
Mth::ERot90 GetRot() {return m_rot;}
Mth::Vector GetDims();
uint32 GetType() {return mp_source_piece->GetType();}
protected:
CClonedPiece();
uint32 m_id;
CSourcePiece * mp_source_piece;
Mth::Vector m_pos; // center, bottom
Mth::ERot90 m_rot; // in units of 90 degrees, CCW
};
class CParkGenerator
{
public:
static const float CELL_WIDTH;
static const float CELL_HEIGHT;
static const float CELL_LENGTH;
static const uint32 vFIRST_ID_FOR_OBJECTS;
static const uint32 vMAX_ID_FOR_OBJECTS;
static const uint32 vFIRST_ID_FOR_RAILS;
static const uint32 vMAX_ID_FOR_RAILS;
static const uint32 vFIRST_ID_FOR_CREATED_RAILS;
static const uint32 vMAX_ID_FOR_CREATED_RAILS;
static const uint32 vFIRST_ID_FOR_RESTARTS;
enum EDestroyType
{
DESTROY_PIECES_AND_SECTORS,
DESTROY_ONLY_PIECES,
};
enum RestartType
{
vEMPTY,
vONE_PLAYER,
vMULTIPLAYER,
vHORSE,
vKING_OF_HILL,
vRED_FLAG,
vGREEN_FLAG,
vBLUE_FLAG,
vYELLOW_FLAG,
vNUM_RESTART_TYPES,
};
CParkGenerator();
~CParkGenerator();
int GetResourceSize(char *name);
Mem::Heap * GetParkEditorHeap();
struct MemUsageInfo
{
int mParkHeapUsed;
int mParkHeapFree; // after padding is deducted
int mMainHeapUsed;
int mMainHeapFree; // after padding is deducted
int mLastMainUsed;
bool mIsFragmented;
int mTotalRailPoints;
int mTotalLinkedRailPoints;
int mTotalClonedPieces;
};
MemUsageInfo GetResourceUsageInfo(bool printInfo = false);
void SetMaxPlayers(int maxPlayers);
int GetMaxPlayers() {return m_max_players;}
int GetMaxPlayersPossible();
CSourcePiece * GetMasterPiece(uint32 pieceType, bool assert = false);
CSourcePiece * GetNextMasterPiece(CSourcePiece *pLast);
CClonedPiece * ClonePiece(CPiece *pMasterPiece, CPiece::EFlags flags);
void AddClonedPieceToWorld(CClonedPiece *pPiece);
void DestroyClonedPiece(CClonedPiece *pPiece);
void InitializeMasterPieces(int parkW, int parkH, int parkL, int theme);
// K: Added to allow cleanup of the park editor heap during play
//void DeleteSourceAndClonedPieces();
//void DeleteParkEditorHeap();
void UnloadMasterPieces();
void PostGenerate();
void GenerateCollisionInfo(bool assert = true);
void RemoveOuterShellPieces(int theme);
void GenerateNodeInfo(CMapListNode * p_concrete_metapiece_list);
void ReadInRailInfo();
void DestroyRailInfo();
void HighlightAllPieces(bool highlight);
void SetGapPiecesVisible(bool visible);
void SetRestartPiecesVisible(bool visible);
void SetLightProps(int num_lights,
float amb_const_r, float amb_const_g, float amb_const_b,
float falloff_const_r, float falloff_const_g, float falloff_const_b,
float cursor_ambience);
void SetLight(Mth::Vector &light_pos, int light_num);
void CalculateLighting(CClonedPiece *p_piece);
void CalculateVertexLighting(const Mth::Vector & vert, Image::RGBA & color);
void DestroyAllClonedPieces(EDestroyType type);
int NumRestartsOfType(RestartType type);
bool NotEnoughRestartsOfType(RestartType type, int need);
Mth::Vector GetRestartPos(RestartType type, int index);
GridDims GetRestartDims(RestartType type, int index);
bool AddRestart(Mth::Vector &pos, int dir, GridDims &dims, RestartType type, bool automatic, bool auto_copy=false);
void RemoveRestart(const GridDims &dims, RestartType type);
bool FreeRestartExists(RestartType type);
void KillRestarts();
void ClearAutomaticRestarts();
CClonedPiece * CreateGapPiece(Mth::Vector &pos, float length, int rot);
Nx::CScene * GetClonedScene() {return mp_cloned_scene;}
void CleanUpOutRailSet();
void GenerateOutRailSet(CMapListNode * p_concrete_metapiece_list);
bool FindNearestRailPoint(Mth::Vector &pos, Mth::Vector *p_nearest_pos, float *p_dist_squared);
private:
enum EFlags
{
mMASTER_STUFF_LOADED = (1<<1),
mSECTORS_GENERATED = (1<<2),
mPIECES_IN_WORLD = (1<<3),
mCOLLISION_INFO_GENERATED = (1<<4),
mNODE_INFO_GENERATED = (1<<5),
// set when we destroy a piece
mSECTOR_MEMORY_NEEDS_FREE = (1<<6),
};
void destroy_piece_impl(CClonedPiece *pPiece, EDestroyType destroyType);
bool flag_on(EFlags flag) {return ((m_flags & flag) != 0);}
void set_flag(EFlags flag) {m_flags = EFlags(m_flags | flag);}
void clear_flag(EFlags flag) {m_flags = EFlags(m_flags & ~flag);}
uint32 scan_for_cluster(Script::CArray *pNodeArray, int &index);
int scan_for_rail_node(Script::CArray *pNodeArray, uint32 cluster, int link, Mth::Vector *pVector, bool *pHasLinks, RailPoint::RailType *pType);
void scan_in_trigger_info(Script::CArray *pNodeArray);
void set_up_object_nodes(Script::CArray *pNodeArray, int *pNodeNum);
void set_up_rail_nodes(Script::CArray *pNodeArray, int *pNodeNum);
void set_up_restart_nodes(Script::CArray *pNodeArray, int *pNodeNum);
/*
Things
-loading master geometry, loading master rails (one operation)
-generating world from compressed map
-collision setup
-rail setup
-cleanup world (maybe just destroys pieces)
*/
EFlags m_flags;
CPiece * mp_cloned_piece_list;
CPiece * mp_source_piece_list;
int m_num_cloned_pieces;
int m_num_source_pieces;
Nx::CScene * mp_source_scene; // Scene used as a manager of pieces
Nx::CScene * mp_cloned_scene;
uint32 m_next_id;
Mem::Region* mp_mem_region;
Mem::Heap* mp_mem_heap;
int m_max_players;
//////////////////////////////////////////////////////////////////////////
// rail and node stuff patched in by Mick
RailSet m_in_rail_set;
RailSet m_out_rail_set;
// in world, at editing time
int m_total_rail_points;
int m_total_rail_linked_points;
struct TempNodeInfo
{
uint32 classCrc;
uint32 cluster;
Script::CArray * pLinkArray;
};
TempNodeInfo * m_temp_node_tab;
int * m_processed_node_tab;
int m_processed_node_tab_entries;
/*
Restart stuff
*/
void get_restart_slots(RestartType type, int *pFirstSlot, int *pLastSlot);
struct RestartInfo
{
Mth::Vector pos;
int dir;
GridDims dims;
RestartType type;
bool automatic;
};
static const int vNUM_RESTARTS = 18;
RestartInfo m_restart_tab[vNUM_RESTARTS];
/*
Light info
*/
struct LightIntensity
{
float r;
float g;
float b;
};
static const int vMAX_LIGHTS = 16;
int m_numLights;
LightIntensity m_ambientLightIntensity;
LightIntensity m_falloffLightIntensity;
Mth::Vector m_lightTab[vMAX_LIGHTS];
float m_cursorAmbience;
MemUsageInfo m_mem_usage_info;
};
} // end namespace
#endif