Added sharedTerrain library

This commit is contained in:
Anonymous
2014-01-14 09:33:54 -07:00
parent f4243cffeb
commit 8342abaeec
159 changed files with 37404 additions and 0 deletions
@@ -0,0 +1,140 @@
set(SHARED_SOURCES
shared/appearance/ProceduralTerrainAppearance.cpp
shared/appearance/ProceduralTerrainAppearance.h
shared/appearance/ProceduralTerrainAppearanceTemplate.cpp
shared/appearance/ProceduralTerrainAppearanceTemplate.h
shared/appearance/SamplerProceduralTerrainAppearance.cpp
shared/appearance/SamplerProceduralTerrainAppearance.h
shared/appearance/SamplerProceduralTerrainAppearance_Cache.cpp
shared/appearance/SamplerProceduralTerrainAppearance_Cache.h
shared/appearance/SamplerProceduralTerrainAppearanceTemplate.cpp
shared/appearance/SamplerProceduralTerrainAppearanceTemplate.h
shared/appearance/ServerProceduralTerrainAppearance_Cache.cpp
shared/appearance/ServerProceduralTerrainAppearance_Cache.h
shared/appearance/ServerProceduralTerrainAppearance.cpp
shared/appearance/ServerProceduralTerrainAppearance.h
shared/appearance/ServerProceduralTerrainAppearanceTemplate.cpp
shared/appearance/ServerProceduralTerrainAppearanceTemplate.h
shared/appearance/ServerSpaceTerrainAppearance.cpp
shared/appearance/ServerSpaceTerrainAppearance.h
shared/appearance/ServerSpaceTerrainAppearanceTemplate.cpp
shared/appearance/ServerSpaceTerrainAppearanceTemplate.h
shared/appearance/SpaceTerrainAppearance.cpp
shared/appearance/SpaceTerrainAppearance.h
shared/appearance/SpaceTerrainAppearanceTemplate.cpp
shared/appearance/SpaceTerrainAppearanceTemplate.h
shared/appearance/TerrainAppearance.cpp
shared/appearance/TerrainAppearance.h
shared/appearance/TerrainQuadTree.cpp
shared/appearance/TerrainQuadTree.h
shared/core/ConfigSharedTerrain.cpp
shared/core/ConfigSharedTerrain.h
shared/core/FirstSharedTerrain.h
shared/core/SetupSharedTerrain.cpp
shared/core/SetupSharedTerrain.h
shared/core/WaterTypeManager.cpp
shared/core/WaterTypeManager.h
shared/flora/FloraManager.cpp
shared/flora/FloraManager.h
shared/flora/ServerFloraManager.cpp
shared/flora/ServerFloraManager.h
shared/generator/AffectorColor.cpp
shared/generator/AffectorColor.h
shared/generator/Affector.cpp
shared/generator/AffectorEnvironment.cpp
shared/generator/AffectorEnvironment.h
shared/generator/AffectorExclude.cpp
shared/generator/AffectorExclude.h
shared/generator/AffectorFloraDynamic.cpp
shared/generator/AffectorFloraDynamic.h
shared/generator/AffectorFloraStatic.cpp
shared/generator/AffectorFloraStatic.h
shared/generator/Affector.h
shared/generator/AffectorHeight.cpp
shared/generator/AffectorHeight.h
shared/generator/AffectorPassable.cpp
shared/generator/AffectorPassable.h
shared/generator/AffectorRibbon.cpp
shared/generator/AffectorRibbon.h
shared/generator/AffectorRiver.cpp
shared/generator/AffectorRiver.h
shared/generator/AffectorRoad.cpp
shared/generator/AffectorRoad.h
shared/generator/AffectorShader.cpp
shared/generator/AffectorShader.h
shared/generator/Array2d.h
shared/generator/BitmapGroup.cpp
shared/generator/BitmapGroup.h
shared/generator/Boundary.cpp
shared/generator/Boundary.h
shared/generator/ColorRamp256.cpp
shared/generator/ColorRamp256.h
shared/generator/CoordinateHash.cpp
shared/generator/CoordinateHash.h
shared/generator/EnvironmentGroup.cpp
shared/generator/EnvironmentGroup.h
shared/generator/FastKeyList.h
shared/generator/FastList.h
shared/generator/Feather.h
shared/generator/Filter.cpp
shared/generator/Filter.h
shared/generator/FloraGroup.cpp
shared/generator/FloraGroup.h
shared/generator/FractalGroup.cpp
shared/generator/FractalGroup.h
shared/generator/HeightData.cpp
shared/generator/HeightData.h
shared/generator/RadialGroup.cpp
shared/generator/RadialGroup.h
shared/generator/ShaderGroup.cpp
shared/generator/ShaderGroup.h
shared/generator/TerrainGenerator.cpp
shared/generator/TerrainGenerator.h
shared/generator/TerrainGeneratorLoader.cpp
shared/generator/TerrainGeneratorLoader.h
shared/generator/TerrainGeneratorType.def
shared/generator/TerrainGeneratorType.h
shared/generator/TerrainModificationHelper.cpp
shared/generator/TerrainModificationHelper.h
shared/object/TerrainObject.cpp
shared/object/TerrainObject.h
shared/object/TerrainReferenceObjectNotification.cpp
shared/object/TerrainReferenceObjectNotification.h
)
if(WIN32)
set(PLATFORM_SOURCES
win32/FirstSharedTerrain.cpp
)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/win32)
else()
set(PLATFORM_SOURCES "")
endif()
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}/shared
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedCollision/include/public
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedDebug/include/public
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedFile/include/public
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedFoundation/include/public
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedFoundationTypes/include/public
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedFractal/include/public
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedImage/include/public
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedMath/include/public
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedMemoryManager/include/public
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedObject/include/public
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedRandom/include/public
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedUtility/include/public
${SWG_EXTERNALS_SOURCE_DIR}/ours/library/fileInterface/include/public
)
add_library(sharedTerrain STATIC
${SHARED_SOURCES}
${PLATFORM_SOURCES}
)
@@ -0,0 +1,456 @@
//===================================================================
//
// ProceduralTerrainAppearance.h
// asommers 9-11-2000
//
// copyright 2000, verant interactive
//
//===================================================================
#ifndef INCLUDED_ProceduralTerrainAppearance_H
#define INCLUDED_ProceduralTerrainAppearance_H
//===================================================================
#include "sharedCollision/BoxExtent.h"
#include "sharedMath/Sphere.h"
#include "sharedMath/Vector.h"
#include "sharedTerrain/TerrainAppearance.h"
#include "sharedTerrain/TerrainGenerator.h"
class Appearance;
class Camera;
class Iff;
class Object;
class ObjectList;
class ObjectTemplate;
class ProceduralTerrainAppearanceTemplate;
class Rectangle2d;
class SpatialSubdivisionHandle;
//-------------------------------------------------------------------
//
// ProceduralTerrainAppearance holds a list of generated terrain chunks
//
// data for the template is as follows:
//
// mapWidthInMeters supplied by designers/artists (i.e. 4096m x 4096m)
//
// chunkWidthInMeters supplied by designers/artists (i.e. 32m)
//
// tileWidthInMeters width of a terrain tile in meters
// tiles are composed of a fan of 8 polygons
//
// numberOfTilesPerChunk number of tiles per chunk for width and height (square)
// total number of tiles per chunk is numberOfTilesPerChunk^2
//
// numberOfTiles along width = numberOfChunks * numberOfTilesPerChunk
// total number of tiles = numberOfTiles^2
//
// tiles are organized in the following vertex structure. the purpose of
// indirection is to allow me to create the tile vertex arrays in a loop
//
// 2 3 4
// x-----x-----x
// |\ | /|
// | \ | / |
// | 0\|/ |
// 1 x-----x-----x 5
// | /|\ |
// | / | \ |
// |/ | \|
// x-----x-----x
// 8 7 6
//
class ProceduralTerrainAppearance : public TerrainAppearance
{
public:
typedef void (*CreateFloraHookFunction) (Object& object);
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//
// CreateChunkData defines the data needed to generate a chunk in the terrain system
//
struct CreateChunkData
{
public:
//-- scratchpad (using TerrainGenerator::createChunkBuffer)
TerrainGenerator::CreateChunkBuffer* createChunkBuffer;
//-- coordinate of chunk (x,z) in chunk space
int chunkX;
int chunkZ;
//-- number of shader tiles
int numberOfTilesPerChunk;
//-- chunk width
float chunkWidthInMeters;
float tileWidthInMeters;
Vector start;
int originOffset;
int numberOfPoles;
//--
const ShaderGroup* shaderGroup;
const FloraGroup* floraGroup;
const RadialGroup* radialGroup;
const EnvironmentGroup* environmentGroup;
const FractalGroup* fractalGroup;
const BitmapGroup* bitmapGroup;
uint8 hasLargerNeighborFlags;
private:
CreateChunkData ();
CreateChunkData (const CreateChunkData& rhs);
CreateChunkData& operator= (const CreateChunkData& rhs);
public:
explicit CreateChunkData (TerrainGenerator::CreateChunkBuffer* newCreateChunkBuffer);
virtual ~CreateChunkData ();
virtual void validate () const;
};
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//
// SurfaceData returns the object template at a given tile of the terrain system
//
struct SurfaceData
{
public:
const ObjectTemplate* objectTemplate;
public:
SurfaceData ();
};
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//
// StaticFloraData defines information about what flora exists at a point
//
struct StaticFloraData
{
public:
//-- family data
bool floats;
float childChoice;
//-- family child data
FloraGroup::FamilyChildData const * familyChildData;
public:
StaticFloraData ();
};
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//
// Chunk defines a chunk of terrain in the terrain system
//
class Chunk : public Appearance
{
public:
explicit Chunk (ProceduralTerrainAppearance& proceduralTerrainAppearance);
virtual ~Chunk ();
const ProceduralTerrainAppearanceTemplate *getAppearanceTemplate() const { return m_proceduralTerrainAppearance.proceduralTerrainAppearanceTemplate; }
virtual bool collide(Vector const & start_o, Vector const & end_o, CollideParameters const & collideParameters, CollisionInfo & result) const = 0;
virtual bool getHeightAt (const Vector& pos, float* height) const = 0;
virtual bool getHeightAt (const Vector& pos, float* height, Vector* normal) const = 0;
const BoxExtent& getBoxExtent() const { return m_boxExtent; }
//-- coordinate of chunk (x,z) in chunk space
int getChunkX() const { return chunkX; }
int getChunkZ() const { return chunkZ; }
float getChunkWidthInMeters () const { return chunkWidthInMeters; }
bool getHasLargerNeighbor (int dir) const;
bool getHasAnyLargerNeighbors () const { return hasLargerNeighborFlags!=0; }
bool findSurface (const Vector& position, SurfaceData& data) const;
void setPassable(int tileX, int tileZ, bool isPassable);
bool isPassable(const Vector& position) const;
bool isExcluded(const Vector& position) const;
bool isExcluded(int tileX, int tileZ) const;
bool floraAllowed(const Vector& position) const { return _floraAllowed(position.x, position.z); }
bool findStaticCollidableFlora (const Vector& position, StaticFloraData& data, bool& floraAllowed) const;
bool findStaticCollidableFlora (const Vector& position, FloraGroup::Info& data, bool& floraAllowed) const;
virtual int getChunkMemorySize () const;
#ifdef _DEBUG
virtual bool debugRenderingEnabled () const;
#endif
SpatialSubdivisionHandle *getSpatialSubdivisionHandle() const { return m_spatialSubdivisionHandle; }
void setSpatialSubdivisionHandle(SpatialSubdivisionHandle *h) const { m_spatialSubdivisionHandle = h; }
public:
static void setDrawVertexNormals (bool drawVertexNormals);
static bool getDrawVertexNormals ();
static void setDrawExtent (bool drawExtent);
static bool getDrawExtent ();
protected:
void _findMapXz (const Vector& position, int& x, int& z) const;
void _findTileXz(Vector const & position, int & x, int & z) const;
void _makeStaticFloraData(StaticFloraData& o_data, const FloraGroup::Info &i_groupInfo) const;
bool _floraAllowed(float positionX, float positionZ) const;
bool _findStaticFlora(const Array2d<FloraGroup::Info>& floraMap, float positionX, float positionZ, StaticFloraData& data, bool& floraAllowed) const;
bool _findStaticFlora(const Array2d<FloraGroup::Info>& floraMap, float positionX, float positionZ, FloraGroup::Info &data, bool& floraAllowed) const;
void _prepareForDelete();
void _setExcluded(int tileX, int tileZ);
protected:
ProceduralTerrainAppearance & m_proceduralTerrainAppearance;
//-- coordinate of chunk (x,z) in chunk space
int chunkX;
int chunkZ;
float chunkWidthInMeters;
uint8 hasLargerNeighborFlags;
int originOffset;
int numberOfPoles;
BoxExtent m_boxExtent;
Array2d<ShaderGroup::Info>* shaderMap;
Array2d<FloraGroup::Info> * m_floraStaticCollidableMap;
unsigned m_excluded, m_passable;
mutable SpatialSubdivisionHandle * m_spatialSubdivisionHandle;
private:
Chunk ();
Chunk (const Chunk& rhs);
Chunk& operator= (const Chunk& rhs);
private:
static bool ms_drawVertexNormals;
static bool ms_drawExtent;
};
friend class Chunk;
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
public:
ProceduralTerrainAppearance (const ProceduralTerrainAppearanceTemplate* appearanceTemplate);
virtual ~ProceduralTerrainAppearance () = 0;
virtual const Sphere& getSphere () const;
virtual bool getHeight (const Vector& position_o, float& height) const;
virtual bool getHeight (const Vector& position_o, float& height, Vector& normal) const;
virtual bool getHeightForceChunkCreation (const Vector& position_o, float& height) const;
virtual const ObjectTemplate* getSurfaceProperties (const Vector& position_o) const;
virtual bool getWaterHeight (const Vector& position_o, float& height) const;
virtual bool getWaterHeight (const Vector& position_o, float& height, TerrainGeneratorWaterType& waterType, bool ignoreNonTransparentWater=false) const;
TerrainGeneratorWaterType getWaterType (const Vector& position_o) const;
virtual bool getWater (int chunkX, int chunkZ) const;
virtual bool getSlope (int chunkX, int chunkZ) const;
virtual bool getWater (const Rectangle2d& rectangle) const;
virtual bool getSlope (const Rectangle2d& rectangle) const;
virtual float getChunkWidthInMeters () const;
virtual float getMapWidthInMeters () const;
virtual float getEnvironmentCycleTime () const;
virtual int getNumberOfChunks () const = 0;
virtual int calculateChunkX (float positionX) const;
virtual int calculateChunkZ (float positionZ) const;
virtual float getChunkHeight (int chunkX, int chunkZ) const;
virtual const BoxExtent* getChunkExtent (const Vector& position_o) const;
virtual const BoxExtent* getChunkExtentForceChunkCreation (const Vector& position_o) const;
virtual bool collide(Vector const & start_o, Vector const & end_o, CollideParameters const & collideParamters, CollisionInfo & result) const = 0;
virtual float alter (float time) = 0;
int getNumberOfTilesPerChunk () const;
bool findSurface (const Vector& position, SurfaceData& data) const;
bool findStaticCollidableFlora (const Vector& position, StaticFloraData& data, bool& floraAllowed) const;
virtual bool isPassable(const Vector& position) const;
virtual bool isPassableForceChunkCreation(const Vector& position) const;
//-- run-time rule addition interface
void addLayer (const TerrainGenerator::Layer* layer);
void removeLayer (const TerrainGenerator::Layer* layer);
void prepareGenerator ();
float generateHeight_expensive (const Vector2d& position_w);
virtual void addClearCollidableFloraObject (const Object* object, const Vector& position_w, float radius);
virtual void removeClearCollidableFloraObject (const Object* object);
virtual void debugDump () const;
ShaderGroup const & getShaderGroup() const;
FloraGroup const & getFloraGroup() const;
RadialGroup const & getRadialGroup() const;
EnvironmentGroup const & getEnvironmentGroup() const;
virtual bool hasPassableAffectors() const;
public:
static void install ();
static void setCreateFloraHookFunction (CreateFloraHookFunction createFloraHookFunction);
static void setMaximumNumberOfChunksAllowed (int newMaximumNumberOfChunksAllowed);
protected:
class ClearCollidableFloraEntry
{
public:
Vector position;
float radius;
};
protected:
typedef stdmap<const Object*, ClearCollidableFloraEntry>::fwd ClearCollidableFloraMap;
protected:
virtual const Chunk* findChunk (int x, int z, int chunkSize) const = 0;
virtual const Chunk* findFirstRenderableChunk (int x, int z) const = 0;
virtual const Chunk* findAnyChunk () const;
virtual void addChunk (Chunk* chunk, int chunkSize) = 0;
virtual void createChunk (int x, int z, int chunkSize, unsigned hasLargerNeighborFlags) = 0;
virtual void removeUnnecessaryChunk () = 0;
bool areValidChunkIndices (int x, int z) const;
const Chunk* findChunk (const Vector& position, int chunkSize) const;
const Chunk* findFirstRenderableChunk (const Vector& position) const;
const Chunk* findFirstRenderableChunk2D(float positionX, float positionZ) const;
void createChunk (const Vector& position, int chunkSize);
virtual void prepareForDelete (const Chunk* chunk);
bool _legacyGetStaticCollidableFloraData(StaticFloraData &o_data, const Chunk* const chunk, const Vector &floraPosition);
void _legacyCreateFlora (const Chunk* chunk);
void createFlora (const Chunk* chunk);
void destroyFlora (const Chunk* chunk);
void verifyChunk (const Chunk* chunk) const;
void setClient ();
const ClearCollidableFloraMap* getClearCollidableFloraMap () const;
protected:
//--
const int originOffset;
const int upperPad;
const int numberOfPoles;
//-- culling sphere
mutable Sphere sphere;
//-- scratchpad for creating chunks
TerrainGenerator::CreateChunkBuffer createChunkBuffer;
//-- scratchpad for [expensively] creating just height data
TerrainGenerator::CreateChunkBuffer generateHeightChunkBuffer;
//-- maximum number of chunks to hold
int maximumNumberOfChunksAllowed;
int maximumNumberOfChunksAlongSide;
const ProceduralTerrainAppearanceTemplate* proceduralTerrainAppearanceTemplate;
typedef stdvector<TerrainGenerator::Layer*>::fwd RunTimeRuleList;
RunTimeRuleList* m_runTimeRuleList;
int m_chunksGeneratedThisFrame;
protected:
static CreateFloraHookFunction ms_createFloraHookFunction;
private:
static void remove ();
private:
bool shouldClearCollidableFlora (const Vector& position) const;
private:
ProceduralTerrainAppearance ();
ProceduralTerrainAppearance (const ProceduralTerrainAppearance&);
ProceduralTerrainAppearance& operator= (const ProceduralTerrainAppearance&);
private:
bool m_server;
typedef stdmap<uint32, Object*>::fwd FloraMap;
FloraMap* const m_floraMap;
FloraMap* const m_cachedFloraMap;
ClearCollidableFloraMap* const m_clearCollidableFloraMap;
bool m_hasPassableAffectors;
};
//-------------------------------------------------------------------
inline
bool ProceduralTerrainAppearance::Chunk::getHasLargerNeighbor (int direction) const
{
VALIDATE_RANGE_INCLUSIVE_EXCLUSIVE (0, direction, 4);
return 0!=(hasLargerNeighborFlags & (1<<direction));
}
//-------------------------------------------------------------------
inline
bool ProceduralTerrainAppearance::Chunk::findStaticCollidableFlora (const Vector& position, StaticFloraData& data, bool& floraAllowed) const
{
NOT_NULL (m_floraStaticCollidableMap);
return _findStaticFlora(*m_floraStaticCollidableMap, position.x, position.z, data, floraAllowed);
}
//-------------------------------------------------------------------
inline
bool ProceduralTerrainAppearance::Chunk::findStaticCollidableFlora (const Vector& position, FloraGroup::Info& data, bool& floraAllowed) const
{
NOT_NULL (m_floraStaticCollidableMap);
return _findStaticFlora(*m_floraStaticCollidableMap, position.x, position.z, data, floraAllowed);
}
//===================================================================
#endif
@@ -0,0 +1,249 @@
//===================================================================
//
// ProceduralTerrainAppearanceTemplate.h
// asommers 9-11-2000
//
// copyright 2000, verant interactive
//
//===================================================================
#ifndef INCLUDED_ProceduralTerrainAppearanceTemplate_H
#define INCLUDED_ProceduralTerrainAppearanceTemplate_H
//===================================================================
#include "sharedMath/Vector2d.h"
#include "sharedObject/AppearanceTemplate.h"
#include "sharedTerrain/TerrainGenerator.h"
#include "sharedTerrain/Boundary.h"
class BakedTerrain;
class Iff;
class PackedIntegerMap;
class PackedFixedPointMap;
//===================================================================
class ProceduralTerrainAppearanceTemplate : public AppearanceTemplate
{
public:
explicit ProceduralTerrainAppearanceTemplate(
const char* filename,
Iff* iff,
bool legacyMode,
int chunkOriginOffset, // size of sample pad on lower side of chunk.
int chunkUpperPad, // size of sample pad on upper side of chunk.
bool samplingMode=false
);
virtual ~ProceduralTerrainAppearanceTemplate ()=0;
const char* getName () const;
float getMapWidthInMeters () const;
float getChunkWidthInMeters () const;
int getNumberOfTilesPerChunk () const;
bool getUseGlobalWaterTable () const;
float getGlobalWaterTableHeight () const;
const char* getGlobalWaterTableShaderTemplateName () const;
float getGlobalWaterTableShaderSize () const;
float getEnvironmentCycleTime () const;
float getCollidableMinimumDistance () const;
float getCollidableMaximumDistance () const;
float getCollidableTileSize () const;
float getCollidableTileBorder () const;
uint32 getCollidableSeed () const;
float getNonCollidableMinimumDistance () const;
float getNonCollidableMaximumDistance () const;
float getNonCollidableTileSize () const;
float getNonCollidableTileBorder () const;
uint32 getNonCollidableSeed () const;
float getRadialMinimumDistance () const;
float getRadialMaximumDistance () const;
float getRadialTileSize () const;
float getRadialTileBorder () const;
uint32 getRadialSeed () const;
float getFarRadialMinimumDistance () const;
float getFarRadialMaximumDistance () const;
float getFarRadialTileSize () const;
float getFarRadialTileBorder () const;
uint32 getFarRadialSeed () const;
float getTileWidthInMeters () const;
bool getLegacyMap() const { return m_legacyMap; }
bool getLegacyMode() const { return m_legacyMode; }
int getChunkOriginOffset() const { return m_chunkOriginOffset; }
int getChunkUpperPad() const { return m_chunkUpperPad; }
const TerrainGenerator* getTerrainGenerator () const;
const BakedTerrain* getBakedTerrain () const;
bool getWaterHeight (const Vector& position, float& height) const;
bool getWaterHeight (const Vector& position, float& height, TerrainGeneratorWaterType& waterType, bool ignoreNonTransparentWater = false) const;
TerrainGeneratorWaterType getWaterType (const Vector& position_w) const;
// --
float getFloraTileWidthInMeters() const { return m_floraTileWidthInMeters; }
int getMapWidthInFlora() const { return m_mapWidthInFlora; }
int getStaticCollidableFloraFamily(int floraTileX, int floraTileY) const;
float getStaticCollidableFloraHeight(int floraTileX, int floraTileY) const;
protected:
struct RibbonQuad
{
TerrainGeneratorWaterType waterType;
Vector points[4];
};
struct RibbonEndCap
{
TerrainGeneratorWaterType waterType;
Vector2d points[8];
Rectangle2d extent;
float height;
};
struct WaterTable
{
TerrainGeneratorWaterType waterType;
const TerrainGenerator::Boundary* boundary;
float height;
};
protected:
char* m_name;
float m_mapWidthInMeters;
float m_chunkWidthInMeters;
int m_numberOfTilesPerChunk;
bool m_useGlobalWaterTable;
float m_globalWaterTableHeight;
char* m_globalWaterTableShaderTemplateName;
float m_globalWaterTableShaderSize;
float m_environmentCycleTime;
float m_collidableMinimumDistance;
float m_collidableMaximumDistance;
float m_collidableTileSize;
float m_collidableTileBorder;
uint32 m_collidableSeed;
float m_nonCollidableMinimumDistance;
float m_nonCollidableMaximumDistance;
float m_nonCollidableTileSize;
float m_nonCollidableTileBorder;
uint32 m_nonCollidableSeed;
float m_radialMinimumDistance;
float m_radialMaximumDistance;
float m_radialTileSize;
float m_radialTileBorder;
uint32 m_radialSeed;
float m_farRadialMinimumDistance;
float m_farRadialMaximumDistance;
float m_farRadialTileSize;
float m_farRadialTileBorder;
uint32 m_farRadialSeed;
bool m_legacyMap;
bool m_legacyMode;
const bool m_samplingMode;
float m_tileWidthInMeters;
int m_chunkOriginOffset;
int m_chunkUpperPad;
TerrainGenerator* m_terrainGenerator;
BakedTerrain* m_bakedTerrain;
typedef stdvector<WaterTable>::fwd WaterTableList;
WaterTableList* m_waterTableList;
typedef stdvector<RibbonQuad>::fwd RibbonQuadList;
RibbonQuadList* m_ribbonQuadList;
typedef stdvector<RibbonEndCap>::fwd RibbonEndCapList;
RibbonEndCapList* m_ribbonEndCapList;
float m_floraTileWidthInMeters;
int m_mapWidthInFlora;
PackedIntegerMap *m_staticCollidableFloraMap;
PackedFixedPointMap *m_staticCollidableFloraHeightMap;
protected:
void load (Iff& iff); //lint !e1511 //-- member hides non-virtual member
void _load(Iff& iff, Tag version);
void createWaterTableAndRibbonQuadLists ();
void createWaterTableAndRibbonQuadLists (const TerrainGenerator::Layer* layer);
void _setSamplingParameters(bool legacyMode, int chunkOriginOffset, int chunkUpperPad);
void _setStaticCollidableFloraInfo(FloraGroup::Info *infoMap, float *heightMap);
void _destroyStaticCollidableFloraMaps();
void _createDefaultStaticCollidableFloraMaps();
private:
ProceduralTerrainAppearanceTemplate ();
ProceduralTerrainAppearanceTemplate (const ProceduralTerrainAppearanceTemplate&);
ProceduralTerrainAppearanceTemplate& operator= (const ProceduralTerrainAppearanceTemplate&);
// ------------------------------------------------------------------
public:
struct WriterData
{
public:
const char* name;
float mapWidthInMeters;
float chunkWidthInMeters;
int numberOfTilesPerChunk;
bool useGlobalWaterTable;
float globalWaterTableHeight;
float globalWaterTableShaderSize;
const char* globalWaterTableShaderTemplateName;
float environmentCycleTime;
float collidableMinimumDistance;
float collidableMaximumDistance;
float collidableTileSize;
float collidableTileBorder;
uint32 collidableSeed;
float nonCollidableMinimumDistance;
float nonCollidableMaximumDistance;
float nonCollidableTileSize;
float nonCollidableTileBorder;
uint32 nonCollidableSeed;
float radialMinimumDistance;
float radialMaximumDistance;
float radialTileSize;
float radialTileBorder;
uint32 radialSeed;
float farRadialMinimumDistance;
float farRadialMaximumDistance;
float farRadialTileSize;
float farRadialTileBorder;
uint32 farRadialSeed;
bool legacyMap;
// ------------------------------------
const TerrainGenerator *terrainGenerator;
const BakedTerrain *bakedTerrain;
const PackedIntegerMap *staticCollidableFloraMap;
const PackedFixedPointMap *staticCollidableFloraHeightMap;
public:
WriterData();
};
void prepareWriterData(WriterData &writerData);
static void write (Iff& iff, const WriterData& data);
};
//===================================================================
#endif
@@ -0,0 +1,158 @@
//===================================================================
//
// SamplerProceduralTerrainAppearance.h
// asommers
//
// copyright 2000, verant interactive
//
//===================================================================
#ifndef INCLUDED_SamplerProceduralTerrainAppearance_h
#define INCLUDED_SamplerProceduralTerrainAppearance_h
//===================================================================
#include "sharedFoundation/MemoryBlockManagerMacros.h"
#include "sharedTerrain/ProceduralTerrainAppearance.h"
class Plane;
class MemoryBlockManager;
//===================================================================
class SamplerProceduralTerrainAppearanceTemplate;
class SamplerProceduralTerrainAppearance : public ProceduralTerrainAppearance
{
public:
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//
// Chunk defines a chunk of terrain in the terrain system
//
class SamplerChunk : public ProceduralTerrainAppearance::Chunk
{
MEMORY_BLOCK_MANAGER_INTERFACE_WITHOUT_INSTALL;
protected:
// indexList is a list of triplets indexing the vertex positions used in each triangle of the chunk.
static ArrayList<int>* ms_indexList;
protected:
// vertexList is a list of 3D positions for the chunk's height poles. size is (numberOfHeightPoles-2)^2
ArrayList<Vector>* m_vertexList;
// planeList is a list of planes corresponding to the above triangles
ArrayList<Plane>* m_planeList;
time_t m_timeStamp;
private:
static void createIndexList (int numberOfTilesPerChunk, int actualNumberOfPoles);
private:
SamplerChunk ();
SamplerChunk (const SamplerChunk& rhs);
SamplerChunk& operator= (const SamplerChunk& rhs);
public:
static void install ();
static void remove ();
static bool compareTimestampsGreater(SamplerChunk const * lhs, SamplerChunk const * rhs);
public:
explicit SamplerChunk (ProceduralTerrainAppearance& proceduralTerrainAppearance);
virtual ~SamplerChunk ();
virtual bool getHeightAt (const Vector& worldPos, float* height) const;
virtual bool getHeightAt (const Vector& worldPos, float* height, Vector* normal) const;
virtual bool collide(Vector const & start_o, Vector const & end_o, CollideParameters const & collideParameters, CollisionInfo & result) const;
virtual int getChunkMemorySize () const;
void create (const ProceduralTerrainAppearance::CreateChunkData& newCreateChunkData);
void writeChunkData (const char* filename) const;
};
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
class Cache;
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
public:
SamplerProceduralTerrainAppearance (SamplerProceduralTerrainAppearanceTemplate* appearanceTemplate);
virtual ~SamplerProceduralTerrainAppearance ();
virtual float alter (float time);
virtual void render () const;
virtual void writeChunkData (int chunkX, int chunkZ) const;
virtual int getTerrainType (const Vector& position_o) const;
virtual void invalidateRegion (const Rectangle2d& extent2d);
virtual bool collide(Vector const & start_o, Vector const & end_o, CollideParameters const & collideParameters, CollisionInfo & result) const;
virtual bool collideForceChunkCreation (Vector const & start_o, Vector const & end_o, CollisionInfo & result);
virtual int getNumberOfChunks () const;
virtual bool hasHighLevelOfDetailTerrain (const Vector& position_o) const;
bool isStaticCollidableFloraChunk(const int x, const int z, const int chunkSize);
SamplerChunk *createChunk(const int x, const int z, const int chunkSize);
virtual void createChunk (int x, int z, int chunkSize, unsigned hasLargerNeighborFlags);
virtual void purgeChunks();
void createFlora (const Chunk* const chunk);
protected:
typedef stdmap<uint32, Chunk const *>::fwd ChunkMap;
typedef stdvector<Chunk const *>::fwd ChunkList;
typedef stdvector<SamplerChunk const *>::fwd SamplerChunkList;
typedef stdset<uint32>::fwd ChunkSet;
protected:
virtual void removeUnnecessaryChunk ();
virtual void addChunk (Chunk* chunk, int chunkSize);
virtual const Chunk* findChunk (int x, int z, int chunkSize) const;
virtual const Chunk* findFirstRenderableChunk (int x, int z) const;
virtual const Chunk* findAnyChunk () const;
virtual uint32 computeChunkMapKey (int x, int z) const;
virtual void prepareForDelete (Chunk const * chunk);
void generateBetween(Vector const & start_o, Vector const & end_o, ChunkList & chunkList);
bool collideChunkList(ChunkList const & chunkList, Vector const & start_o, Vector const & end_o, CollisionInfo & result) const;
protected:
SamplerProceduralTerrainAppearanceTemplate &terrainSamplerTemplate;
ChunkMap* const m_chunkMap;
private:
class CollisionChunkSorter;
private:
SamplerProceduralTerrainAppearance ();
SamplerProceduralTerrainAppearance (const SamplerProceduralTerrainAppearance&);
SamplerProceduralTerrainAppearance& operator= (const SamplerProceduralTerrainAppearance&);
private:
int m_chunkMapKeyOffset;
SamplerChunkList* const m_highUsedChunkList;
SamplerChunkList* const m_lowUsedChunkList;
SamplerChunkList* const m_unusedChunkList;
ChunkList* const m_invalidateChunkList;
};
//===================================================================
#endif
@@ -0,0 +1,501 @@
//===================================================================
//
// SamplerProceduralTerrainAppearanceTemplate.cpp
// asommers
//
// copyright 2000, verant interactive
//
//===================================================================
#include "sharedTerrain/FirstSharedTerrain.h"
#include "sharedTerrain/SamplerProceduralTerrainAppearanceTemplate.h"
#include "sharedTerrain/SamplerProceduralTerrainAppearance.h"
#include "sharedFoundation/ExitChain.h"
#include "sharedUtility/PackedIntegerMap.h"
#include "sharedUtility/PackedFixedPointMap.h"
#include "sharedObject/AppearanceTemplateList.h"
#include "sharedTerrain/ConfigSharedTerrain.h"
#include "fileInterface/StdioFile.h"
#include "sharedFile/TreeFile.h"
#include <malloc.h>
#if defined(PLATFORM_LINUX)
#include <alloca.h>
#endif
//===================================================================
struct StaticFloraSampleFileHeader
{
char terrainName[64];
float floraTileWidthInMeters;
int numberOfFloraSampled;
};
struct StaticFloraSampleHeightPlaneHeader
{
int version;
float minHeight;
float maxHeight;
float scale;
int nibblesPerEntry;
};
struct CollidableFloraSampleFileHeader
{
uint32 type;
int version;
char terrainName[64];
float floraTileWidthInMeters;
int minFloraTileX;
int minFloraTileZ;
int maxFloraTileX;
int maxFloraTileZ;
int numberOfFloraSampled;
float minHeight;
float maxHeight;
};
//===================================================================
AppearanceTemplate* SamplerProceduralTerrainAppearanceTemplate::create (const char* filename, Iff* iff)
{
return new SamplerProceduralTerrainAppearanceTemplate (filename, iff);
}
//===================================================================
SamplerProceduralTerrainAppearanceTemplate::SamplerProceduralTerrainAppearanceTemplate (const char* filename, Iff* iff) :
ProceduralTerrainAppearanceTemplate (filename, iff, false, 0, 1, true),
m_staticCollidableFloraHeightMin(0),
m_staticCollidableFloraHeightMax(0),
m_staticCollidableFloraHeightSamples(0),
m_staticCollidableFloraSamples(0),
m_numberOfSampledFlora(0)
{
if (m_legacyMap)
{
_setSamplingParameters(true, 3, 3);
}
}
//-------------------------------------------------------------------
SamplerProceduralTerrainAppearanceTemplate::~SamplerProceduralTerrainAppearanceTemplate ()
{
delete [] m_staticCollidableFloraHeightSamples;
m_staticCollidableFloraHeightSamples=0;
delete [] m_staticCollidableFloraSamples;
m_staticCollidableFloraSamples=0;
}
//-------------------------------------------------------------------
Appearance* SamplerProceduralTerrainAppearanceTemplate::createAppearance () const
{
return new SamplerProceduralTerrainAppearance (const_cast<SamplerProceduralTerrainAppearanceTemplate *>(this));
}
//-------------------------------------------------------------------
void SamplerProceduralTerrainAppearanceTemplate::setMapsToSample(unsigned maps)
{
m_terrainGenerator->setMapsToSample(maps);
}
//-------------------------------------------------------------------
bool SamplerProceduralTerrainAppearanceTemplate::getFloraHeightSample(int key, float &o_height) const
{
if (!m_staticCollidableFloraHeightSamples)
{
o_height=0;
return false;
}
else
{
o_height = m_staticCollidableFloraHeightSamples[key];
return true;
}
}
//-------------------------------------------------------------------
void SamplerProceduralTerrainAppearanceTemplate::beginStaticCollidableFloraSampling()
{
m_staticCollidableFloraHeightMin = FLT_MAX;
m_staticCollidableFloraHeightMax = -FLT_MAX;
const int numElements = sqr(getMapWidthInFlora());
float *staticCollidableFloraHeightSamples = new float[numElements];
memset(staticCollidableFloraHeightSamples, 0, numElements*sizeof(*staticCollidableFloraHeightSamples));
m_staticCollidableFloraHeightSamples=staticCollidableFloraHeightSamples;
FloraGroup::Info *staticCollidableFloraSamples = new FloraGroup::Info[numElements];
memset(staticCollidableFloraSamples, 0, numElements*sizeof(*staticCollidableFloraSamples));
m_staticCollidableFloraSamples = staticCollidableFloraSamples;
m_numberOfSampledFlora=0;
}
//-------------------------------------------------------------------
bool SamplerProceduralTerrainAppearanceTemplate::loadStaticCollidableFloraFile(const char *i_filename)
{
if (!m_staticCollidableFloraHeightSamples)
{
beginStaticCollidableFloraSampling();
}
// -------------------------------------------------------
AbstractFile *mapFile = TreeFile::open(i_filename, AbstractFile::PriorityData, true);
if (!mapFile)
{
REPORT_LOG_PRINT(true, ("Could not open sample file %s\n", i_filename));
return false;
}
// -------------------------------------------------------
CollidableFloraSampleFileHeader fileHeader;
mapFile->read(&fileHeader, sizeof(fileHeader));
if (fileHeader.type!=TGM_floraStaticCollidable)
{
return false;
}
if (fileHeader.version!=1)
{
return false;
}
if (fileHeader.floraTileWidthInMeters!=getFloraTileWidthInMeters())
{
return false;
}
// -------------------------------------------------------
int xWidth = fileHeader.maxFloraTileX - fileHeader.minFloraTileX;
int z;
for (z=fileHeader.minFloraTileZ;z<fileHeader.maxFloraTileZ;z++)
{
FloraGroup::Info *row = m_staticCollidableFloraSamples + z*getMapWidthInFlora();
mapFile->read(row+fileHeader.minFloraTileX, xWidth*sizeof(*row));
}
for (z=fileHeader.minFloraTileZ;z<fileHeader.maxFloraTileZ;z++)
{
float *row = m_staticCollidableFloraHeightSamples + z*getMapWidthInFlora();
mapFile->read(row+fileHeader.minFloraTileX, xWidth*sizeof(*row));
}
// -------------------------------------------------------
delete mapFile;
return true;
}
//-------------------------------------------------------------------
void SamplerProceduralTerrainAppearanceTemplate::setFloraTileSample(int key, const FloraGroup::Info &i_data, float height)
{
FloraGroup::Info &info = m_staticCollidableFloraSamples[key];
if (!info.getFamilyId())
{
info=i_data;
if (i_data.getFamilyId())
{
if (height>m_staticCollidableFloraHeightMax)
{
m_staticCollidableFloraHeightMax=height;
}
if (height<m_staticCollidableFloraHeightMin)
{
m_staticCollidableFloraHeightMin=height;
}
m_staticCollidableFloraHeightSamples[key]=height;
m_numberOfSampledFlora++;
}
}
}
//-------------------------------------------------------------------
static bool _extractPlanetName(char *o_buffer, const char *i_filename)
{
o_buffer[0]=0;
if (!i_filename || !*i_filename || i_filename[0]=='.')
{
return false;
}
const char *iter;
iter=strrchr(i_filename, 0);
while (iter>i_filename)
{
if ( iter[-1]=='/'
|| iter[-1]=='\\'
|| iter[-1]==':'
)
{
break;
}
iter--;
}
// iter should now point to beginning of planet name
char *oiter=o_buffer;
while (*iter && *iter!='.')
{
*oiter++=*iter++;
}
*oiter++=0;
return true;
}
//-------------------------------------------------------------------
bool SamplerProceduralTerrainAppearanceTemplate::writeStaticCollidableFloraFile(const char *i_filename, int tileBounds[4]) const
{
if (!m_samplingMode)
{
return false;
}
AbstractFile *of = StdioFileFactory().createFile(i_filename, "wb");
if (!of)
{
return false;
}
char planetname[256];
strcpy(planetname, "terrain\\");
if (!_extractPlanetName(strrchr(planetname, 0), i_filename))
{
return false;
}
strcat(planetname, ".trn");
// --------------------------------------------
CollidableFloraSampleFileHeader fileHeader;
Zero(fileHeader);
fileHeader.type=TGM_floraStaticCollidable;
fileHeader.version=1;
strcpy(fileHeader.terrainName, planetname);
fileHeader.floraTileWidthInMeters = getFloraTileWidthInMeters();
fileHeader.minFloraTileX = tileBounds[0];
fileHeader.minFloraTileZ = tileBounds[1];
fileHeader.maxFloraTileX = tileBounds[2];
fileHeader.maxFloraTileZ = tileBounds[3];
fileHeader.numberOfFloraSampled=0;
fileHeader.minHeight = FLT_MAX;
fileHeader.maxHeight = -FLT_MAX;
// --------------------------------------------
int x, z;
for (z=tileBounds[1];z<tileBounds[3];z++)
{
const float *heightRow = m_staticCollidableFloraHeightSamples + z*getMapWidthInFlora();
for (x=tileBounds[0];x<tileBounds[2];x++)
{
if (heightRow[x]<fileHeader.minHeight)
{
fileHeader.minHeight=heightRow[x];
}
if (heightRow[x]>fileHeader.maxHeight)
{
fileHeader.maxHeight=heightRow[x];
}
}
const FloraGroup::Info *infoRow = m_staticCollidableFloraSamples + z*getMapWidthInFlora();
for (x=tileBounds[0];x<tileBounds[2];x++)
{
FloraGroup::Info fgi = infoRow[x];
if (fgi.getFamilyId())
{
fileHeader.numberOfFloraSampled++;
}
}
}
// --------------------------------------------
of->write(sizeof(fileHeader), &fileHeader);
int xWidth = tileBounds[2] - tileBounds[0];
for (z=tileBounds[1];z<tileBounds[3];z++)
{
const FloraGroup::Info *row = m_staticCollidableFloraSamples + z*getMapWidthInFlora();
of->write(xWidth*sizeof(*row), row+tileBounds[0]);
}
for (z=tileBounds[1];z<tileBounds[3];z++)
{
const float *row = m_staticCollidableFloraHeightSamples + z*getMapWidthInFlora();
of->write(xWidth*sizeof(*row), row+tileBounds[0]);
}
of->close();
delete of;
// --------------------------------------------------------
return true;
}
//-------------------------------------------------------------------
bool SamplerProceduralTerrainAppearanceTemplate::writeOldStaticCollidableFloraFile(const char *i_filename) const
{
if (!m_samplingMode)
{
return false;
}
AbstractFile *of = StdioFileFactory().createFile(i_filename, "wb");
if (!of)
{
return false;
}
char planetname[256];
strcpy(planetname, "terrain\\");
if (!_extractPlanetName(strrchr(planetname, 0), i_filename))
{
return false;
}
strcat(planetname, ".trn");
StaticFloraSampleFileHeader fileHeader;
Zero(fileHeader);
strcpy(fileHeader.terrainName, planetname);
fileHeader.floraTileWidthInMeters = getFloraTileWidthInMeters();
fileHeader.numberOfFloraSampled=m_numberOfSampledFlora;
of->write(sizeof(fileHeader), &fileHeader);
of->write(sqr(getMapWidthInFlora())*sizeof(*m_staticCollidableFloraSamples), m_staticCollidableFloraSamples);
of->close();
delete of;
// --------------------------------------------------------
char buffer[1024];
strcpy(buffer, i_filename);
strcat(buffer, "2");
writeOldStaticCollidableFloraHeightFile(buffer);
// --------------------------------------------------------
return true;
}
//-------------------------------------------------------------------
bool SamplerProceduralTerrainAppearanceTemplate::writeOldStaticCollidableFloraHeightFile(const char *i_filename) const
{
if (!m_samplingMode)
{
return false;
}
AbstractFile *of = StdioFileFactory().createFile(i_filename, "wb");
if (!of)
{
return false;
}
char planetname[256];
strcpy(planetname, "terrain\\");
if (!_extractPlanetName(strrchr(planetname, 0), i_filename))
{
return false;
}
strcat(planetname, ".trn");
StaticFloraSampleHeightPlaneHeader fileHeader;
Zero(fileHeader);
//strcpy(fileHeader.terrainName, planetname);
fileHeader.version = 1;
fileHeader.minHeight = m_staticCollidableFloraHeightMin;
fileHeader.maxHeight = m_staticCollidableFloraHeightMax;
fileHeader.scale = 1.0f / 50.0f;
fileHeader.nibblesPerEntry = 8;
of->write(sizeof(fileHeader), &fileHeader);
size_t heightSize = sqr(getMapWidthInFlora());
of->write(heightSize*sizeof(*m_staticCollidableFloraHeightSamples), m_staticCollidableFloraHeightSamples);
of->close();
delete of;
return true;
}
//-------------------------------------------------------------------
void SamplerProceduralTerrainAppearanceTemplate::commitStaticCollidableFloraSamples(int *tileBounds)
{
const int mapWidthInFlora = getMapWidthInFlora();
if (tileBounds)
{
int x, z;
// initialize everything outside the bounds with the original data.
const int xstart = (tileBounds) ? clamp(0, tileBounds[0], mapWidthInFlora) : 0;
const int zstart = (tileBounds) ? clamp(0, tileBounds[1], mapWidthInFlora) : 0;
const int xstop = (tileBounds) ? clamp(0, tileBounds[2], mapWidthInFlora) : mapWidthInFlora;
const int zstop = (tileBounds) ? clamp(0, tileBounds[3], mapWidthInFlora) : mapWidthInFlora;
for (z=0;z<mapWidthInFlora;z++)
{
if (z>=zstart && z<zstop)
{
continue;
}
for (x=0;x<xstart;x++)
{
int familyId = getStaticCollidableFloraFamily(x, z);
float height = getStaticCollidableFloraHeight(x, z);
const int index = z*mapWidthInFlora + x;
m_staticCollidableFloraSamples[index].setFamilyId(familyId);
m_staticCollidableFloraHeightSamples[index]=height;
}
for (x=xstop;x<mapWidthInFlora;x++)
{
int familyId = getStaticCollidableFloraFamily(x, z);
float height = getStaticCollidableFloraHeight(x, z);
const int index = z*mapWidthInFlora + x;
m_staticCollidableFloraSamples[index].setFamilyId(familyId);
m_staticCollidableFloraHeightSamples[index]=height;
}
}
}
// --------------------------------------------------------
_setStaticCollidableFloraInfo(m_staticCollidableFloraSamples, m_staticCollidableFloraHeightSamples);
}
//-------------------------------------------------------------------
//===================================================================
@@ -0,0 +1,70 @@
//===================================================================
//
// SamplerProceduralTerrainAppearanceTemplate.h
// asommers
//
// copyright 2000, verant interactive
//
//===================================================================
#ifndef INCLUDED_SamplerProceduralTerrainAppearanceTemplate_h
#define INCLUDED_SamplerProceduralTerrainAppearanceTemplate_h
//===================================================================
#include "sharedTerrain/ProceduralTerrainAppearanceTemplate.h"
class Iff;
//===================================================================
class SamplerProceduralTerrainAppearanceTemplate : public ProceduralTerrainAppearanceTemplate
{
public:
static AppearanceTemplate* create (const char* filename, Iff* iff);
public:
SamplerProceduralTerrainAppearanceTemplate (const char* filename, Iff* iff);
virtual ~SamplerProceduralTerrainAppearanceTemplate ();
void setMapsToSample(unsigned maps);
virtual Appearance* createAppearance () const;
int getNumberOfSampledFlora() const { return m_numberOfSampledFlora; }
void setFloraTileSample(int key, const FloraGroup::Info &i_data, float height);
bool getFloraHeightSample(int key, float &o_height) const;
void beginStaticCollidableFloraSampling();
bool loadStaticCollidableFloraFile(const char *i_filename);
bool writeStaticCollidableFloraFile(const char *i_filename, int tileBounds[4]) const;
bool writeOldStaticCollidableFloraFile(const char *i_filename) const;
bool writeOldStaticCollidableFloraHeightFile(const char *i_filename) const;
void commitStaticCollidableFloraSamples(int *tileBounds); // commit current sample data to base appearance template
const FloraGroup::Info *getStaticCollidableFloraSamples() const { return m_staticCollidableFloraSamples; }
const PackedIntegerMap *getStaticCollidableFloraMap() const { return m_staticCollidableFloraMap; }
const PackedFixedPointMap *getStaticCollidableFloraHeightMap() const { return m_staticCollidableFloraHeightMap; }
private:
SamplerProceduralTerrainAppearanceTemplate ();
SamplerProceduralTerrainAppearanceTemplate (const SamplerProceduralTerrainAppearanceTemplate&);
SamplerProceduralTerrainAppearanceTemplate& operator= (const SamplerProceduralTerrainAppearanceTemplate&);
// ----------------------------------
float m_staticCollidableFloraHeightMin;
float m_staticCollidableFloraHeightMax;
float *m_staticCollidableFloraHeightSamples;
FloraGroup::Info *m_staticCollidableFloraSamples;
int m_numberOfSampledFlora;
// ----------------------------------
};
//===================================================================
#endif
@@ -0,0 +1,392 @@
//==================================================================
//
// SamplerProceduralTerrainAppearance_Cache.cpp
// asommers
//
// copyright 2002, sony online entertainment
//
//==================================================================
#include "sharedTerrain/FirstSharedTerrain.h"
#include "sharedTerrain/SamplerProceduralTerrainAppearance_Cache.h"
#include "sharedDebug/DebugFlags.h"
#include "sharedFoundation/PointerDeleter.h"
#include "sharedMath/Plane.h"
#include "sharedTerrain/ConfigSharedTerrain.h"
#include <algorithm>
#include <vector>
//==================================================================
namespace SamplerProceduralTerrainAppearanceCacheNamespace
{
typedef std::vector<ArrayList<Vector>*> VertexListList;
typedef std::vector<ArrayList<Plane>*> PlaneListList;
typedef std::vector<Array2d<ShaderGroup::Info>*> ShaderGroupList;
typedef std::vector<Array2d<FloraGroup::Info>*> FloraGroupList;
typedef std::vector<Array2d<bool>*> PassableMapList;
bool ms_installed;
uint ms_preloadSize = 2048;
VertexListList* ms_vertexListList;
PlaneListList* ms_planeListList;
ShaderGroupList* ms_shaderMapList;
FloraGroupList* ms_floraMapList;
PassableMapList* ms_passableMapList;
#ifdef _DEBUG
bool ms_debugReport;
#endif
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void debugDump ();
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ArrayList<Vector>* localCreateVertexList (const int size)
{
ArrayList<Vector>* const vertexList = new ArrayList<Vector>;
vertexList->preallocate (size, true);
return vertexList;
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ArrayList<Plane>* localCreatePlaneList (const int size)
{
ArrayList<Plane>* const planeList = new ArrayList<Plane>;
planeList->preallocate (size, true);
return planeList;
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Array2d<ShaderGroup::Info>* localCreateShaderMap (const int width, const int height)
{
Array2d<ShaderGroup::Info>* const map = new Array2d<ShaderGroup::Info>;
map->allocate (width, height);
return map;
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Array2d<FloraGroup::Info>* localCreateFloraMap (const int width, const int height)
{
Array2d<FloraGroup::Info>* const map = new Array2d<FloraGroup::Info>;
map->allocate (width, height);
return map;
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Array2d<bool>* localCreatePassableMap (const int width, const int height)
{
Array2d<bool>* const map = new Array2d<bool>;
map->allocate (width, height);
return map;
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
}
using namespace SamplerProceduralTerrainAppearanceCacheNamespace;
//==================================================================
void SamplerProceduralTerrainAppearance::Cache::install ()
{
DEBUG_REPORT_LOG_PRINT (ConfigSharedTerrain::getDebugReportInstall (), ("SamplerProceduralTerrainAppearance::Cache::install\n"));
DEBUG_FATAL (ms_installed, ("already installed"));
ms_installed = true;
ms_preloadSize = static_cast<uint> (ConfigSharedTerrain::getMaximumNumberOfChunksAllowed ());
//-- can't precreate maps because we don't know what size they will be
ms_vertexListList = new VertexListList;
ms_planeListList = new PlaneListList;
ms_shaderMapList = new ShaderGroupList;
ms_floraMapList = new FloraGroupList;
ms_passableMapList = new PassableMapList;
#ifdef _DEBUG
DebugFlags::registerFlag (SamplerProceduralTerrainAppearanceCacheNamespace::ms_debugReport, "SharedTerrain", "reportSamplerProceduralTerrainAppearanceCache", SamplerProceduralTerrainAppearanceCacheNamespace::debugDump);
#endif
}
//-------------------------------------------------------------------
void SamplerProceduralTerrainAppearance::Cache::remove ()
{
DEBUG_FATAL (!ms_installed, ("not installed"));
ms_installed = false;
//-- delete non-array lists
#define DELETE_SPECIFIC_LIST(a) { \
DEBUG_REPORT_LOG_PRINT (ConfigSharedTerrain::getDebugReportLogPrint (), ("Terrain Cache %sList = %i\n", #a, ms_ ## a ## List->size ())); \
std::for_each (ms_ ## a ## List->begin (), ms_ ## a ## List->end (), PointerDeleter ()); \
delete ms_ ## a ## List; \
ms_ ## a ## List = 0; \
}
DELETE_SPECIFIC_LIST (vertexList);
DELETE_SPECIFIC_LIST (planeList);
DELETE_SPECIFIC_LIST (shaderMap);
DELETE_SPECIFIC_LIST (floraMap);
DELETE_SPECIFIC_LIST (passableMap);
#ifdef _DEBUG
DebugFlags::unregisterFlag (SamplerProceduralTerrainAppearanceCacheNamespace::ms_debugReport);
#endif
}
//-------------------------------------------------------------------
void SamplerProceduralTerrainAppearance::Cache::warm (const int vertexListSize, const int planeListSize, const int mapSize)
{
NOT_NULL (ms_vertexListList);
ms_vertexListList->reserve (ms_preloadSize);
NOT_NULL (ms_planeListList);
ms_planeListList->reserve (ms_preloadSize);
NOT_NULL (ms_shaderMapList);
ms_shaderMapList->reserve (ms_preloadSize);
NOT_NULL (ms_floraMapList);
ms_floraMapList->reserve (ms_preloadSize);
NOT_NULL (ms_passableMapList);
ms_passableMapList->reserve (ms_preloadSize);
uint i;
for (i = 0; i < ms_preloadSize; ++i)
{
ms_vertexListList->push_back (localCreateVertexList (vertexListSize));
ms_planeListList->push_back (localCreatePlaneList (planeListSize));
ms_shaderMapList->push_back (localCreateShaderMap (mapSize, mapSize));
ms_floraMapList->push_back (localCreateFloraMap (mapSize, mapSize));
ms_passableMapList->push_back (localCreatePassableMap (mapSize, mapSize));
}
}
//-------------------------------------------------------------------
ArrayList<Vector>* SamplerProceduralTerrainAppearance::Cache::createVertexList (const int size)
{
DEBUG_FATAL (!ms_installed, ("not installed"));
NOT_NULL (ms_vertexListList);
ArrayList<Vector>* vertexList = 0;
//-- just take one off the list
if (!ms_vertexListList->empty ())
{
vertexList = ms_vertexListList->back ();
ms_vertexListList->pop_back ();
}
else
{
//-- create one
vertexList = localCreateVertexList (size);
}
NOT_NULL (vertexList);
return vertexList;
}
//-------------------------------------------------------------------
void SamplerProceduralTerrainAppearance::Cache::destroyVertexList (ArrayList<Vector>* const vertexList)
{
DEBUG_FATAL (!ms_installed, ("not installed"));
NOT_NULL (ms_vertexListList);
if (vertexList)
ms_vertexListList->push_back (vertexList);
}
//-------------------------------------------------------------------
ArrayList<Plane>* SamplerProceduralTerrainAppearance::Cache::createPlaneList (const int size)
{
DEBUG_FATAL (!ms_installed, ("not installed"));
NOT_NULL (ms_planeListList);
ArrayList<Plane>* planeList = 0;
//-- just take one off the list
if (!ms_planeListList->empty ())
{
planeList = ms_planeListList->back ();
ms_planeListList->pop_back ();
}
else
{
//-- create one
planeList = localCreatePlaneList (size);
}
NOT_NULL (planeList);
return planeList;
}
//-------------------------------------------------------------------
void SamplerProceduralTerrainAppearance::Cache::destroyPlaneList (ArrayList<Plane>* const planeList)
{
DEBUG_FATAL (!ms_installed, ("not installed"));
NOT_NULL (ms_planeListList);
if (planeList)
ms_planeListList->push_back (planeList);
}
//-------------------------------------------------------------------
Array2d<ShaderGroup::Info>* SamplerProceduralTerrainAppearance::Cache::createShaderMap (int width, int height)
{
DEBUG_FATAL (!ms_installed, ("not installed"));
NOT_NULL (ms_shaderMapList);
Array2d<ShaderGroup::Info>* map = 0;
//-- just take one off the list
if (!ms_shaderMapList->empty ())
{
map = ms_shaderMapList->back ();
ms_shaderMapList->pop_back ();
}
else
{
//-- create one
map = localCreateShaderMap (width, height);
}
NOT_NULL (map);
DEBUG_FATAL (width != map->getWidth () && height != map->getHeight (), ("SamplerProceduralTerrainAppearance::Cache - cached map of wrong size"));
return map;
}
//-------------------------------------------------------------------
void SamplerProceduralTerrainAppearance::Cache::destroyShaderMap (Array2d<ShaderGroup::Info>* map)
{
DEBUG_FATAL (!ms_installed, ("not installed"));
NOT_NULL (ms_shaderMapList);
if (map)
ms_shaderMapList->push_back (map);
}
//-------------------------------------------------------------------
Array2d<FloraGroup::Info>* SamplerProceduralTerrainAppearance::Cache::createFloraMap (int width, int height)
{
DEBUG_FATAL (!ms_installed, ("not installed"));
NOT_NULL (ms_floraMapList);
Array2d<FloraGroup::Info>* map = 0;
//-- just take one off the list
if (!ms_floraMapList->empty ())
{
map = ms_floraMapList->back ();
ms_floraMapList->pop_back ();
}
else
{
//-- create one
map = localCreateFloraMap (width, height);
}
NOT_NULL (map);
DEBUG_FATAL (width != map->getWidth () && height != map->getHeight (), ("SamplerProceduralTerrainAppearance::Cache - cached map of wrong size"));
return map;
}
//-------------------------------------------------------------------
void SamplerProceduralTerrainAppearance::Cache::destroyFloraMap (Array2d<FloraGroup::Info>* map)
{
DEBUG_FATAL (!ms_installed, ("not installed"));
NOT_NULL (ms_floraMapList);
if (map)
ms_floraMapList->push_back (map);
}
//----------------------------------------------------------------------
Array2d<bool>* SamplerProceduralTerrainAppearance::Cache::createPassableMap (int width, int height)
{
DEBUG_FATAL (!ms_installed, ("not installed"));
NOT_NULL (ms_passableMapList);
Array2d<bool>* map = 0;
//-- just take one off the list
if (!ms_passableMapList->empty ())
{
map = ms_passableMapList->back ();
ms_passableMapList->pop_back ();
}
else
{
//-- create one
map = localCreatePassableMap (width, height);
}
NOT_NULL (map);
DEBUG_FATAL (width != map->getWidth () && height != map->getHeight (), ("SamplerProceduralTerrainAppearance::Cache - cached map of wrong size"));
return map;
}
//-------------------------------------------------------------------
void SamplerProceduralTerrainAppearance::Cache::destroyPassableMap (Array2d<bool>* map)
{
DEBUG_FATAL (!ms_installed, ("not installed"));
NOT_NULL (ms_passableMapList);
if (map)
ms_passableMapList->push_back (map);
}
//-------------------------------------------------------------------
void SamplerProceduralTerrainAppearanceCacheNamespace::debugDump ()
{
#ifdef _DEBUG
DEBUG_FATAL (!ms_installed, ("not installed"));
NOT_NULL (ms_vertexListList);
NOT_NULL (ms_planeListList);
NOT_NULL (ms_shaderMapList);
NOT_NULL (ms_floraMapList);
NOT_NULL (ms_passableMapList);
DEBUG_REPORT_PRINT (ms_debugReport, ("vertexListList size = %i\n", ms_vertexListList->size ()));
DEBUG_REPORT_PRINT (ms_debugReport, ("planeListList size = %i\n", ms_planeListList->size ()));
DEBUG_REPORT_PRINT (ms_debugReport, ("shaderMapList size = %i\n", ms_shaderMapList->size ()));
DEBUG_REPORT_PRINT (ms_debugReport, ("floraMapList size = %i\n", ms_floraMapList->size ()));
DEBUG_REPORT_PRINT (ms_debugReport, ("passableMapList size = %i\n", ms_passableMapList->size ()));
#endif
}
//==================================================================
@@ -0,0 +1,53 @@
//==================================================================
//
// SamplerProceduralTerrainAppearance_Cache.h
// asommers
//
// copyright 2002, sony online entertainment
//
//==================================================================
#ifndef INCLUDED_SamplerProceduralTerrainAppearance_Cache_H
#define INCLUDED_SamplerProceduralTerrainAppearance_Cache_H
//==================================================================
#include "SamplerProceduralTerrainAppearance.h"
//==================================================================
class SamplerProceduralTerrainAppearance::Cache
{
public:
static void install ();
static void remove ();
static void warm (int vertexListSize, int planeListSize, int mapSize);
static ArrayList<Vector>* createVertexList (int size);
static void destroyVertexList (ArrayList<Vector>* vertexList);
static ArrayList<Plane>* createPlaneList (int size);
static void destroyPlaneList (ArrayList<Plane>* planeList);
static Array2d<ShaderGroup::Info>* createShaderMap (int width, int height);
static void destroyShaderMap (Array2d<ShaderGroup::Info>* map);
static Array2d<FloraGroup::Info>* createFloraMap (int width, int height);
static void destroyFloraMap (Array2d<FloraGroup::Info>* map);
static Array2d<bool>* createPassableMap (int width, int height);
static void destroyPassableMap (Array2d<bool>* map);
private:
Cache ();
~Cache ();
Cache (const Cache&);
Cache& operator= (const Cache&);
};
//==================================================================
#endif
@@ -0,0 +1,161 @@
//===================================================================
//
// ServerProceduralTerrainAppearance.h
// asommers
//
// copyright 2000, verant interactive
//
//===================================================================
#ifndef INCLUDED_ServerProceduralTerrainAppearance_h
#define INCLUDED_ServerProceduralTerrainAppearance_h
//===================================================================
#include "sharedFoundation/MemoryBlockManagerMacros.h"
#include "sharedMath/SphereTree.h"
#include "sharedTerrain/ProceduralTerrainAppearance.h"
class Plane;
class MemoryBlockManager;
//===================================================================
class ServerProceduralTerrainAppearance : public ProceduralTerrainAppearance
{
public:
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//
// Chunk defines a chunk of terrain in the terrain system
//
class ServerChunk : public ProceduralTerrainAppearance::Chunk
{
MEMORY_BLOCK_MANAGER_INTERFACE_WITHOUT_INSTALL;
protected:
// indexList is a list of triplets indexing the vertex positions used in each triangle of the chunk.
static ArrayList<int>* ms_indexList;
protected:
// vertexList is a list of 3D positions for the chunk's height poles. size is (numberOfHeightPoles-2)^2
ArrayList<Vector>* m_vertexList;
// planeList is a list of planes corresponding to the above triangles
ArrayList<Plane>* m_planeList;
time_t m_timeStamp;
private:
static void createIndexList (int numberOfTilesPerChunk, int actualNumberOfPoles);
private:
ServerChunk ();
ServerChunk (const ServerChunk& rhs);
ServerChunk& operator= (const ServerChunk& rhs);
public:
static void install ();
static void remove ();
static bool compareTimestampsGreater(ServerChunk const * lhs, ServerChunk const * rhs);
public:
explicit ServerChunk (ProceduralTerrainAppearance& proceduralTerrainAppearance);
virtual ~ServerChunk ();
virtual bool getHeightAt (const Vector& worldPos, float* height) const;
virtual bool getHeightAt (const Vector& worldPos, float* height, Vector* normal) const;
virtual bool collide(Vector const & start_o, Vector const & end_o, CollideParameters const & collideParameters, CollisionInfo & result) const;
virtual int getChunkMemorySize () const;
void create (const ProceduralTerrainAppearance::CreateChunkData& newCreateChunkData);
void writeChunkData (const char* filename) const;
};
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
class Cache;
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
public:
ServerProceduralTerrainAppearance (const ProceduralTerrainAppearanceTemplate* appearanceTemplate);
virtual ~ServerProceduralTerrainAppearance ();
virtual float alter (float time);
virtual void render () const;
virtual void writeChunkData (int chunkX, int chunkZ) const;
virtual int getTerrainType (const Vector& position_o) const;
virtual void invalidateRegion (const Rectangle2d& extent2d);
virtual bool collide(Vector const & start_o, Vector const & end_o, CollideParameters const & collideParameters, CollisionInfo & result) const;
virtual bool collideForceChunkCreation (Vector const & start_o, Vector const & end_o, CollisionInfo & result);
virtual int getNumberOfChunks () const;
virtual bool hasHighLevelOfDetailTerrain (const Vector& position_o) const;
virtual void purgeChunks();
protected:
typedef stdmap<uint32, Chunk const *>::fwd ChunkMap;
typedef stdvector<Chunk const *>::fwd ChunkList;
typedef stdvector<ServerChunk const *>::fwd ServerChunkList;
typedef stdset<uint32>::fwd ChunkSet;
protected:
virtual void createChunk (int x, int z, int chunkSize, unsigned hasLargerNeighborFlags);
virtual void removeUnnecessaryChunk ();
virtual void addChunk (Chunk* chunk, int chunkSize);
virtual const Chunk* findChunk (int x, int z, int chunkSize) const;
virtual const Chunk* findFirstRenderableChunk (int x, int z) const;
virtual const Chunk* findAnyChunk () const;
virtual uint32 computeChunkMapKey (int x, int z) const;
virtual void prepareForDelete (Chunk const * chunk);
void generateBetween(Vector const & start_o, Vector const & end_o, ChunkList & chunkList);
bool collideChunkList(ChunkList const & chunkList, Vector const & start_o, Vector const & end_o, CollisionInfo & result) const;
protected:
ChunkMap* const m_chunkMap;
private:
class ChunkSphereExtentAccessor: public BaseSphereTreeAccessor<Chunk const *, ChunkSphereExtentAccessor>
{
public:
static Sphere const getExtent (Chunk const * chunk);
static char const * getDebugName (Chunk const * chunk);
};
class CollisionChunkSorter;
private:
ServerProceduralTerrainAppearance ();
ServerProceduralTerrainAppearance (const ServerProceduralTerrainAppearance&);
ServerProceduralTerrainAppearance& operator= (const ServerProceduralTerrainAppearance&);
private:
int m_chunkMapKeyOffset;
ServerChunkList* const m_highUsedChunkList;
ServerChunkList* const m_lowUsedChunkList;
ServerChunkList* const m_unusedChunkList;
ChunkList* const m_invalidateChunkList;
ChunkSet* const m_chunksCreatedThisFrame;
SphereTree<Chunk const *, ChunkSphereExtentAccessor> m_sphereTree;
};
//===================================================================
#endif
@@ -0,0 +1,78 @@
//===================================================================
//
// ServerProceduralTerrainAppearanceTemplate.cpp
// asommers
//
// copyright 2000, verant interactive
//
//===================================================================
#include "sharedTerrain/FirstSharedTerrain.h"
#include "sharedTerrain/ServerProceduralTerrainAppearanceTemplate.h"
#include "sharedFoundation/ExitChain.h"
#include "sharedObject/AppearanceTemplateList.h"
#include "sharedTerrain/ConfigSharedTerrain.h"
#include "sharedTerrain/ServerProceduralTerrainAppearance.h"
//===================================================================
void ServerProceduralTerrainAppearanceTemplate::install ()
{
DEBUG_REPORT_LOG_PRINT (ConfigSharedTerrain::getDebugReportInstall (), ("ServerProceduralTerrainAppearanceTemplate::install\n"));
AppearanceTemplateList::assignBinding (TAG (M,P,T,A), ServerProceduralTerrainAppearanceTemplate::create);
AppearanceTemplateList::assignBinding (TAG (P,T,A,T), ServerProceduralTerrainAppearanceTemplate::create);
ExitChain::add (remove, "ServerProceduralTerrainAppearanceTemplate::remove");
}
//-------------------------------------------------------------------
void ServerProceduralTerrainAppearanceTemplate::remove ()
{
AppearanceTemplateList::removeBinding (TAG (M,P,T,A));
AppearanceTemplateList::removeBinding (TAG (P,T,A,T));
}
//-------------------------------------------------------------------
AppearanceTemplate* ServerProceduralTerrainAppearanceTemplate::create (const char* filename, Iff* iff)
{
return new ServerProceduralTerrainAppearanceTemplate (filename, iff);
}
//===================================================================
ServerProceduralTerrainAppearanceTemplate::ServerProceduralTerrainAppearanceTemplate (const char* filename, Iff* iff) :
ProceduralTerrainAppearanceTemplate (filename, iff, false, 0, 2)
{
unsigned mapsToSample =
TGM_vertexPosition
| TGM_shader
| TGM_passable
| TGM_exclude
;
if (getLegacyMode())
{
mapsToSample|=TGM_floraStaticCollidable;
}
m_terrainGenerator->setMapsToSample(mapsToSample);
}
//-------------------------------------------------------------------
ServerProceduralTerrainAppearanceTemplate::~ServerProceduralTerrainAppearanceTemplate ()
{
}
//-------------------------------------------------------------------
Appearance* ServerProceduralTerrainAppearanceTemplate::createAppearance () const
{
return new ServerProceduralTerrainAppearance (this);
}
//===================================================================
@@ -0,0 +1,50 @@
//===================================================================
//
// ServerProceduralTerrainAppearanceTemplate.h
// asommers
//
// copyright 2000, verant interactive
//
//===================================================================
#ifndef INCLUDED_ServerProceduralTerrainAppearanceTemplate_h
#define INCLUDED_ServerProceduralTerrainAppearanceTemplate_h
//===================================================================
#include "sharedTerrain/ProceduralTerrainAppearanceTemplate.h"
class Iff;
//===================================================================
class ServerProceduralTerrainAppearanceTemplate : public ProceduralTerrainAppearanceTemplate
{
public:
static void install ();
static AppearanceTemplate* create (const char* filename, Iff* iff);
public:
ServerProceduralTerrainAppearanceTemplate (const char* filename, Iff* iff);
virtual ~ServerProceduralTerrainAppearanceTemplate ();
virtual Appearance* createAppearance () const;
private:
static void remove ();
private:
ServerProceduralTerrainAppearanceTemplate ();
ServerProceduralTerrainAppearanceTemplate (const ServerProceduralTerrainAppearanceTemplate&);
ServerProceduralTerrainAppearanceTemplate& operator= (const ServerProceduralTerrainAppearanceTemplate&);
};
//===================================================================
#endif
@@ -0,0 +1,334 @@
//==================================================================
//
// ServerProceduralTerrainAppearance_Cache.cpp
// asommers
//
// copyright 2002, sony online entertainment
//
//==================================================================
#include "sharedTerrain/FirstSharedTerrain.h"
#include "sharedTerrain/ServerProceduralTerrainAppearance_Cache.h"
#include "sharedDebug/DebugFlags.h"
#include "sharedFoundation/PointerDeleter.h"
#include "sharedMath/Plane.h"
#include "sharedTerrain/ConfigSharedTerrain.h"
#include <algorithm>
#include <vector>
//==================================================================
namespace ServerProceduralTerrainAppearanceCacheNamespace
{
typedef std::vector<ArrayList<Vector>*> VertexListList;
typedef std::vector<ArrayList<Plane>*> PlaneListList;
typedef std::vector<Array2d<ShaderGroup::Info>*> ShaderGroupList;
typedef std::vector<Array2d<FloraGroup::Info>*> FloraGroupList;
bool ms_installed;
uint ms_preloadSize = 2048;
VertexListList* ms_vertexListList;
PlaneListList* ms_planeListList;
ShaderGroupList* ms_shaderMapList;
FloraGroupList* ms_floraMapList;
#ifdef _DEBUG
bool ms_debugReport;
#endif
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void debugDump ();
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ArrayList<Vector>* localCreateVertexList (const int size)
{
ArrayList<Vector>* const vertexList = new ArrayList<Vector>;
vertexList->preallocate (size, true);
return vertexList;
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ArrayList<Plane>* localCreatePlaneList (const int size)
{
ArrayList<Plane>* const planeList = new ArrayList<Plane>;
planeList->preallocate (size, true);
return planeList;
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Array2d<ShaderGroup::Info>* localCreateShaderMap (const int width, const int height)
{
Array2d<ShaderGroup::Info>* const map = new Array2d<ShaderGroup::Info>;
map->allocate (width, height);
return map;
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Array2d<FloraGroup::Info>* localCreateFloraMap (const int width, const int height)
{
Array2d<FloraGroup::Info>* const map = new Array2d<FloraGroup::Info>;
map->allocate (width, height);
return map;
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
}
using namespace ServerProceduralTerrainAppearanceCacheNamespace;
//==================================================================
void ServerProceduralTerrainAppearance::Cache::install ()
{
DEBUG_REPORT_LOG_PRINT (ConfigSharedTerrain::getDebugReportInstall (), ("ServerProceduralTerrainAppearance::Cache::install\n"));
DEBUG_FATAL (ms_installed, ("already installed"));
ms_installed = true;
ms_preloadSize = static_cast<uint> (ConfigSharedTerrain::getMaximumNumberOfChunksAllowed ());
//-- can't precreate maps because we don't know what size they will be
ms_vertexListList = new VertexListList;
ms_planeListList = new PlaneListList;
ms_shaderMapList = new ShaderGroupList;
ms_floraMapList = new FloraGroupList;
#ifdef _DEBUG
DebugFlags::registerFlag (ServerProceduralTerrainAppearanceCacheNamespace::ms_debugReport, "SharedTerrain", "reportServerProceduralTerrainAppearanceCache", ServerProceduralTerrainAppearanceCacheNamespace::debugDump);
#endif
}
//-------------------------------------------------------------------
void ServerProceduralTerrainAppearance::Cache::remove ()
{
DEBUG_FATAL (!ms_installed, ("not installed"));
ms_installed = false;
//-- delete non-array lists
#define DELETE_SPECIFIC_LIST(a) { \
DEBUG_REPORT_LOG_PRINT (ConfigSharedTerrain::getDebugReportLogPrint (), ("Terrain Cache %sList = %i\n", #a, ms_ ## a ## List->size ())); \
std::for_each (ms_ ## a ## List->begin (), ms_ ## a ## List->end (), PointerDeleter ()); \
delete ms_ ## a ## List; \
ms_ ## a ## List = 0; \
}
DELETE_SPECIFIC_LIST (vertexList);
DELETE_SPECIFIC_LIST (planeList);
DELETE_SPECIFIC_LIST (shaderMap);
DELETE_SPECIFIC_LIST (floraMap);
#ifdef _DEBUG
DebugFlags::unregisterFlag (ServerProceduralTerrainAppearanceCacheNamespace::ms_debugReport);
#endif
}
//-------------------------------------------------------------------
void ServerProceduralTerrainAppearance::Cache::warm (const int vertexListSize, const int planeListSize, const int mapSize)
{
NOT_NULL (ms_vertexListList);
ms_vertexListList->reserve (ms_preloadSize);
NOT_NULL (ms_planeListList);
ms_planeListList->reserve (ms_preloadSize);
NOT_NULL (ms_shaderMapList);
ms_shaderMapList->reserve (ms_preloadSize);
NOT_NULL (ms_floraMapList);
ms_floraMapList->reserve (ms_preloadSize);
uint i;
for (i = 0; i < ms_preloadSize; ++i)
{
ms_vertexListList->push_back (localCreateVertexList (vertexListSize));
ms_planeListList->push_back (localCreatePlaneList (planeListSize));
ms_shaderMapList->push_back (localCreateShaderMap (mapSize, mapSize));
ms_floraMapList->push_back (localCreateFloraMap (mapSize, mapSize));
}
}
//-------------------------------------------------------------------
ArrayList<Vector>* ServerProceduralTerrainAppearance::Cache::createVertexList (const int size)
{
DEBUG_FATAL (!ms_installed, ("not installed"));
NOT_NULL (ms_vertexListList);
ArrayList<Vector>* vertexList = 0;
//-- just take one off the list
if (!ms_vertexListList->empty ())
{
vertexList = ms_vertexListList->back ();
ms_vertexListList->pop_back ();
}
else
{
//-- create one
vertexList = localCreateVertexList (size);
}
NOT_NULL (vertexList);
return vertexList;
}
//-------------------------------------------------------------------
void ServerProceduralTerrainAppearance::Cache::destroyVertexList (ArrayList<Vector>* const vertexList)
{
DEBUG_FATAL (!ms_installed, ("not installed"));
NOT_NULL (ms_vertexListList);
if (vertexList)
ms_vertexListList->push_back (vertexList);
}
//-------------------------------------------------------------------
ArrayList<Plane>* ServerProceduralTerrainAppearance::Cache::createPlaneList (const int size)
{
DEBUG_FATAL (!ms_installed, ("not installed"));
NOT_NULL (ms_planeListList);
ArrayList<Plane>* planeList = 0;
//-- just take one off the list
if (!ms_planeListList->empty ())
{
planeList = ms_planeListList->back ();
ms_planeListList->pop_back ();
}
else
{
//-- create one
planeList = localCreatePlaneList (size);
}
NOT_NULL (planeList);
return planeList;
}
//-------------------------------------------------------------------
void ServerProceduralTerrainAppearance::Cache::destroyPlaneList (ArrayList<Plane>* const planeList)
{
DEBUG_FATAL (!ms_installed, ("not installed"));
NOT_NULL (ms_planeListList);
if (planeList)
ms_planeListList->push_back (planeList);
}
//-------------------------------------------------------------------
Array2d<ShaderGroup::Info>* ServerProceduralTerrainAppearance::Cache::createShaderMap (int width, int height)
{
DEBUG_FATAL (!ms_installed, ("not installed"));
NOT_NULL (ms_shaderMapList);
Array2d<ShaderGroup::Info>* map = 0;
//-- just take one off the list
if (!ms_shaderMapList->empty ())
{
map = ms_shaderMapList->back ();
ms_shaderMapList->pop_back ();
}
else
{
//-- create one
map = localCreateShaderMap (width, height);
}
NOT_NULL (map);
DEBUG_FATAL (width != map->getWidth () && height != map->getHeight (), ("ServerProceduralTerrainAppearance::Cache - cached map of wrong size"));
return map;
}
//-------------------------------------------------------------------
void ServerProceduralTerrainAppearance::Cache::destroyShaderMap (Array2d<ShaderGroup::Info>* map)
{
DEBUG_FATAL (!ms_installed, ("not installed"));
NOT_NULL (ms_shaderMapList);
if (map)
ms_shaderMapList->push_back (map);
}
//-------------------------------------------------------------------
Array2d<FloraGroup::Info>* ServerProceduralTerrainAppearance::Cache::createFloraMap (int width, int height)
{
DEBUG_FATAL (!ms_installed, ("not installed"));
NOT_NULL (ms_floraMapList);
Array2d<FloraGroup::Info>* map = 0;
//-- just take one off the list
if (!ms_floraMapList->empty ())
{
map = ms_floraMapList->back ();
ms_floraMapList->pop_back ();
}
else
{
//-- create one
map = localCreateFloraMap (width, height);
}
NOT_NULL (map);
DEBUG_FATAL (width != map->getWidth () && height != map->getHeight (), ("ServerProceduralTerrainAppearance::Cache - cached map of wrong size"));
return map;
}
//-------------------------------------------------------------------
void ServerProceduralTerrainAppearance::Cache::destroyFloraMap (Array2d<FloraGroup::Info>* map)
{
DEBUG_FATAL (!ms_installed, ("not installed"));
NOT_NULL (ms_floraMapList);
if (map)
ms_floraMapList->push_back (map);
}
//-------------------------------------------------------------------
void ServerProceduralTerrainAppearanceCacheNamespace::debugDump ()
{
#ifdef _DEBUG
DEBUG_FATAL (!ms_installed, ("not installed"));
NOT_NULL (ms_vertexListList);
NOT_NULL (ms_planeListList);
NOT_NULL (ms_shaderMapList);
NOT_NULL (ms_floraMapList);
DEBUG_REPORT_PRINT (ms_debugReport, ("vertexListList size = %i\n", ms_vertexListList->size ()));
DEBUG_REPORT_PRINT (ms_debugReport, ("planeListList size = %i\n", ms_planeListList->size ()));
DEBUG_REPORT_PRINT (ms_debugReport, ("shaderMapList size = %i\n", ms_shaderMapList->size ()));
DEBUG_REPORT_PRINT (ms_debugReport, ("floraMapList size = %i\n", ms_floraMapList->size ()));
#endif
}
//==================================================================
@@ -0,0 +1,50 @@
//==================================================================
//
// ServerProceduralTerrainAppearance_Cache.h
// asommers
//
// copyright 2002, sony online entertainment
//
//==================================================================
#ifndef INCLUDED_ServerProceduralTerrainAppearance_Cache_H
#define INCLUDED_ServerProceduralTerrainAppearance_Cache_H
//==================================================================
#include "sharedTerrain/ServerProceduralTerrainAppearance.h"
//==================================================================
class ServerProceduralTerrainAppearance::Cache
{
public:
static void install ();
static void remove ();
static void warm (int vertexListSize, int planeListSize, int mapSize);
static ArrayList<Vector>* createVertexList (int size);
static void destroyVertexList (ArrayList<Vector>* vertexList);
static ArrayList<Plane>* createPlaneList (int size);
static void destroyPlaneList (ArrayList<Plane>* planeList);
static Array2d<ShaderGroup::Info>* createShaderMap (int width, int height);
static void destroyShaderMap (Array2d<ShaderGroup::Info>* map);
static Array2d<FloraGroup::Info>* createFloraMap (int width, int height);
static void destroyFloraMap (Array2d<FloraGroup::Info>* map);
private:
Cache ();
~Cache ();
Cache (const Cache&);
Cache& operator= (const Cache&);
};
//==================================================================
#endif
@@ -0,0 +1,30 @@
// ======================================================================
//
// ServerSpaceTerrainAppearance.cpp
// asommers
//
// copyright 2004, sony online entertainment
//
// ======================================================================
#include "sharedTerrain/FirstSharedTerrain.h"
#include "sharedTerrain/ServerSpaceTerrainAppearance.h"
#include "sharedTerrain/ServerSpaceTerrainAppearanceTemplate.h"
// ======================================================================
// PUBLIC ServerSpaceTerrainAppearance
// ======================================================================
ServerSpaceTerrainAppearance::ServerSpaceTerrainAppearance(ServerSpaceTerrainAppearanceTemplate const * const serverSpaceTerrainAppearanceTemplate) :
SpaceTerrainAppearance(serverSpaceTerrainAppearanceTemplate)
{
}
// ----------------------------------------------------------------------
ServerSpaceTerrainAppearance::~ServerSpaceTerrainAppearance()
{
}
// ======================================================================
@@ -0,0 +1,37 @@
// ======================================================================
//
// ServerSpaceTerrainAppearance.h
// asommers
//
// copyright 2004, sony online entertainment
//
// ======================================================================
#ifndef INCLUDED_ServerSpaceTerrainAppearance_H
#define INCLUDED_ServerSpaceTerrainAppearance_H
// ======================================================================
#include "sharedTerrain/SpaceTerrainAppearance.h"
class ServerSpaceTerrainAppearanceTemplate;
// ======================================================================
class ServerSpaceTerrainAppearance : public SpaceTerrainAppearance
{
public:
explicit ServerSpaceTerrainAppearance(ServerSpaceTerrainAppearanceTemplate const * serverSpaceTerrainAppearanceTemplate);
virtual ~ServerSpaceTerrainAppearance();
private:
ServerSpaceTerrainAppearance();
ServerSpaceTerrainAppearance(ServerSpaceTerrainAppearance const &);
ServerSpaceTerrainAppearance & operator=(ServerSpaceTerrainAppearance const &);
};
// ======================================================================
#endif
@@ -0,0 +1,67 @@
// ======================================================================
//
// ServerSpaceTerrainAppearanceTemplate.cpp
// asommers
//
// copyright 2004, sony online entertainment
//
// ======================================================================
#include "sharedTerrain/FirstSharedTerrain.h"
#include "sharedTerrain/ServerSpaceTerrainAppearanceTemplate.h"
#include "sharedFoundation/ExitChain.h"
#include "sharedObject/AppearanceTemplateList.h"
#include "sharedTerrain/ServerSpaceTerrainAppearance.h"
// ======================================================================
// STATIC PUBLIC ServerSpaceTerrainAppearanceTemplate
// ======================================================================
void ServerSpaceTerrainAppearanceTemplate::install()
{
AppearanceTemplateList::assignBinding(cms_spaceTerrainAppearanceTemplateTag, ServerSpaceTerrainAppearanceTemplate::create);
ExitChain::add(ServerSpaceTerrainAppearanceTemplate::remove, "ServerSpaceTerrainAppearanceTemplate::remove");
}
// ----------------------------------------------------------------------
AppearanceTemplate * ServerSpaceTerrainAppearanceTemplate::create(char const * const filename, Iff * const iff)
{
return new ServerSpaceTerrainAppearanceTemplate(filename, iff);
}
// ======================================================================
// PUBLIC ServerSpaceTerrainAppearanceTemplate
// ======================================================================
ServerSpaceTerrainAppearanceTemplate::ServerSpaceTerrainAppearanceTemplate(char const * const filename, Iff * const iff) :
SpaceTerrainAppearanceTemplate(filename, iff)
{
}
// ----------------------------------------------------------------------
ServerSpaceTerrainAppearanceTemplate::~ServerSpaceTerrainAppearanceTemplate()
{
}
// ----------------------------------------------------------------------
Appearance * ServerSpaceTerrainAppearanceTemplate::createAppearance() const
{
return new ServerSpaceTerrainAppearance(this);
}
// ======================================================================
// STATIC PRIVATE ServerSpaceTerrainAppearanceTemplate
// ======================================================================
void ServerSpaceTerrainAppearanceTemplate::remove()
{
AppearanceTemplateList::removeBinding(cms_spaceTerrainAppearanceTemplateTag);
}
// ======================================================================
@@ -0,0 +1,50 @@
// ======================================================================
//
// ServerSpaceTerrainAppearanceTemplate.h
// asommers
//
// copyright 2004, sony online entertainment
//
// ======================================================================
#ifndef INCLUDED_ServerSpaceTerrainAppearanceTemplate_H
#define INCLUDED_ServerSpaceTerrainAppearanceTemplate_H
// ======================================================================
#include "sharedTerrain/SpaceTerrainAppearanceTemplate.h"
class Iff;
// ======================================================================
class ServerSpaceTerrainAppearanceTemplate : public SpaceTerrainAppearanceTemplate
{
public:
static void install();
static AppearanceTemplate * create(char const * filename, Iff * iff);
public:
ServerSpaceTerrainAppearanceTemplate(char const * filename, Iff * iff);
virtual ~ServerSpaceTerrainAppearanceTemplate();
virtual Appearance * createAppearance() const;
private:
static void remove();
private:
ServerSpaceTerrainAppearanceTemplate();
ServerSpaceTerrainAppearanceTemplate(ServerSpaceTerrainAppearanceTemplate const &);
ServerSpaceTerrainAppearanceTemplate & operator=(ServerSpaceTerrainAppearanceTemplate const &);
};
// ======================================================================
#endif
@@ -0,0 +1,38 @@
// ======================================================================
//
// SpaceTerrainAppearance.cpp
// asommers
//
// copyright 2004, sony online entertainment
//
// ======================================================================
#include "sharedTerrain/FirstSharedTerrain.h"
#include "sharedTerrain/SpaceTerrainAppearance.h"
#include "sharedTerrain/SpaceTerrainAppearanceTemplate.h"
// ======================================================================
// PUBLIC SpaceTerrainAppearance
// ======================================================================
SpaceTerrainAppearance::SpaceTerrainAppearance(SpaceTerrainAppearanceTemplate const * const spaceTerrainAppearanceTemplate) :
TerrainAppearance(spaceTerrainAppearanceTemplate)
{
}
// ----------------------------------------------------------------------
SpaceTerrainAppearance::~SpaceTerrainAppearance()
{
}
// ----------------------------------------------------------------------
float SpaceTerrainAppearance::getMapWidthInMeters() const
{
SpaceTerrainAppearanceTemplate const * const stat = safe_cast<SpaceTerrainAppearanceTemplate const *>(getAppearanceTemplate());
return stat->getMapWidthInMeters();
}
// ======================================================================
@@ -0,0 +1,39 @@
// ======================================================================
//
// SpaceTerrainAppearance.h
// asommers
//
// copyright 2004, sony online entertainment
//
// ======================================================================
#ifndef INCLUDED_SpaceTerrainAppearance_H
#define INCLUDED_SpaceTerrainAppearance_H
// ======================================================================
#include "sharedTerrain/TerrainAppearance.h"
class SpaceTerrainAppearanceTemplate;
// ======================================================================
class SpaceTerrainAppearance : public TerrainAppearance
{
public:
SpaceTerrainAppearance(SpaceTerrainAppearanceTemplate const * spaceTerrainAppearanceTemplate);
virtual ~SpaceTerrainAppearance();
virtual float getMapWidthInMeters() const;
private:
SpaceTerrainAppearance();
SpaceTerrainAppearance(SpaceTerrainAppearance const &);
SpaceTerrainAppearance & operator=(SpaceTerrainAppearance const &);
};
// ======================================================================
#endif
@@ -0,0 +1,565 @@
// ======================================================================
//
// SpaceTerrainAppearanceTemplate.cpp
// asommers
//
// copyright 2004, sony online entertainment
//
// ======================================================================
#include "sharedTerrain/FirstSharedTerrain.h"
#include "sharedTerrain/SpaceTerrainAppearanceTemplate.h"
#include "sharedFile/Iff.h"
#include <string>
#include <vector>
// ======================================================================
namespace SpaceTerrainAppearanceTemplateNamespace
{
Tag const TAG_AMBI = TAG(A,M,B,I);
Tag const TAG_CELE = TAG(C,E,L,E);
Tag const TAG_CLEA = TAG(C,L,E,A);
Tag const TAG_DIST = TAG(D,I,S,T);
Tag const TAG_DUST = TAG(D,U,S,T);
Tag const TAG_ENVI = TAG(E,N,V,I);
Tag const TAG_FOG = TAG3(F,O,G);
Tag const TAG_PARA = TAG(P,A,R,A);
Tag const TAG_PLAN = TAG(P,L,A,N);
Tag const TAG_STAR = TAG(S,T,A,R);
Tag const TAG_SKYB = TAG(S,K,Y,B);
}
using namespace SpaceTerrainAppearanceTemplateNamespace;
// ======================================================================
// PUBLIC SpaceTerrainAppearanceTemplate
// ======================================================================
SpaceTerrainAppearanceTemplate::SpaceTerrainAppearanceTemplate(char const * const filename, Iff * const iff) :
AppearanceTemplate(filename),
m_clearColor(),
m_ambientColor(),
m_lightDataList(new LightDataList),
m_environmentTextureName(),
m_fogEnabled(false),
m_fogColor(),
m_fogDensity(0.f),
m_numberOfStars(0),
m_starColorRampName(),
m_numberOfDust(0),
m_dustRadius(0.f),
m_skyBoxCubeMap(false),
m_skyBoxTextureNameMask(),
m_celestialDataList(new CelestialDataList),
m_distantAppearanceDataList(new DistantAppearanceDataList),
m_mapWidthInMeters(16384.0f)
{
NOT_NULL(iff);
load(*iff);
}
// ----------------------------------------------------------------------
SpaceTerrainAppearanceTemplate::~SpaceTerrainAppearanceTemplate()
{
delete m_lightDataList;
delete m_celestialDataList;
delete m_distantAppearanceDataList;
}
// ----------------------------------------------------------------------
PackedRgb const & SpaceTerrainAppearanceTemplate::getClearColor() const
{
return m_clearColor;
}
// ----------------------------------------------------------------------
VectorArgb const & SpaceTerrainAppearanceTemplate::getAmbientColor() const
{
return m_ambientColor;
}
// ----------------------------------------------------------------------
int SpaceTerrainAppearanceTemplate::getNumberOfParallelLights() const
{
NOT_NULL(m_lightDataList);
return static_cast<int>(m_lightDataList->size());
}
// ----------------------------------------------------------------------
VectorArgb const & SpaceTerrainAppearanceTemplate::getParallelLightDiffuseColor(int const index) const
{
VALIDATE_RANGE_INCLUSIVE_EXCLUSIVE(0, index, getNumberOfParallelLights());
return (*m_lightDataList)[static_cast<size_t>(index)].m_diffuseColor;
}
// ----------------------------------------------------------------------
VectorArgb const & SpaceTerrainAppearanceTemplate::getParallelLightSpecularColor(int const index) const
{
VALIDATE_RANGE_INCLUSIVE_EXCLUSIVE(0, index, getNumberOfParallelLights());
return (*m_lightDataList)[static_cast<size_t>(index)].m_specularColor;
}
// ----------------------------------------------------------------------
Vector const & SpaceTerrainAppearanceTemplate::getParallelLightDirection_w(int const index) const
{
VALIDATE_RANGE_INCLUSIVE_EXCLUSIVE(0, index, getNumberOfParallelLights());
return (*m_lightDataList)[static_cast<size_t>(index)].m_direction_w;
}
// ----------------------------------------------------------------------
CrcString const & SpaceTerrainAppearanceTemplate::getEnvironmentTextureName() const
{
return m_environmentTextureName;
}
// ----------------------------------------------------------------------
bool SpaceTerrainAppearanceTemplate::getFogEnabled() const
{
return m_fogEnabled;
}
// ----------------------------------------------------------------------
PackedArgb const & SpaceTerrainAppearanceTemplate::getFogColor() const
{
return m_fogColor;
}
// ----------------------------------------------------------------------
float SpaceTerrainAppearanceTemplate::getFogDensity() const
{
return m_fogDensity;
}
// ----------------------------------------------------------------------
int SpaceTerrainAppearanceTemplate::getNumberOfStars() const
{
return m_numberOfStars;
}
// ----------------------------------------------------------------------
CrcString const & SpaceTerrainAppearanceTemplate::getStarColorRampName() const
{
return m_starColorRampName;
}
// ----------------------------------------------------------------------
int SpaceTerrainAppearanceTemplate::getNumberOfDust() const
{
return m_numberOfDust;
}
// ----------------------------------------------------------------------
float SpaceTerrainAppearanceTemplate::getDustRadius() const
{
return m_dustRadius;
}
// ----------------------------------------------------------------------
bool SpaceTerrainAppearanceTemplate::getSkyBoxCubeMap() const
{
return m_skyBoxCubeMap;
}
// ----------------------------------------------------------------------
CrcString const & SpaceTerrainAppearanceTemplate::getSkyBoxTextureNameMask() const
{
return m_skyBoxTextureNameMask;
}
// ----------------------------------------------------------------------
int SpaceTerrainAppearanceTemplate::getNumberOfDistantAppearances() const
{
NOT_NULL(m_distantAppearanceDataList);
return static_cast<int>(m_distantAppearanceDataList->size());
}
// ----------------------------------------------------------------------
CrcString const & SpaceTerrainAppearanceTemplate::getDistantAppearanceTemplateName(int const index) const
{
VALIDATE_RANGE_INCLUSIVE_EXCLUSIVE(0, index, getNumberOfDistantAppearances());
return (*m_distantAppearanceDataList)[static_cast<size_t>(index)].m_appearanceTemplateName;
}
// ----------------------------------------------------------------------
Vector const & SpaceTerrainAppearanceTemplate::getDistantAppearanceDirection_w(int const index) const
{
VALIDATE_RANGE_INCLUSIVE_EXCLUSIVE(0, index, getNumberOfDistantAppearances());
return (*m_distantAppearanceDataList)[static_cast<size_t>(index)].m_direction_w;
}
// ----------------------------------------------------------------------
Vector const & SpaceTerrainAppearanceTemplate::getDistantAppearanceOrientation_w(int const index) const
{
VALIDATE_RANGE_INCLUSIVE_EXCLUSIVE(0, index, getNumberOfDistantAppearances());
return (*m_distantAppearanceDataList)[static_cast<size_t>(index)].m_orientation_w;
}
// ----------------------------------------------------------------------
float SpaceTerrainAppearanceTemplate::getPlanetHaloRoll(int const index) const
{
VALIDATE_RANGE_INCLUSIVE_EXCLUSIVE(0, index, getNumberOfDistantAppearances());
return (*m_distantAppearanceDataList)[static_cast<size_t>(index)].m_haloRoll;
}
// ----------------------------------------------------------------------
float SpaceTerrainAppearanceTemplate::getPlanetHaloScale(int const index) const
{
VALIDATE_RANGE_INCLUSIVE_EXCLUSIVE(0, index, getNumberOfDistantAppearances());
return (*m_distantAppearanceDataList)[static_cast<size_t>(index)].m_haloScale;
}
//----------------------------------------------------------------------
bool SpaceTerrainAppearanceTemplate::isDistantAppearanceInfiniteDistance(int const index) const
{
VALIDATE_RANGE_INCLUSIVE_EXCLUSIVE(0, index, getNumberOfDistantAppearances());
return (*m_distantAppearanceDataList)[static_cast<size_t>(index)].m_infiniteDistance;
}
// ----------------------------------------------------------------------
int SpaceTerrainAppearanceTemplate::getNumberOfCelestials() const
{
NOT_NULL(m_celestialDataList);
return static_cast<int>(m_celestialDataList->size());
}
// ----------------------------------------------------------------------
CrcString const & SpaceTerrainAppearanceTemplate::getCelestialBackShaderTemplateName(int const index) const
{
VALIDATE_RANGE_INCLUSIVE_EXCLUSIVE(0, index, getNumberOfCelestials());
return (*m_celestialDataList)[static_cast<size_t>(index)].m_backShaderTemplateName;
}
// ----------------------------------------------------------------------
float SpaceTerrainAppearanceTemplate::getCelestialBackSize(int const index) const
{
VALIDATE_RANGE_INCLUSIVE_EXCLUSIVE(0, index, getNumberOfCelestials());
return (*m_celestialDataList)[static_cast<size_t>(index)].m_backSize;
}
// ----------------------------------------------------------------------
CrcString const & SpaceTerrainAppearanceTemplate::getCelestialFrontShaderTemplateName(int const index) const
{
VALIDATE_RANGE_INCLUSIVE_EXCLUSIVE(0, index, getNumberOfCelestials());
return (*m_celestialDataList)[static_cast<size_t>(index)].m_frontShaderTemplateName;
}
// ----------------------------------------------------------------------
float SpaceTerrainAppearanceTemplate::getCelestialFrontSize(int const index) const
{
VALIDATE_RANGE_INCLUSIVE_EXCLUSIVE(0, index, getNumberOfCelestials());
return (*m_celestialDataList)[static_cast<size_t>(index)].m_frontSize;
}
// ----------------------------------------------------------------------
Vector const & SpaceTerrainAppearanceTemplate::getCelestialDirection_w(int const index) const
{
VALIDATE_RANGE_INCLUSIVE_EXCLUSIVE(0, index, getNumberOfCelestials());
return (*m_celestialDataList)[static_cast<size_t>(index)].m_direction_w;
}
// ======================================================================
// PROTECTED SpaceTerrainAppearanceTemplate
// ======================================================================
Tag const SpaceTerrainAppearanceTemplate::cms_spaceTerrainAppearanceTemplateTag = TAG(S,T,A,T);
// ======================================================================
// PRIVATE SpaceTerrainAppearanceTemplate
// ======================================================================
void SpaceTerrainAppearanceTemplate::load(Iff & iff)
{
iff.enterForm(cms_spaceTerrainAppearanceTemplateTag);
switch(iff.getCurrentName())
{
case TAG_0000:
load_0000(iff);
break;
default:
{
char tagBuffer[5];
ConvertTagToString(iff.getCurrentName(), tagBuffer);
char buffer[128];
iff.formatLocation(buffer, sizeof(buffer));
FATAL(true, ("SpaceTerrainAppearanceTemplate::load: unsupported version tag %s/%s", buffer, tagBuffer));
}
break;
}
iff.exitForm(cms_spaceTerrainAppearanceTemplateTag);
}
// ----------------------------------------------------------------------
void SpaceTerrainAppearanceTemplate::load_0000(Iff & iff)
{
iff.enterForm(TAG_0000);
while (iff.getNumberOfBlocksLeft())
{
switch (iff.getCurrentName())
{
case TAG_INFO:
{
iff.enterForm(TAG_INFO);
{
iff.enterChunk(TAG_0000);
{
m_mapWidthInMeters = iff.read_float();
}
iff.exitChunk(TAG_0000);
}
iff.exitForm(TAG_INFO);
}
break;
case TAG_CLEA:
{
iff.enterForm(TAG_CLEA);
iff.enterChunk(TAG_0000);
m_clearColor.r = static_cast<uint8>(clamp(0.f, iff.read_float(), 1.f) * 255.f);
m_clearColor.g = static_cast<uint8>(clamp(0.f, iff.read_float(), 1.f) * 255.f);
m_clearColor.b = static_cast<uint8>(clamp(0.f, iff.read_float(), 1.f) * 255.f);
iff.exitChunk(TAG_0000);
iff.exitForm(TAG_CLEA);
}
break;
case TAG_AMBI:
{
iff.enterForm(TAG_AMBI);
iff.enterChunk(TAG_0000);
m_ambientColor = iff.read_floatVectorArgb();
iff.exitChunk(TAG_0000);
iff.exitForm(TAG_AMBI);
}
break;
case TAG_PARA:
{
iff.enterForm(TAG_PARA);
iff.enterChunk(TAG_0000);
LightData lightData;
lightData.m_dot3 = iff.read_bool8();
lightData.m_diffuseColor = iff.read_floatVectorArgb();
lightData.m_specularColor = iff.read_floatVectorArgb();
lightData.m_direction_w = iff.read_floatVector();
m_lightDataList->push_back(lightData);
iff.exitChunk(TAG_0000);
iff.exitForm(TAG_PARA);
}
break;
case TAG_ENVI:
{
iff.enterForm(TAG_ENVI);
iff.enterChunk(TAG_0000);
std::string environmentTextureName;
iff.read_string(environmentTextureName);
m_environmentTextureName.set(environmentTextureName.c_str(), true);
iff.exitChunk(TAG_0000);
iff.exitForm(TAG_ENVI);
}
break;
case TAG_FOG:
{
iff.enterForm(TAG_FOG);
iff.enterChunk(TAG_0000);
m_fogEnabled = true;
VectorArgb const fogColor = iff.read_floatVectorArgb();
m_fogColor.setArgb(fogColor);
m_fogDensity = fogColor.a;
iff.exitChunk(TAG_0000);
iff.exitForm(TAG_FOG);
}
break;
case TAG_STAR:
{
iff.enterForm(TAG_STAR);
iff.enterChunk(TAG_0000);
std::string starColorRampName;
iff.read_string(starColorRampName);
m_starColorRampName.set(starColorRampName.c_str(), true);
m_numberOfStars = iff.read_int32();
iff.exitChunk(TAG_0000);
iff.exitForm(TAG_STAR);
}
break;
case TAG_DUST:
{
iff.enterForm(TAG_DUST);
iff.enterChunk(TAG_0000);
m_numberOfDust = iff.read_int32();
m_dustRadius = iff.read_float();
iff.exitChunk(TAG_0000);
iff.exitForm(TAG_DUST);
}
break;
case TAG_SKYB:
{
iff.enterForm(TAG_SKYB);
iff.enterChunk(TAG_0000);
m_skyBoxCubeMap = iff.read_bool8();
std::string textureNameMask;
iff.read_string(textureNameMask);
m_skyBoxTextureNameMask.set(textureNameMask.c_str(), true);
iff.exitChunk(TAG_0000);
iff.exitForm(TAG_SKYB);
}
break;
case TAG_DIST:
{
iff.enterForm(TAG_DIST);
iff.enterChunk(TAG_0000);
DistantAppearanceData distantAppearanceData;
std::string appearanceTemplateName;
iff.read_string(appearanceTemplateName);
distantAppearanceData.m_appearanceTemplateName.set(appearanceTemplateName.c_str(), true);
distantAppearanceData.m_direction_w = iff.read_floatVector();
distantAppearanceData.m_orientation_w.x = convertDegreesToRadians(iff.read_float());
distantAppearanceData.m_orientation_w.y = convertDegreesToRadians(iff.read_float());
distantAppearanceData.m_orientation_w.z = convertDegreesToRadians(iff.read_float());
distantAppearanceData.m_haloRoll = 0.f;
distantAppearanceData.m_haloScale = 1.f;
distantAppearanceData.m_infiniteDistance = (iff.read_int8() != 0);
m_distantAppearanceDataList->push_back(distantAppearanceData);
iff.exitChunk(TAG_0000);
iff.exitForm(TAG_DIST);
}
break;
case TAG_PLAN:
{
iff.enterForm(TAG_PLAN);
iff.enterChunk(TAG_0000);
DistantAppearanceData distantAppearanceData;
std::string appearanceTemplateName;
iff.read_string(appearanceTemplateName);
distantAppearanceData.m_appearanceTemplateName.set(appearanceTemplateName.c_str(), true);
distantAppearanceData.m_direction_w = iff.read_floatVector();
distantAppearanceData.m_orientation_w.x = convertDegreesToRadians(iff.read_float());
distantAppearanceData.m_orientation_w.y = convertDegreesToRadians(iff.read_float());
distantAppearanceData.m_orientation_w.z = convertDegreesToRadians(iff.read_float());
distantAppearanceData.m_haloRoll = convertDegreesToRadians(iff.read_float());
distantAppearanceData.m_haloScale = iff.read_float();
distantAppearanceData.m_infiniteDistance = (iff.read_int8() != 0);
m_distantAppearanceDataList->push_back(distantAppearanceData);
iff.exitChunk(TAG_0000);
iff.exitForm(TAG_PLAN);
}
break;
case TAG_CELE:
{
iff.enterForm(TAG_CELE);
iff.enterChunk(TAG_0000);
CelestialData celestialData;
std::string shaderTemplateName;
iff.read_string(shaderTemplateName);
celestialData.m_backShaderTemplateName.set(shaderTemplateName.c_str(), true);
celestialData.m_backSize = iff.read_float();
iff.read_string(shaderTemplateName);
celestialData.m_frontShaderTemplateName.set(shaderTemplateName.c_str(), true);
celestialData.m_frontSize = iff.read_float();
celestialData.m_direction_w = iff.read_floatVector();
m_celestialDataList->push_back(celestialData);
iff.exitChunk(TAG_0000);
iff.exitForm(TAG_CELE);
}
break;
default:
{
#ifdef _DEBUG
char tagBuffer[5];
ConvertTagToString(iff.getCurrentName(), tagBuffer);
char buffer[128];
iff.formatLocation(buffer, sizeof(buffer));
DEBUG_WARNING(true, ("SpaceTerrainAppearanceTemplate::load: skipping unknown chunk type %s/%s", buffer, tagBuffer));
#endif
IGNORE_RETURN(iff.goForward());
}
break;
}
}
iff.exitForm(TAG_0000);
}
//----------------------------------------------------------------------
float SpaceTerrainAppearanceTemplate::getMapWidthInMeters() const
{
return m_mapWidthInMeters;
}
// ======================================================================
@@ -0,0 +1,160 @@
// ======================================================================
//
// SpaceTerrainAppearanceTemplate.h
// asommers
//
// copyright 2004, sony online entertainment
//
// ======================================================================
#ifndef INCLUDED_SpaceTerrainAppearanceTemplate_H
#define INCLUDED_SpaceTerrainAppearanceTemplate_H
// ======================================================================
#include "sharedFoundation/PersistentCrcString.h"
#include "sharedFoundation/Tag.h"
#include "sharedObject/AppearanceTemplate.h"
#include "sharedMath/PackedArgb.h"
#include "sharedMath/PackedRgb.h"
#include "sharedMath/Vector.h"
#include "sharedMath/VectorArgb.h"
class Iff;
// ======================================================================
class SpaceTerrainAppearanceTemplate : public AppearanceTemplate
{
public:
SpaceTerrainAppearanceTemplate(char const * filename, Iff * iff);
virtual ~SpaceTerrainAppearanceTemplate() = 0;
PackedRgb const & getClearColor() const;
VectorArgb const & getAmbientColor() const;
int getNumberOfParallelLights() const;
VectorArgb const & getParallelLightDiffuseColor(int index) const;
VectorArgb const & getParallelLightSpecularColor(int index) const;
Vector const & getParallelLightDirection_w(int index) const;
CrcString const & getEnvironmentTextureName() const;
bool getFogEnabled() const;
PackedArgb const & getFogColor() const;
float getFogDensity() const;
int getNumberOfStars() const;
CrcString const & getStarColorRampName() const;
int getNumberOfDust() const;
float getDustRadius() const;
bool getSkyBoxCubeMap() const;
CrcString const & getSkyBoxTextureNameMask() const;
int getNumberOfDistantAppearances() const;
CrcString const & getDistantAppearanceTemplateName(int index) const;
Vector const & getDistantAppearanceDirection_w(int index) const;
Vector const & getDistantAppearanceOrientation_w(int index) const;
float getPlanetHaloRoll(int index) const;
float getPlanetHaloScale(int index) const;
bool isDistantAppearanceInfiniteDistance(int index) const;
int getNumberOfCelestials() const;
CrcString const & getCelestialBackShaderTemplateName(int index) const;
float getCelestialBackSize(int index) const;
CrcString const & getCelestialFrontShaderTemplateName(int index) const;
float getCelestialFrontSize(int index) const;
Vector const & getCelestialDirection_w(int index) const;
float getMapWidthInMeters() const;
protected:
static Tag const cms_spaceTerrainAppearanceTemplateTag;
private:
struct LightData
{
bool m_dot3;
VectorArgb m_diffuseColor;
VectorArgb m_specularColor;
Vector m_direction_w;
};
struct DistantAppearanceData
{
PersistentCrcString m_appearanceTemplateName;
Vector m_direction_w;
Vector m_orientation_w;
float m_haloRoll;
float m_haloScale;
bool m_infiniteDistance;
private:
DistantAppearanceData operator=(DistantAppearanceData const & rhs);
};
struct CelestialData
{
PersistentCrcString m_backShaderTemplateName;
float m_backSize;
PersistentCrcString m_frontShaderTemplateName;
float m_frontSize;
Vector m_direction_w;
private:
CelestialData operator=(CelestialData const & rhs);
};
private:
SpaceTerrainAppearanceTemplate();
SpaceTerrainAppearanceTemplate(SpaceTerrainAppearanceTemplate const &);
SpaceTerrainAppearanceTemplate & operator=(SpaceTerrainAppearanceTemplate const &);
void load(Iff & iff);
void load_0000(Iff & iff);
private:
PackedRgb m_clearColor;
VectorArgb m_ambientColor;
typedef stdvector<LightData>::fwd LightDataList;
LightDataList * const m_lightDataList;
PersistentCrcString m_environmentTextureName;
bool m_fogEnabled;
PackedArgb m_fogColor;
float m_fogDensity;
int m_numberOfStars;
PersistentCrcString m_starColorRampName;
int m_numberOfDust;
float m_dustRadius;
bool m_skyBoxCubeMap;
PersistentCrcString m_skyBoxTextureNameMask;
typedef stdvector<CelestialData>::fwd CelestialDataList;
CelestialDataList * const m_celestialDataList;
typedef stdvector<DistantAppearanceData>::fwd DistantAppearanceDataList;
DistantAppearanceDataList * const m_distantAppearanceDataList;
float m_mapWidthInMeters;
};
// ======================================================================
#endif
@@ -0,0 +1,457 @@
//===================================================================
//
// TerrainAppearance.cpp
// asommers 7-6-99
//
// copyright 1999, bootprint entertainment
// copyright 2001, sony online entertainment
//
//===================================================================
#include "sharedTerrain/FirstSharedTerrain.h"
#include "sharedTerrain/TerrainAppearance.h"
#include "sharedCollision/CollisionInfo.h"
#include "sharedMath/Sphere.h"
#include "sharedObject/Object.h"
#include "sharedObject/ObjectList.h"
//===================================================================
// PUBLIC TerrainAppearance
//===================================================================
TerrainAppearance::TerrainAppearance (const AppearanceTemplate* newAppearanceTemplate) :
Appearance (newAppearanceTemplate),
m_referenceObjectList (NON_NULL (new ObjectList (10)))
{
}
//-------------------------------------------------------------------
TerrainAppearance::~TerrainAppearance ()
{
delete m_referenceObjectList;
}
//-------------------------------------------------------------------
bool TerrainAppearance::collide(Vector const & /*start_o*/, Vector const & /*end_o*/, CollideParameters const & /*collideParameters*/, CollisionInfo & /*result*/) const
{
return false;
}
//-------------------------------------------------------------------
bool TerrainAppearance::collideObjects (const Vector& /*start_o*/, const Vector& /*end_o*/, CollisionInfo& /*result*/) const
{
return false;
}
//-------------------------------------------------------------------
bool TerrainAppearance::approximateCollideObjects (const Vector& /*start_o*/, const Vector& /*end_o*/, CollisionInfo& /*result*/) const
{
return false;
}
//-------------------------------------------------------------------
bool TerrainAppearance::getPauseEnvironment () const
{
return false;
}
//-------------------------------------------------------------------
void TerrainAppearance::setPauseEnvironment (bool const /*pauseEnvironment*/)
{
}
//-------------------------------------------------------------------
float TerrainAppearance::getEnvironmentCycleTime () const
{
return 0.f;
}
//-------------------------------------------------------------------
const PackedRgb TerrainAppearance::getClearColor () const
{
return PackedRgb::solidBlack;
}
//-------------------------------------------------------------------
const PackedRgb TerrainAppearance::getFogColor () const
{
return PackedRgb::solidBlack;
}
//-------------------------------------------------------------------
float TerrainAppearance::getFogDensity () const
{
return 0.f;
}
//-------------------------------------------------------------------
void TerrainAppearance::getTime (int& /*hour*/, int& /*minute*/) const
{
}
//-------------------------------------------------------------------
float TerrainAppearance::getTime () const
{
return 0.f;
}
//-------------------------------------------------------------------
void TerrainAppearance::setTime (float /*time*/, bool /*force*/)
{
}
//-------------------------------------------------------------------
bool TerrainAppearance::isDay () const
{
return true;
}
//----------------------------------------------------------------------
bool TerrainAppearance::isTimeLocked() const
{
return false;
}
//-------------------------------------------------------------------
bool TerrainAppearance::getHeight (const Vector& /*position_o*/, float& /*height*/) const
{
return false;
}
//-------------------------------------------------------------------
bool TerrainAppearance::getHeight (const Vector& /*position_o*/, float& /*height*/, Vector& /*normal*/) const
{
return false;
}
//-------------------------------------------------------------------
bool TerrainAppearance::getHeightForceChunkCreation (const Vector& /*position_o*/, float& /*height*/) const
{
return false;
}
//-------------------------------------------------------------------
const ObjectTemplate* TerrainAppearance::getSurfaceProperties (const Vector& /*position_o*/) const
{
return 0;
}
//-------------------------------------------------------------------
int TerrainAppearance::getTerrainType (const Vector& /*position_o*/) const
{
return 0;
}
//-----------------------------------------------------------------
bool TerrainAppearance::getWaterHeight (const Vector& /*position_o*/, float& /*height*/) const
{
return false;
}
//-----------------------------------------------------------------
bool TerrainAppearance::getWaterHeight (const Vector& /*position_o*/, float& /*height*/, TerrainGeneratorWaterType& /*waterType*/, bool /*ignoreNonTransparentWater*/) const
{
return false;
}
//-----------------------------------------------------------------
TerrainGeneratorWaterType TerrainAppearance::getWaterType (const Vector& /*position_w*/) const
{
return TGWT_invalid;
}
//-----------------------------------------------------------------
bool TerrainAppearance::getWater (const Rectangle2d& /*rectangle*/) const
{
return false;
}
//-------------------------------------------------------------------
bool TerrainAppearance::getSlope (const Rectangle2d& /*rectangle*/) const
{
return false;
}
//----------------------------------------------------------------------
bool TerrainAppearance::isPassable(Vector const & /*position_w*/) const
{
return true;
}
//----------------------------------------------------------------------
bool TerrainAppearance::isPassableForceChunkCreation(Vector const & /*position_w*/) const
{
return true;
}
//----------------------------------------------------------------------
bool TerrainAppearance::hasPassableAffectors() const
{
return false;
}
//-------------------------------------------------------------------
bool TerrainAppearance::getWater (const int /*chunkX*/, const int /*chunkZ*/) const
{
return false;
}
//-------------------------------------------------------------------
bool TerrainAppearance::getSlope (const int /*chunkX*/, const int /*chunkZ*/) const
{
return false;
}
//-------------------------------------------------------------------
float TerrainAppearance::getMapWidthInMeters () const
{
return 0.f;
}
//-------------------------------------------------------------------
float TerrainAppearance::getChunkWidthInMeters () const
{
return 0.f;
}
//-------------------------------------------------------------------
int TerrainAppearance::getNumberOfChunks () const
{
return 0;
}
//-------------------------------------------------------------------
bool TerrainAppearance::hasHighLevelOfDetailTerrain (const Vector& /*position_o*/) const
{
return true;
}
//-------------------------------------------------------------------
int TerrainAppearance::calculateChunkX (float) const
{
return 0;
}
//-------------------------------------------------------------------
int TerrainAppearance::calculateChunkZ (float) const
{
return 0;
}
//-------------------------------------------------------------------
float TerrainAppearance::getChunkHeight (const int /*chunkX*/, const int /*chunkZ*/) const
{
return 0.f;
}
//-------------------------------------------------------------------
const BoxExtent* TerrainAppearance::getChunkExtent (const Vector& /*position_o*/) const
{
return 0;
}
//-------------------------------------------------------------------
const BoxExtent* TerrainAppearance::getChunkExtentForceChunkCreation (const Vector& /*position_o*/) const
{
return 0;
}
//-------------------------------------------------------------------
bool TerrainAppearance::collideForceChunkCreation(Vector const & /*start_o*/, Vector const & /*end_o*/, CollisionInfo & /*result*/)
{
return false;
}
//-------------------------------------------------------------------
void TerrainAppearance::preRender (const Camera* /*camera*/) const
{
}
//-----------------------------------------------------------------
void TerrainAppearance::postRender () const
{
}
//-----------------------------------------------------------------
void TerrainAppearance::addClearCollidableFloraObject (const Object* const /*object*/, const Vector& /*position_w*/, const float /*radius*/)
{
}
//-------------------------------------------------------------------
void TerrainAppearance::removeClearCollidableFloraObject (const Object* const /*object*/)
{
}
//-------------------------------------------------------------------
void TerrainAppearance::addClearNonCollidableFloraObject (const Object* const /*object*/, const ClearFloraEntryList& /*clearFloraEntryList*/)
{
}
//-------------------------------------------------------------------
void TerrainAppearance::removeClearNonCollidableFloraObject (const Object* const /*object*/)
{
}
//-------------------------------------------------------------------
float TerrainAppearance::getHighLevelOfDetailThreshold () const
{
return 1.f;
}
//-------------------------------------------------------------------
void TerrainAppearance::setHighLevelOfDetailThreshold (const float /*highLevelOfDetailThreshold*/)
{
}
//-------------------------------------------------------------------
float TerrainAppearance::getLevelOfDetailThreshold () const
{
return 1.f;
}
//-------------------------------------------------------------------
void TerrainAppearance::setLevelOfDetailThreshold (const float /*levelOfDetailThreshold*/)
{
}
//-------------------------------------------------------------------
void TerrainAppearance::getPolygonSoup (const Rectangle2d& /*extent2d_o*/, IndexedTriangleList& /*indexedTriangleList*/) const
{
}
//-------------------------------------------------------------------
void TerrainAppearance::invalidateRegion (const Rectangle2d& /*extent2d*/)
{
}
//-------------------------------------------------------------------
void TerrainAppearance::addReferenceObject (const Object* const object)
{
m_referenceObjectList->addObject (const_cast<Object*> (object));
}
//-------------------------------------------------------------------
void TerrainAppearance::removeReferenceObject (const Object* const object)
{
m_referenceObjectList->removeObject (const_cast<Object*> (object));
}
//-------------------------------------------------------------------
void TerrainAppearance::removeAllReferenceObjects ()
{
m_referenceObjectList->removeAll ();
}
//-------------------------------------------------------------------
bool TerrainAppearance::isReferenceObject (const Object* const object) const
{
return m_referenceObjectList->find (object);
}
//-------------------------------------------------------------------
void TerrainAppearance::drawExtents (const Vector& /*position_o*/) const
{
}
//-------------------------------------------------------------------
void TerrainAppearance::debugDump () const
{
#ifdef _DEBUG
DEBUG_REPORT_PRINT (true, ("-- TerrainAppearance\n"));
DEBUG_REPORT_PRINT (true, ("numberOfReferenceObjects = %i\n", getNumberOfReferenceObjects ()));
if (getNumberOfReferenceObjects ())
{
const Object* const object = getReferenceObject (0);
if (object)
{
const Vector position_w = object->getPosition_w ();
DEBUG_REPORT_PRINT (true, ("referenceObject0Position = <%1.2f, %1.2f, %1.2f>\n", position_w.x, position_w.y, position_w.z));
}
}
#endif
}
//-------------------------------------------------------------------
void TerrainAppearance::purgeChunks()
{
}
//===================================================================
// PRIVATE TerrainAppearance
//===================================================================
int TerrainAppearance::getNumberOfReferenceObjects () const
{
return m_referenceObjectList->getNumberOfObjects ();
}
//-------------------------------------------------------------------
const Object* TerrainAppearance::getReferenceObject (const int index) const
{
return m_referenceObjectList->getObject (index);
}
//===================================================================
@@ -0,0 +1,126 @@
//===================================================================
//
// TerrainAppearance.h
// asommers 7-6-99
//
// copyright 1999, bootprint entertainment
// copyright 2001, sony online entertainment
//
//===================================================================
#ifndef INCLUDED_TerrainAppearance_H
#define INCLUDED_TerrainAppearance_H
//===================================================================
#include "sharedMath/PackedRgb.h"
#include "sharedObject/Appearance.h"
#include "sharedTerrain/TerrainGeneratorType.h"
class Camera;
class ObjectList;
class ObjectTemplate;
class Rectangle2d;
//===================================================================
class TerrainAppearance : public Appearance
{
public:
explicit TerrainAppearance (const AppearanceTemplate* newAppearanceTemplate);
virtual ~TerrainAppearance ();
//-- Appearance
virtual bool collide(Vector const & start_o, Vector const & end_o, CollideParameters const & collideParameters, CollisionInfo & result) const;
//-- TerrainAppearance
virtual bool getHeight (const Vector& position_o, float& height) const;
virtual bool getHeight (const Vector& position_o, float& height, Vector& normal) const;
virtual bool getHeightForceChunkCreation (const Vector& position_o, float& height) const;
virtual const ObjectTemplate* getSurfaceProperties (const Vector& position_o) const;
virtual int getTerrainType (const Vector& position_o) const;
virtual bool getWaterHeight (const Vector& position_o, float& height) const;
virtual bool getWaterHeight (const Vector& position_o, float& height, TerrainGeneratorWaterType& waterType, bool ignoreNonTransparentWater=false) const;
virtual TerrainGeneratorWaterType getWaterType (const Vector& position_w) const;
virtual bool getWater (const Rectangle2d& rectangle) const;
virtual bool getSlope (const Rectangle2d& rectangle) const;
virtual bool getWater (int chunkX, int chunkZ) const;
virtual bool getSlope (int chunkX, int chunkZ) const;
virtual bool isPassable(Vector const & position_w) const;
virtual bool isPassableForceChunkCreation(Vector const & position_w) const;
virtual bool hasPassableAffectors() const;
virtual float getMapWidthInMeters () const;
virtual float getChunkWidthInMeters () const;
virtual int getNumberOfChunks () const;
virtual bool hasHighLevelOfDetailTerrain (const Vector& position_o) const;
virtual int calculateChunkX (float positionX_o) const;
virtual int calculateChunkZ (float positionZ_o) const;
virtual float getChunkHeight (int chunkX, int chunkZ) const;
virtual const BoxExtent* getChunkExtent (const Vector& position_o) const;
virtual const BoxExtent* getChunkExtentForceChunkCreation (const Vector& position_o) const;
virtual bool collideForceChunkCreation(Vector const & start_o, Vector const & end_o, CollisionInfo & result);
virtual void preRender (const Camera* camera) const;
virtual void postRender () const;
virtual bool collideObjects (const Vector& start_o, const Vector& end_o, CollisionInfo& result) const;
virtual bool approximateCollideObjects (const Vector& start_o, const Vector& end_o, CollisionInfo& result) const;
virtual bool getPauseEnvironment () const;
virtual void setPauseEnvironment (bool pauseEnvironment);
virtual float getEnvironmentCycleTime () const;
virtual const PackedRgb getClearColor () const;
virtual const PackedRgb getFogColor () const;
virtual float getFogDensity () const;
virtual void getTime (int& hour, int& minute) const;
virtual float getTime () const;
virtual void setTime (float time, bool force);
virtual bool isDay () const;
virtual bool isTimeLocked() const;
typedef stdvector<std::pair<Vector, float> >::fwd ClearFloraEntryList;
virtual void addClearCollidableFloraObject (const Object* object, const Vector& position_o, float radius);
virtual void removeClearCollidableFloraObject (const Object* object);
virtual void addClearNonCollidableFloraObject (const Object* object, const ClearFloraEntryList& clearFloraEntryList);
virtual void removeClearNonCollidableFloraObject (const Object* object);
virtual float getHighLevelOfDetailThreshold () const;
virtual void setHighLevelOfDetailThreshold (float highLevelOfDetailThreshold);
virtual float getLevelOfDetailThreshold () const;
virtual void setLevelOfDetailThreshold (float levelOfDetailThreshold);
virtual void getPolygonSoup (const Rectangle2d& extent2d_o, IndexedTriangleList& indexedTriangleList) const;
virtual void invalidateRegion (const Rectangle2d& extent2d);
void addReferenceObject (const Object* object);
int getNumberOfReferenceObjects () const;
void removeReferenceObject (const Object* object);
void removeAllReferenceObjects ();
bool isReferenceObject (const Object* object) const;
//-- debugging
virtual void drawExtents (const Vector& position_o) const;
virtual void debugDump () const;
virtual void purgeChunks();
protected:
const Object* getReferenceObject (int index) const;
private:
TerrainAppearance ();
TerrainAppearance (const TerrainAppearance&);
TerrainAppearance& operator= (const TerrainAppearance&);
private:
ObjectList* const m_referenceObjectList;
};
//===================================================================
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,741 @@
// ======================================================================
//
// TerrainQuadTree.h
// copyright 2001 Sony Online Entertainment
//
// ======================================================================
#ifndef INCLUDED_TerrainQuadTree_H
#define INCLUDED_TerrainQuadTree_H
// ======================================================================
#include "sharedCollision/BoxExtent.h"
#include "sharedFoundation/MemoryBlockManagerMacros.h"
#include "sharedTerrain/ProceduralTerrainAppearance.h"
// ======================================================================
/**
* TerrainQuadTree is a wrapper class for a quadtree of TerrainQuadTree::Nodes
*
* @author jwatson
* @date 2001-01-12
* @see nothing
*/
class TerrainQuadTree
{
public:
/**
* TerrainQuadTree::Node is a node in the Terrain Quad Tree. The interface is pretty fat. (not phat)
*/
class Node
{
MEMORY_BLOCK_MANAGER_INTERFACE_WITHOUT_INSTALL;
public:
static void install ();
static void remove ();
public:
/**
* neighbors
*/
enum
{
NORTH = 0,
WEST = 1,
SOUTH = 2,
EAST = 3,
NUM_NEIGHBORS = 4
};
/**
* neighbor flags
*/
enum
{
NORTH_FLAG = (1<<0)
,WEST_FLAG = (1<<1)
,SOUTH_FLAG = (1<<2)
,EAST_FLAG = (1<<3)
};
static const int REVERSE_DIRECTIONS[4];
/**
* quadrants
*/
enum
{
NORTHEAST = 0,
NORTHWEST = 1,
SOUTHWEST = 2,
SOUTHEAST = 3
};
static const int OPPOSITE_QUADRANTS[4];
/**
* half-quadrants
*/
enum
{
ENE = 0,
NNE = 1,
NNW = 2,
WNW = 3,
WSW = 4,
SSW = 5,
SSE = 6,
ESE = 7
};
static const int OPPOSITE_HALFQUADRANTS[8];
/**
* MAX_SIZE should be the square root of the maximum numeric capacity of 32 bit unsigned int
*/
enum
{
MAX_SIZE = 1 << 14
};
public:
Node (int newX, int newZ, int newSize, float theMinChunkWidthInMeters);
~Node ();
void destroyNode (Node * node);
void removeNode (Node * node);
void addNode (Node * node, int quadrant);
Node * addChunk (ProceduralTerrainAppearance::Chunk * newChunk, const int chunkSize);
int removeSubNodes (bool deleteChunks);
int removeSubNodeChunks (bool deleteChunks, bool recurse=true);
Node * findChunkNode (const ProceduralTerrainAppearance::Chunk * aChunk, int ax, int az, int chunkSize);
const BoxExtent & getBoxExtent () const;
bool isBoxExtentInitialized () const;
bool hasChunk (const ProceduralTerrainAppearance::Chunk * aChunk, int ax, int az, int chunkSize);
bool nodeEncloses (int ax, int az) const;
void pruneTree ();
void removeChunk (ProceduralTerrainAppearance::Chunk * aChunk, bool deleteChunk);
const ProceduralTerrainAppearance::Chunk * getChunk () const;
ProceduralTerrainAppearance::Chunk * getChunk ();
int32 getX () const;
int32 getZ () const;
int32 getSize () const;
int getNumberOfChunks () const;
unsigned getChildIndex () const;
Node * getParent ();
const Node * getParent () const;
Node * getSubNode (const int which) const;
int getQuadrant (const int ax, const int az) const;
int getQuadrant (const Vector & v) const;
int getHalfQuadrant (const int ax, const int az) const;
int getHalfQuadrant (const Vector & v) const;
float getDistanceSquared (const Vector & v) const;
Node * findNode (int ax, int az, int asize);
const Node * findFirstRenderableNode (const Vector& position) const;
Node * findFirstRenderableNode (const Vector& position);
const Node * findFirstRenderableNode (int ax, int az) const;
Node * findFirstRenderableNode (int ax, int az);
Node * findFirstRenderableLowerNeighbor (const Node * otherNode, int dir);
Node * findFirstRenderablePeerNeighbor (const Node * otherNode, int dir);
bool isSelectedForRender () const;
void setSelectedForRender (bool b);
//-- larger neighbor stuff
bool getHasLargerNeighbor (int dir) const;
void setHasLargerNeighbor (int dir, bool b);
void clearHasLargerNeighbors ();
bool getHasAnyLargerNeighbors () const;
unsigned getHasLargerNeighbors () const;
bool isOutsideBuildRange () const;
void setOutsideBuildRange (bool b);
const Node * getNeighbor (int index) const;
Node * getNeighbor (int index);
private:
Node ();
Node (const Node &);
Node & operator= (const Node &);
int internalRemoveSubNodes (bool deleteChunks);
int internalRemoveSubNodeChunks (bool deleteChunks, bool recurse) const;
/**
* find the quadrant given the x and z coordinates relative
* to the center of this node
*/
template<class T> int getQuadrantTemplate (const T ax, const T az) const
{
// left quadrants
if (ax < 0)
{
// bottom left quadrant
if (az < 0)
return SOUTHWEST;
// top left quadrant
else
return NORTHWEST;
}
// bottom right quadrant
else if (az < 0)
return SOUTHEAST;
// top right quadrant
else
return NORTHEAST;
}
/**
* find the half-quadrant given the x and z coordinates relative
* to the center of this node
*/
template<class T> int getHalfQuadrantTemplate (const T ax, const T az) const
{
// left quadrants
if (ax < 0)
{
// bottom left quadrant
if (az < 0)
{
return (ax < az) ? WSW : SSW;
}
// top left quadrant
else
{
return (-ax > az) ? NNW : WNW;
}
}
// bottom right quadrant
else if (az < 0)
{
return (ax < -az) ? SSE : ESE;
}
// top right quadrant
else
{
return (ax > az) ? ENE : NNE;
}
}
private:
/**
* The chunkspace coordinates of the node.
*/
const short m_x;
const short m_z;
/**
* The chunkspace size (width & height) of this node. Size is always a power of 2.
* The maximum number of chunks contained under a node is size*size.
*/
const short m_size;
unsigned short m_childIndex : 2; // The index of this child node as a subnode of its parent.
unsigned short m_worldExtentInitialized : 1;
unsigned short hasLargerNeighborFlags : 4;
unsigned short m_selectedForRender : 1;
unsigned short m_outsideBuildRange : 1;
/**
* This is the width of the smallest chunk on the map. REDUNDANT, store elsewhere?
*/
const float m_minChunkWidthInMeters;
/**
* The chunk which lives at this node. Currently all chunks are assumed
* to live on size 1 leaf nodes.
*/
ProceduralTerrainAppearance::Chunk * m_chunk;
/**
* Subnodes are arranged spatially the same as mathematical quadrants.
*/
Node * m_subNodes[4];
Node * m_parent;
Node * m_neighbors[4];
/**
* Current number of size 1 chunks contained beneath this node.
*/
int m_numberOfChunks;
/**
* The worldspace extents of this node. This extent contains all subnodes.
*/
BoxExtent m_worldExtent;
};
/**
* Constants for Iterator tree traversal
*/
class IteratorConstants
{
public:
static const int ORDER_PRE[4];
// traversal starting with the specified corner, front to back
static const int ORDER_ENE[4];
static const int ORDER_NNE[4];
static const int ORDER_NNW[4];
static const int ORDER_WNW[4];
static const int ORDER_WSW[4];
static const int ORDER_SSW[4];
static const int ORDER_SSE[4];
static const int ORDER_ESE[4];
static const int * const HALF_QUADRANT_ORDERS[8];
};
/**
* TerrainQuadTree::Iterator is a preorder iterator
* To use an iterator, loop while the current node is non-null. If the
* current node's subtree should be processed further, call descend ()
* on the iterator, otherwise call advance () to go to the next node.
* Either advance () or descend () should be called every loop iteration,
* otherwise an infinite loop will result.
*
*
* This template floatly depends on having a pointer type as its template parameter.
* T must be assignable from zero and have a default constructor. A zero sentinel
* is used to improve performance.
*/
template <class T>
class IteratorTemplate
{
public:
explicit IteratorTemplate (T node);
void reset (T node);
T advance ();
bool isEmpty () const;
T getCurNode ();
T descend (const int * theOrder = IteratorConstants::ORDER_PRE);
T descendOneChild (int index);
void push (T node);
private:
IteratorTemplate ();
enum
{
maxDepth = 64 // 16 deep x 4 nodes
};
//* The iterator is a stack of nodes
T s[maxDepth];
int depth;
};
/**
* The ordinary, non-const Iterator
*/
typedef IteratorTemplate<Node *> Iterator;
/**
* The const Iterator
*/
typedef IteratorTemplate<const Node *> ConstIterator;
public:
static void setUseDistance2d (bool useDistance2d);
public:
explicit TerrainQuadTree (int maxsize, float theMinChunkWidthInMeters);
~TerrainQuadTree ();
Node * getTopNode ();
const Node * getTopNode () const;
Iterator getIterator () const;
Node * addChunk (ProceduralTerrainAppearance::Chunk * chunk, const int chunkSize);
void removeChunk (ProceduralTerrainAppearance::Chunk * chunk, bool deleteChunk);
int getNumberOfChunks () const;
void pruneTree ();
ProceduralTerrainAppearance::Chunk * findChunk (int ax, int az, int chunkSize) const;
Node * findChunkNode (int ax, int az, int chunkSize) const;
bool hasChunk (int ax, int az, int chunkSize) const;
private:
Node * m_nodes;
private:
TerrainQuadTree ();
TerrainQuadTree (const TerrainQuadTree&);
TerrainQuadTree& operator= (const TerrainQuadTree&);
};
//-----------------------------------------------------------------
// TerrainQuadTree::Node
//-----------------------------------------------------------------
/**
* Get the BoxExtent which contains this node. This is the enclosing BoxExtent
* of all chunks which are children of this node and its subnodes.
* @return the BoxExtent
*/
inline const BoxExtent & TerrainQuadTree::Node::getBoxExtent () const
{
return m_worldExtent;
}
//-----------------------------------------------------------------
/**
* Have any float-world chunks ever been added to this Node or its' subnodes?
* If not, then the BoxExtent is not yet valid.
*/
inline bool TerrainQuadTree::Node::isBoxExtentInitialized () const
{
return m_worldExtentInitialized;
}
//-----------------------------------------------------------------
/**
* Get the chunk located at this node. Currently chunks are only found on size 1 leaf nodes.
*/
inline const ProceduralTerrainAppearance::Chunk * TerrainQuadTree::Node::getChunk () const
{
return m_chunk;
}
//-----------------------------------------------------------------
inline ProceduralTerrainAppearance::Chunk * TerrainQuadTree::Node::getChunk ()
{
return m_chunk;
}
//-----------------------------------------------------------------
/**
* Get the X position of this node in chunkspace.
*/
inline int32 TerrainQuadTree::Node::getX () const
{
return m_x;
}
//-----------------------------------------------------------------
/**
* Get the z position of this node in chunkspace.
*/
inline int32 TerrainQuadTree::Node::getZ () const
{
return m_z;
}
//-----------------------------------------------------------------
/**
* Get the size of this node in chunkspace.
*/
inline int32 TerrainQuadTree::Node::getSize () const
{
return m_size;
}
//-----------------------------------------------------------------
/**
* Get the number of chunks contained within this entire subtree.
*/
inline int TerrainQuadTree::Node::getNumberOfChunks () const
{
return m_numberOfChunks;
}
//-----------------------------------------------------------------
/**
* Get the childIndex, or the quadrant of this node as related to it's parent node.
*/
inline unsigned TerrainQuadTree::Node::getChildIndex () const
{
return m_childIndex;
}
//-----------------------------------------------------------------
/**
* Get the parent node.
*/
inline TerrainQuadTree::Node * TerrainQuadTree::Node::getParent ()
{
return m_parent;
}
//-----------------------------------------------------------------
/**
* Get the parent node
*/
inline const TerrainQuadTree::Node * TerrainQuadTree::Node::getParent () const
{
return m_parent;
}
//-----------------------------------------------------------------
/**
* Get the child node in the specified quadrant of this node.
*/
inline TerrainQuadTree::Node * TerrainQuadTree::Node::getSubNode (const int childIndex) const
{
return m_subNodes [childIndex];
}
//-----------------------------------------------------------------
/**
* Is this node selected for rendering? If so, then it is rendered, and collision detection occurs with it.
*/
inline bool TerrainQuadTree::Node::isSelectedForRender () const
{
return m_selectedForRender;
}
//-----------------------------------------------------------------
inline void TerrainQuadTree::Node::setSelectedForRender (const bool selectedForRender)
{
m_selectedForRender = selectedForRender;
}
//-----------------------------------------------------------------
/**
* Has this node been flagged as having a larger neighbor in the specified direction?
*/
inline bool TerrainQuadTree::Node::getHasLargerNeighbor (const int direction) const
{
return 0!=(hasLargerNeighborFlags & (1<<direction));
}
//-----------------------------------------------------------------
/**
* Flag this node's larger neighbor status in the specified direction
*/
inline void TerrainQuadTree::Node::setHasLargerNeighbor (const int direction, const bool hasLargerNeighbor)
{
if (hasLargerNeighbor)
{
hasLargerNeighborFlags |= (1<<direction);
}
else
{
hasLargerNeighborFlags &= ~(1<<direction);
}
}
//-----------------------------------------------------------------
inline void TerrainQuadTree::Node::clearHasLargerNeighbors ()
{
hasLargerNeighborFlags=0;
}
//-----------------------------------------------------------------
/**
* Quick check to see if any neighbors are larger.
*/
inline bool TerrainQuadTree::Node::getHasAnyLargerNeighbors () const
{
return hasLargerNeighborFlags!=0;
}
//-----------------------------------------------------------------
/**
* Get 4-element bool array of larger neighbor flags.
*/
inline unsigned TerrainQuadTree::Node::getHasLargerNeighbors() const
{
return hasLargerNeighborFlags;
}
//-----------------------------------------------------------------
inline bool TerrainQuadTree::Node::isOutsideBuildRange () const
{
return m_outsideBuildRange;
}
//-----------------------------------------------------------------
inline void TerrainQuadTree::Node::setOutsideBuildRange (const bool outsideBuildRange)
{
m_outsideBuildRange = outsideBuildRange;
}
//-----------------------------------------------------------------
// TerrainQuadTree::IteratorTemplate
//-----------------------------------------------------------------
/**
* Construct an Iterator starting with the specified node. Initialize
* the sentinel and setup the stack with the selected node.
* @param node The top of the tree to traverse.
*/
template <class T>
inline TerrainQuadTree::IteratorTemplate<T>::IteratorTemplate (T node)
{
NOT_NULL (node);
s[0] = 0;
s[1] = node;
depth = 1;
}
//-----------------------------------------------------------------
/**
* Reset the iterator. The sentinel should be already correct.
*/
template <class T>
inline void TerrainQuadTree::IteratorTemplate<T>::reset (T node)
{
NOT_NULL (node);
DEBUG_FATAL (s[0] != 0, ("Corrupt sentinel")); // verify the sentinel
s[1] = node;
depth = 1;
}
//-----------------------------------------------------------------
template <class T>
inline void TerrainQuadTree::IteratorTemplate<T>::push (T node)
{
NOT_NULL (node);
DEBUG_FATAL (depth >= maxDepth, ("TerrainQuadTree::IteratorTemplate<T>: max depth exceeded"));
s[++depth] = node;
}
//-----------------------------------------------------------------
/**
* advance pops the current node off the stack and returns a pointer to
* the next one, if there is one.
*/
template <class T>
inline T TerrainQuadTree::IteratorTemplate<T>::advance ()
{
DEBUG_FATAL (depth <= 0, ("TerrainQuadTree::IteratorTemplate<T>: advancing past root"));
return s[--depth];
}
//-----------------------------------------------------------------
template <class T>
inline bool TerrainQuadTree::IteratorTemplate<T>::isEmpty () const
{
return depth==0;
}
//-----------------------------------------------------------------
/**
* get the top node of the stack
*/
template <class T>
inline T TerrainQuadTree::IteratorTemplate<T>::getCurNode ()
{
return s[depth];
}
//-----------------------------------------------------------------
/**
* descend pushes the children of the current node onto the stack,
* in the reverse of the order specified. The result is that
* multiple calls to advance () will return the nodes in the order
* specified. The current node is removed from the stack, and the
* resulting top of the stack is returned.
*/
template <class T>
inline T TerrainQuadTree::IteratorTemplate<T>::descend (const int * theOrder)
{
DEBUG_FATAL (isEmpty (), ("descent into empty iterator"));
T node = s[depth--];
// go through the order backwards since our iterator uses a stack rather than a queue
for (int i = 3; i >= 0; --i)
{
const int index = theOrder [i];
if (node->getSubNode (index))
push (node->getSubNode (index));
}
return s[depth];
}
//-----------------------------------------------------------------
template <class T>
inline T TerrainQuadTree::IteratorTemplate<T>::descendOneChild (const int index)
{
DEBUG_FATAL (isEmpty (), ("descent into empty iterator"));
T node = s[depth--];
if (node->getSubNode (index))
push (node->getSubNode (index));
return getCurNode ();
}
//-----------------------------------------------------------------
// TerrainQuadTree
//-----------------------------------------------------------------
inline TerrainQuadTree::Node * TerrainQuadTree::getTopNode ()
{
return m_nodes;
}
//-----------------------------------------------------------------
inline const TerrainQuadTree::Node * TerrainQuadTree::getTopNode () const
{
return m_nodes;
}
//-----------------------------------------------------------------
#endif
@@ -0,0 +1,88 @@
//===================================================================
//
// ConfigSharedTerrain.cpp
// copyright 2000, verant interactive
//
//===================================================================
#include "sharedTerrain/FirstSharedTerrain.h"
#include "sharedTerrain/ConfigSharedTerrain.h"
#include "sharedFoundation/ConfigFile.h"
//===================================================================
namespace
{
int ms_maximumNumberOfChunksAllowed;
bool ms_disableGetHeight;
bool ms_debugReportInstall;
bool ms_debugReportLogPrint;
bool ms_disableFloraCaching;
float ms_maximumValidHeightInMeters;
}
//===================================================================
int ConfigSharedTerrain::getMaximumNumberOfChunksAllowed ()
{
return ms_maximumNumberOfChunksAllowed;
}
//-------------------------------------------------------------------
bool ConfigSharedTerrain::getDisableGetHeight ()
{
return ms_disableGetHeight;
}
//-------------------------------------------------------------------
bool ConfigSharedTerrain::getDebugReportInstall ()
{
return ms_debugReportInstall;
}
//-------------------------------------------------------------------
bool ConfigSharedTerrain::getDebugReportLogPrint ()
{
return ms_debugReportLogPrint;
}
//-------------------------------------------------------------------
bool ConfigSharedTerrain::getDisableFloraCaching ()
{
return ms_disableFloraCaching;
}
//-------------------------------------------------------------------
float ConfigSharedTerrain::getMaximumValidHeightInMeters ()
{
return ms_maximumValidHeightInMeters;
}
//===================================================================
#define KEY_BOOL(a,b) (ms_ ## a = ConfigFile::getKeyBool ("SharedTerrain", #a, b))
#define KEY_INT(a,b) (ms_ ## a = ConfigFile::getKeyInt ("SharedTerrain", #a, b))
#define KEY_FLOAT(a,b) (ms_ ## a = ConfigFile::getKeyFloat ("SharedTerrain", #a, b))
//#define KEY_STRING (a,b) (ms_ ## a = ConfigFile::getKeyString ("SharedTerrain", #a, b))
//===================================================================
void ConfigSharedTerrain::install ()
{
KEY_INT (maximumNumberOfChunksAllowed, 40 * 1024);
KEY_BOOL (disableGetHeight, false);
KEY_BOOL (debugReportInstall, false);
KEY_BOOL (debugReportLogPrint, false);
KEY_BOOL (disableFloraCaching, false);
KEY_FLOAT (maximumValidHeightInMeters, 16000.0f);
DEBUG_REPORT_LOG_PRINT (ms_debugReportInstall, ("ConfigSharedTerrain::install\n"));
}
//===================================================================
@@ -0,0 +1,36 @@
//===================================================================
//
// ConfigSharedTerrain.h
// copyright 2000, verant interactive
//
//===================================================================
#ifndef INCLUDED_ConfigSharedTerrain_H
#define INCLUDED_ConfigSharedTerrain_H
//===================================================================
class ConfigSharedTerrain
{
public:
static void install ();
static int getMaximumNumberOfChunksAllowed ();
static bool getDisableGetHeight ();
static bool getDebugReportInstall ();
static bool getDebugReportLogPrint ();
static bool getDisableFloraCaching ();
static float getMaximumValidHeightInMeters ();
private:
ConfigSharedTerrain ();
ConfigSharedTerrain (const ConfigSharedTerrain&);
ConfigSharedTerrain& operator= (const ConfigSharedTerrain&);
};
//===================================================================
#endif
@@ -0,0 +1,18 @@
// ======================================================================
//
// FirstTerrain.h
// copyright (c) 2001 Sony Online Entertainment
//
// ======================================================================
#ifndef INCLUDED_FirstTerrain_H
#define INCLUDED_FirstTerrain_H
// ======================================================================
#include "sharedFoundation/FirstSharedFoundation.h"
// ======================================================================
#endif
@@ -0,0 +1,93 @@
//===================================================================
//
// SetupSharedTerrain.cpp
// asommers 9-10-2000
//
// copyright 2000, verant interactive
//
//===================================================================
#include "sharedTerrain/FirstSharedTerrain.h"
#include "sharedTerrain/SetupSharedTerrain.h"
#include "sharedDebug/InstallTimer.h"
#include "sharedFoundation/ExitChain.h"
#include "sharedFractal/MultiFractal.h"
#include "sharedTerrain/ConfigSharedTerrain.h"
#include "sharedTerrain/ServerProceduralTerrainAppearance.h"
#include "sharedTerrain/ServerProceduralTerrainAppearanceTemplate.h"
#include "sharedTerrain/ServerSpaceTerrainAppearanceTemplate.h"
#include "sharedTerrain/TerrainObject.h"
#include "sharedTerrain/WaterTypeManager.h"
//===================================================================
namespace
{
bool ms_installed;
}
//===================================================================
SetupSharedTerrain::Data::Data () :
m_allowInactiveLayerItems (false)
{
}
//===================================================================
void SetupSharedTerrain::install (const SetupSharedTerrain::Data& /*data*/)
{
InstallTimer const installTimer("SetupSharedTerrain::install");
DEBUG_FATAL (ms_installed, ("SetupSharedTerrain::install already installed"));
ms_installed = true;
DEBUG_REPORT_LOG_PRINT (ConfigSharedTerrain::getDebugReportInstall (), ("SetupSharedTerrain::install\n"));
ConfigSharedTerrain::install ();
TerrainObject::install ();
ProceduralTerrainAppearance::install ();
ServerProceduralTerrainAppearanceTemplate::install ();
ServerSpaceTerrainAppearanceTemplate::install();
WaterTypeManager::install();
ExitChain::add (SetupSharedTerrain::remove, "SetupSharedTerrain");
}
//-------------------------------------------------------------------
void SetupSharedTerrain::remove ()
{
DEBUG_FATAL (!ms_installed, ("SetupSharedTerrain::remove not installed"));
ms_installed = false;
/*
#ifdef _DEBUG
MultiFractal::debugDump ();
#endif
*/
}
//-------------------------------------------------------------------
bool SetupSharedTerrain::isInstalled ()
{
return ms_installed;
}
//-------------------------------------------------------------------
void SetupSharedTerrain::setupGameData (Data& data)
{
data.m_allowInactiveLayerItems = false;
}
//-------------------------------------------------------------------
void SetupSharedTerrain::setupToolData (Data& data)
{
data.m_allowInactiveLayerItems = true;
}
//===================================================================
@@ -0,0 +1,53 @@
//===================================================================
//
// SetupSharedTerrain.h
// asommers 9-11-2000
//
// copyright 2000, verant interactive
//
//===================================================================
#ifndef INCLUDED_SetupSharedTerrain_H
#define INCLUDED_SetupSharedTerrain_H
//===================================================================
class SetupSharedTerrain
{
public:
class Data
{
public:
Data ();
private:
bool m_allowInactiveLayerItems;
private:
friend class SetupSharedTerrain;
};
public:
static void install (const Data& data);
static void remove ();
static bool isInstalled ();
static void setupGameData (Data& data);
static void setupToolData (Data& data);
private:
SetupSharedTerrain ();
SetupSharedTerrain (const SetupSharedTerrain&);
SetupSharedTerrain& operator= (const SetupSharedTerrain&);
};
//===================================================================
#endif
@@ -0,0 +1,248 @@
// ======================================================================
//
// WaterTypeManager.cpp
//
// copyright 2005, Sony Online Entertainment
//
// ======================================================================
#include "sharedTerrain/FirstSharedTerrain.h"
#include "sharedTerrain/WaterTypeManager.h"
#include "sharedDebug/InstallTimer.h"
#include "sharedFoundation/ExitChain.h"
#include "sharedUtility/DataTable.h"
#include "sharedUtility/DataTableManager.h"
#include <map>
// ======================================================================
bool WaterTypeManager::ms_installed = false;
WaterTypeManager::WaterTypeDataType * WaterTypeManager::ms_waterTypeData=NULL;
WaterTypeManager::CreatureWaterTypeDataType* WaterTypeManager::ms_creatureWaterTypeData=NULL;
// ======================================================================
WaterTypeManager::WaterTypeDataRecord::WaterTypeDataRecord() :
m_typeId(0),
m_name(),
m_causesDamage(false),
m_damageKills(false),
m_damageInterval(0),
m_damagePerInterval(0),
m_transparent(false)
{
}
// ======================================================================
WaterTypeManager::CreatureWaterTypeDataRecord::CreatureWaterTypeDataRecord() :
m_objectTemplateName(),
m_lavaResistance(0.0f)
{
}
// ======================================================================
void WaterTypeManager::install()
{
InstallTimer const installTimer("WaterTypeManager::install");
DEBUG_FATAL(ms_installed,("WaterTypeManager::install was called more than once."));
ms_waterTypeData = new WaterTypeDataType;
ms_creatureWaterTypeData = new CreatureWaterTypeDataType;
ms_installed = true;
ExitChain::add(&remove,"WaterTypeManager::remove");
{
DataTable const * const waterTypeDataTable = DataTableManager::getTable("datatables/terrain/water_values.iff", true);
FATAL(!waterTypeDataTable,("water_values data table could not be opened."));
int const numRows = waterTypeDataTable->getNumRows();
for (int row=0; row<numRows; ++row)
{
WaterTypeDataRecord data;
data.m_typeId = row;
data.m_name = waterTypeDataTable->getStringValue("water_type",row);
data.m_causesDamage = (waterTypeDataTable->getIntValue("causes_damage",row) != 0);
data.m_damageKills = (waterTypeDataTable->getIntValue("damage_kills",row) != 0);
data.m_damageInterval = waterTypeDataTable->getIntValue("damage_interval_secs", row);
data.m_damagePerInterval = waterTypeDataTable->getFloatValue("damage_per_interval_percentage",row);
data.m_transparent = (waterTypeDataTable->getIntValue("transparent",row) != 0);
(*ms_waterTypeData)[data.m_typeId] = data;
}
DataTableManager::close("datatables/terrain/water_values.iff");
}
{
DataTable const* const creatureWaterTypeDataTable = DataTableManager::getTable("datatables/terrain/creature_water_values.iff",true);
FATAL(!creatureWaterTypeDataTable,("creature_water_values data table could not be opened."));
int const numRows = creatureWaterTypeDataTable->getNumRows();
for(int row=0; row < numRows; ++row)
{
CreatureWaterTypeDataRecord data;
data.m_objectTemplateName = creatureWaterTypeDataTable->getStringValue("object_template_name",row);
data.m_lavaResistance = creatureWaterTypeDataTable->getFloatValue("lava_resistance",row);
if(data.m_lavaResistance > 100.0f)
{
data.m_lavaResistance = 100.0f;
}
else if(data.m_lavaResistance < 0.0f)
{
data.m_lavaResistance = 0.0f;
}
(*ms_creatureWaterTypeData)[data.m_objectTemplateName] = data;
}
DataTableManager::close("datatables/terrain/creature_water_values.iff");
}
}
// ----------------------------------------------------------------------
void WaterTypeManager::remove()
{
DEBUG_FATAL(!ms_installed,("WaterTypeManager not installed"));
{
/*
// JU_TODO: temp - reference if we need to preload the character or vehicle effects here
for (WaterTypeManager::WaterTypeDataType::iterator it = ms_waterTypeData->begin(); it != ms_waterTypeData->end(); ++it)
{
WaterTypeDataRecord & waterTypeDataRecord = (*it).second;
waterTypeDataRecord.releaseResources();
}
*/
}
delete ms_waterTypeData;
ms_waterTypeData=NULL;
delete ms_creatureWaterTypeData;
ms_creatureWaterTypeData=NULL;
ms_installed = false;
}
// ----------------------------------------------------------------------
bool WaterTypeManager::getCausesDamage(TerrainGeneratorWaterType type)
{
bool ret = false;
WaterTypeDataType::const_iterator const i = ms_waterTypeData->find(type);
if (i == ms_waterTypeData->end())
{
WARNING(true,("WaterTypeManager::getCausesDamage: Received request with type id %i, which isn't in the data table.", type));
}
else
{
WaterTypeDataRecord const & data = i->second;
ret = data.m_causesDamage;
}
return ret;
}
// ----------------------------------------------------------------------
bool WaterTypeManager::getDamageKills(TerrainGeneratorWaterType type)
{
bool ret = false;
WaterTypeDataType::const_iterator const i = ms_waterTypeData->find(type);
if (i == ms_waterTypeData->end())
{
WARNING(true,("WaterTypeManager::getDamageKills: Received request with type id %i, which isn't in the data table.", type));
}
else
{
WaterTypeDataRecord const & data = i->second;
ret = data.m_damageKills;
}
return ret;
}
// ----------------------------------------------------------------------
int WaterTypeManager::getDamageInterval(TerrainGeneratorWaterType type)
{
int ret = 0;
WaterTypeDataType::const_iterator const i = ms_waterTypeData->find(type);
if (i == ms_waterTypeData->end())
{
WARNING(true,("WaterTypeManager::getDamageInterval: Received request with type id %i, which isn't in the data table.", type));
}
else
{
WaterTypeDataRecord const & data = i->second;
ret = data.m_damageInterval;
}
return ret;
}
// ----------------------------------------------------------------------
float WaterTypeManager::getDamagePerInterval(TerrainGeneratorWaterType type)
{
float ret = 0.0f;
WaterTypeDataType::const_iterator const i = ms_waterTypeData->find(type);
if (i == ms_waterTypeData->end())
{
WARNING(true,("WaterTypeManager::getDamagePerInterval: Received request with type id %i, which isn't in the data table.", type));
}
else
{
WaterTypeDataRecord const & data = i->second;
ret = data.m_damagePerInterval;
}
return ret;
}
// ----------------------------------------------------------------------
bool WaterTypeManager::getTransparent(TerrainGeneratorWaterType type)
{
bool ret = false;
WaterTypeDataType::const_iterator const i = ms_waterTypeData->find(type);
if (i == ms_waterTypeData->end())
{
WARNING(true,("WaterTypeManager::getTransparent: Received request with type id %i, which isn't in the data table.", type));
}
else
{
WaterTypeDataRecord const & data = i->second;
ret = data.m_transparent;
}
return ret;
}
// ----------------------------------------------------------------------
float WaterTypeManager::getLavaResistance(const std::string& objectTemplateName)
{
float ret = 0.0f;
CreatureWaterTypeDataType::const_iterator const i = ms_creatureWaterTypeData->find(objectTemplateName);
if(i != ms_creatureWaterTypeData->end())
{
CreatureWaterTypeDataRecord const &data = i->second;
ret = data.m_lavaResistance;
}
return ret;
}
// ======================================================================
@@ -0,0 +1,71 @@
//===================================================================
//
// WaterTypeManager.h
//
// copyright 2005, Sony Online Entertainment
//
//===================================================================
#ifndef INCLUDED_WaterTypeManager_H
#define INCLUDED_WaterTypeManager_H
#include <string>
#include "sharedTerrain/TerrainGeneratorType.def"
//===================================================================
class WaterTypeManager
{
public:
static void install ();
static void remove ();
public:
static bool getCausesDamage(TerrainGeneratorWaterType type);
static bool getDamageKills(TerrainGeneratorWaterType type);
static int getDamageInterval(TerrainGeneratorWaterType type);
static float getDamagePerInterval(TerrainGeneratorWaterType type);
static bool getTransparent(TerrainGeneratorWaterType type);
static float getLavaResistance(const std::string& objectTemplateName);
private:
struct WaterTypeDataRecord
{
public:
WaterTypeDataRecord();
public:
int m_typeId;
std::string m_name;
bool m_causesDamage;
bool m_damageKills;
int m_damageInterval;
float m_damagePerInterval;
bool m_transparent;
};
struct CreatureWaterTypeDataRecord
{
public:
CreatureWaterTypeDataRecord();
public:
std::string m_objectTemplateName;
float m_lavaResistance;
};
typedef stdmap<int, WaterTypeDataRecord>::fwd WaterTypeDataType;
typedef stdmap<std::string, CreatureWaterTypeDataRecord>::fwd CreatureWaterTypeDataType;
static bool ms_installed;
static WaterTypeDataType * ms_waterTypeData;
static CreatureWaterTypeDataType* ms_creatureWaterTypeData;
};
//===================================================================
#endif
@@ -0,0 +1,48 @@
//===================================================================
//
// FloraManager.cpp
// asommers
//
// copyright 2000, verant interactive
//
//===================================================================
#include "sharedTerrain/FirstSharedTerrain.h"
#include "sharedTerrain/FloraManager.h"
//===================================================================
namespace FloraManagerNamespace
{
const Object* ms_referenceObject;
}
using namespace FloraManagerNamespace;
//===================================================================
const Object* FloraManager::getReferenceObject ()
{
return ms_referenceObject;
}
//-------------------------------------------------------------------
void FloraManager::setReferenceObject (const Object* const referenceObject)
{
ms_referenceObject = referenceObject;
}
//===================================================================
FloraManager::FloraManager ()
{
}
//-------------------------------------------------------------------
FloraManager::~FloraManager ()
{
}
//===================================================================
@@ -0,0 +1,34 @@
//===================================================================
//
// FloraManager.h
// asommers
//
// copyright 2001, sony online entertainment
//
//===================================================================
#ifndef INCLUDED_FloraManager_H
#define INCLUDED_FloraManager_H
//===================================================================
class Object;
//===================================================================
class FloraManager
{
public:
static const Object* getReferenceObject ();
static void setReferenceObject (const Object* referenceObject);
public:
FloraManager ();
virtual ~FloraManager ()=0;
};
//===================================================================
#endif
@@ -0,0 +1,25 @@
//===================================================================
//
// ServerFloraManager.cpp
// asommers
//
// copyright 2000, verant interactive
//
//===================================================================
#include "sharedTerrain/FirstSharedTerrain.h"
#include "sharedTerrain/ServerFloraManager.h"
//===================================================================
ServerFloraManager::ServerFloraManager ()
{
}
//-------------------------------------------------------------------
ServerFloraManager::~ServerFloraManager ()
{
}
//===================================================================
@@ -0,0 +1,26 @@
//===================================================================
//
// ServerFloraManager.h
// asommers
//
// copyright 2001, sony online entertainment
//
//===================================================================
#ifndef INCLUDED_ServerFloraManager_H
#define INCLUDED_ServerFloraManager_H
//===================================================================
class ServerFloraManager
{
public:
ServerFloraManager ();
virtual ~ServerFloraManager ()=0;
};
//===================================================================
#endif
@@ -0,0 +1,454 @@
//===================================================================
//
// Affector.cpp
// asommers 2001-01-17
//
// copyright 2001, verant interactive
//
//===================================================================
#include "sharedTerrain/FirstSharedTerrain.h"
#include "sharedTerrain/Affector.h"
#include "sharedMath/Line2d.h"
#include <algorithm>
//===================================================================
namespace
{
inline const float computeT (const Vector2d& start, const Vector2d& end, const Vector2d& point)
{
return ((point.x - start.x) * (end.x - start.x) + (point.y - start.y) * (end.y - start.y)) / (sqr (end.x - start.x) + sqr (end.y - start.y));
}
template<class T>
inline const T min (const T& a, const T& b)
{
return a < b ? a : b;
}
}
//===================================================================
void AffectorBoundaryPoly::FindData::reset ()
{
height = 0.f;
distanceToCenter = 0.f;
t = 0.f;
length = 0.f;
}
//===================================================================
bool AffectorBoundaryPoly::ms_enabled = true;
//===================================================================
AffectorBoundaryPoly::AffectorBoundaryPoly (const Tag newTag, const TerrainGeneratorAffectorType newType) :
TerrainGenerator::Affector (newTag, newType),
m_featherFunction (TGFF_linear),
m_featherDistance (0.5f),
m_pointList (),
m_lengths (),
m_lengthTotals (),
m_width (4.f),
m_extent (),
m_heightData ()
{
}
//-------------------------------------------------------------------
AffectorBoundaryPoly::~AffectorBoundaryPoly ()
{
}
//-------------------------------------------------------------------
float AffectorBoundaryPoly::isWithin (const float worldX, const float worldZ) const
{
if (!m_extent.isWithin (worldX, worldZ))
return 0.f;
const float widthSquared = sqr (m_width);
float distanceSquared = widthSquared;
//-- first, scan how far we are from the points
{
const int n = m_pointList.getNumberOfElements ();
int i;
for (i = 0; i < n; ++i)
{
const float x = m_pointList [i].x;
const float y = m_pointList [i].y;
const float thisDistanceSquared = sqr (worldX - x) + sqr (worldZ - y);
if (thisDistanceSquared < distanceSquared)
distanceSquared = thisDistanceSquared;
}
}
//-- next, scan each line
{
const int n = m_pointList.getNumberOfElements () - 1;
int i;
for (i = 0; i < n; ++i)
{
const float x1 = m_pointList [i].x;
const float y1 = m_pointList [i].y; //lint !e578 //-- hides y1 (double)
const float x2 = m_pointList [i + 1].x;
const float y2 = m_pointList [i + 1].y;
const float u = ((worldX - x1) * (x2 - x1) + (worldZ - y1) * (y2 - y1)) / (sqr (x2 - x1) + sqr (y2 - y1));
if (u >= 0 && u <= 1)
{
const float x = x1 + u * (x2 - x1);
const float y = y1 + u * (y2 - y1);
const float thisDistanceSquared = sqr (worldX - x) + sqr (worldZ - y);
if (thisDistanceSquared < distanceSquared)
distanceSquared = thisDistanceSquared;
}
}
}
if (distanceSquared < widthSquared)
{
const float newFeatherDistance = m_width * (1.f - getFeatherDistance ());
const float newFeatherDistanceSquared = sqr (newFeatherDistance);
if (distanceSquared < newFeatherDistanceSquared)
return 1.f;
return 1.f - (sqrt (distanceSquared) - newFeatherDistance) / (m_width - newFeatherDistance);
}
return 0.f;
}
//-------------------------------------------------------------------
void AffectorBoundaryPoly::addPoint (const Vector2d& point)
{
m_pointList.add (point);
recalculate ();
}
//-------------------------------------------------------------------
void AffectorBoundaryPoly::replacePoint (const int index, const Vector2d& newPoint)
{
m_pointList [index] = newPoint;
recalculate ();
}
//-------------------------------------------------------------------
void AffectorBoundaryPoly::removePoint (const int index)
{
m_pointList.removeIndexAndCompactList (index);
recalculate ();
}
//-------------------------------------------------------------------
void AffectorBoundaryPoly::clearPointList ()
{
m_pointList.clear ();
}
//-------------------------------------------------------------------
void AffectorBoundaryPoly::copyPointList (const ArrayList<Vector2d>& newPointList)
{
m_pointList = newPointList;
recalculate ();
}
//-------------------------------------------------------------------
void AffectorBoundaryPoly::recalculate ()
{
//
// recalculate extent
//
{
m_extent.x0 = FLT_MAX;
m_extent.y0 = FLT_MAX;
m_extent.x1 = -FLT_MAX;
m_extent.y1 = -FLT_MAX;
int i;
for (i = 0; i < m_pointList.getNumberOfElements (); ++i)
m_extent.expand (m_pointList [i].x, m_pointList [i].y);
m_extent.x0 -= m_width;
m_extent.y0 -= m_width;
m_extent.x1 += m_width;
m_extent.y1 += m_width;
}
//
// recalculate lengths
//
{
m_lengths.clear ();
m_lengthTotals.clear ();
m_lengths.push_back (0.f);
m_lengthTotals.push_back (0.f);
int i;
for (i = 1; i < m_pointList.getNumberOfElements (); ++i)
{
m_lengths.push_back (m_pointList [i].magnitudeBetween (m_pointList [i - 1]));
m_lengthTotals.push_back (m_lengths [i] + m_lengthTotals [i - 1]);
}
}
}
//-------------------------------------------------------------------
void AffectorBoundaryPoly::rotate (const float angle)
{
if (m_pointList.getNumberOfElements () == 0)
return;
Vector2d center;
int i;
for (i = 0; i < m_pointList.getNumberOfElements (); i++)
center += m_pointList [i];
center.x /= static_cast<float> (m_pointList.getNumberOfElements ());
center.y /= static_cast<float> (m_pointList.getNumberOfElements ());
rotate (angle, center);
}
//-------------------------------------------------------------------
void AffectorBoundaryPoly::rotate (const float angle, const Vector2d& center)
{
if (m_pointList.getNumberOfElements () == 0)
return;
const float cosAngle = cos (angle);
const float sinAngle = sin (angle);
int i;
for (i = 0; i < m_pointList.getNumberOfElements (); i++)
{
Vector2d point;
point.x = m_pointList [i].x - center.x;
point.y = m_pointList [i].y - center.y;
Vector2d newPoint;
newPoint.x = center.x + point.x * cosAngle - point.y * sinAngle;
newPoint.y = center.y + point.x * sinAngle + point.y * cosAngle;
m_pointList [i] = newPoint;
}
recalculate ();
}
//-------------------------------------------------------------------
void AffectorBoundaryPoly::translate (const Vector2d& translation)
{
int i;
for (i = 0; i < m_pointList.getNumberOfElements (); i++)
m_pointList [i] += translation;
recalculate ();
}
//-------------------------------------------------------------------
void AffectorBoundaryPoly::scale (const float scalar)
{
if (m_pointList.getNumberOfElements () == 0)
return;
Vector2d center;
int i;
for (i = 0; i < m_pointList.getNumberOfElements (); i++)
center += m_pointList [i];
center.x /= static_cast<float> (m_pointList.getNumberOfElements ());
center.y /= static_cast<float> (m_pointList.getNumberOfElements ());
for (i = 0; i < m_pointList.getNumberOfElements (); i++)
{
m_pointList [i].x = (m_pointList [i].x - center.x) * scalar + center.x;
m_pointList [i].y = (m_pointList [i].y - center.y) * scalar + center.y;
}
recalculate ();
}
//-------------------------------------------------------------------
void AffectorBoundaryPoly::expand (Rectangle2d& parentExtent) const
{
parentExtent.expand (m_extent.x0, m_extent.y0);
parentExtent.expand (m_extent.x1, m_extent.y1);
}
//-------------------------------------------------------------------
void AffectorBoundaryPoly::setWidth (const float newWidth)
{
m_width = newWidth;
recalculate ();
}
//-------------------------------------------------------------------
void AffectorBoundaryPoly::setFeatherFunction (TerrainGeneratorFeatherFunction newFeatherFunction)
{
m_featherFunction = newFeatherFunction;
}
//-------------------------------------------------------------------
void AffectorBoundaryPoly::setFeatherDistance (const float newFeatherDistance)
{
m_featherDistance = newFeatherDistance;
}
//-------------------------------------------------------------------
void AffectorBoundaryPoly::enable ()
{
ms_enabled = true;
}
//-------------------------------------------------------------------
void AffectorBoundaryPoly::disable ()
{
ms_enabled = false;
}
//-------------------------------------------------------------------
bool AffectorBoundaryPoly::isEnabled ()
{
return ms_enabled;
}
//-------------------------------------------------------------------
void AffectorBoundaryPoly::clearHeightData ()
{
m_heightData.clear ();
}
//-------------------------------------------------------------------
void AffectorBoundaryPoly::addSegmentHeightData ()
{
m_heightData.addSegment ();
}
//-------------------------------------------------------------------
void AffectorBoundaryPoly::addPointHeightData (const Vector& point)
{
m_heightData.addPoint (point);
}
//-------------------------------------------------------------------
bool AffectorBoundaryPoly::find (const Vector2d& point, const float width, FindData& result, bool ignoreHeight) const
{
if (m_pointList.empty ())
return false;
const float widthSquared = sqr (width);
float distanceSquared = widthSquared;
//-- first, scan how far we are from the points
{
int i;
for (i = 0; i < m_pointList.size (); ++i)
{
const float thisDistanceSquared = point.magnitudeBetweenSquared (m_pointList [i]);
if (thisDistanceSquared < distanceSquared)
{
distanceSquared = thisDistanceSquared;
result.t = m_lengthTotals [i];
result.height = (i != m_pointList.size () - 1) ? m_heightData.getPoint (i, 0).y : m_heightData.getPoint (i - 1, m_heightData.getNumberOfPoints (i - 1) - 1).y;
}
}
}
int segmentIndex = 0;
Vector2d resultPoint;
bool searchHeightData = false;
//-- next, scan each line
{
int i;
for (i = 0; i < m_pointList.size () - 1; ++i)
{
const Vector2d start = m_pointList [i];
const Vector2d end = m_pointList [i + 1];
const float t = computeT (start, end, point);
if (t >= 0 && t <= 1)
{
const Vector2d lerpedPoint = Vector2d::linearInterpolate (start, end, t);
const float thisDistanceSquared = point.magnitudeBetweenSquared (lerpedPoint);
if (thisDistanceSquared < distanceSquared)
{
distanceSquared = thisDistanceSquared;
segmentIndex = i;
resultPoint = lerpedPoint;
if(!ignoreHeight) // some affectors don't have height data (ribbon)
{
searchHeightData = true;
}
result.t = m_lengthTotals [i] + (t * m_lengths [i + 1]);
}
}
}
}
if (distanceSquared < widthSquared)
{
result.distanceToCenter = static_cast<float> (sqrt (distanceSquared));
result.length = m_lengthTotals.back ();
if (searchHeightData && !m_heightData.find (segmentIndex, resultPoint, result.height))
{
static bool s_warnedMissingHeightData = false;
if (!s_warnedMissingHeightData)
{
s_warnedMissingHeightData = true;
DEBUG_WARNING (true, ("AffectorBoundaryPoly::find - couldn't find height data for %s. Did you not bake the river/road data?", getName ()));
}
result.height = 0.f;
}
return true;
}
return false;
}
//===================================================================
@@ -0,0 +1,200 @@
//===================================================================
//
// Affector.h
// asommers 9-30-2000
//
// copyright 2000, verant interactive
//
//===================================================================
#ifndef INCLUDED_Affector_H
#define INCLUDED_Affector_H
//===================================================================
#include "sharedMath/Vector2d.h"
#include "sharedTerrain/TerrainGenerator.h"
#include "sharedTerrain/HeightData.h"
//===================================================================
class AffectorExclude : public TerrainGenerator::Affector
{
public:
AffectorExclude ();
virtual ~AffectorExclude ();
virtual void affect (float worldX, float worldZ, int x, int z, float amount, const TerrainGenerator::GeneratorChunkData& generatorChunkData) const;
virtual void load (Iff& iff);
virtual void save (Iff& iff) const;
virtual unsigned getAffectedMaps() const;
private:
void load_0000 (Iff& iff);
private:
AffectorExclude (const AffectorExclude& rhs);
AffectorExclude& operator= (const AffectorExclude& rhs);
};
//===================================================================
class AffectorBoundaryPoly : public TerrainGenerator::Affector
{
public:
AffectorBoundaryPoly (Tag newTag, TerrainGeneratorAffectorType newType);
virtual ~AffectorBoundaryPoly ()=0;
virtual float isWithin (float worldX, float worldZ) const;
TerrainGeneratorFeatherFunction getFeatherFunction () const;
void setFeatherFunction (TerrainGeneratorFeatherFunction newFeatherFunction);
float getFeatherDistance () const;
void setFeatherDistance (float newFeatherDistance);
void rotate (float angle);
void rotate (float angle, const Vector2d& center);
void translate (const Vector2d& translation);
void scale (float scalar);
void expand (Rectangle2d& extent) const;
const Vector2d getCenter () const;
const ArrayList<Vector2d>& getPointList () const;
int getNumberOfPoints () const;
const Vector2d& getPoint (int index) const;
void addPoint (const Vector2d& point);
void replacePoint (int index, const Vector2d& point);
void removePoint (int index);
void clearPointList ();
void copyPointList (const ArrayList<Vector2d>& newPointList);
void setWidth (float newWidth);
float getWidth () const;
const Rectangle2d& getExtent () const;
const HeightData& getHeightData () const;
void clearHeightData ();
void addSegmentHeightData ();
void addPointHeightData (const Vector& point);
virtual void createHeightData ()=0;
//--
static bool isEnabled ();
static void enable ();
static void disable ();
protected:
struct FindData
{
public:
float height;
float distanceToCenter;
float t;
float length;
public:
void reset ();
};
protected:
virtual void recalculate ();
//-- find the closest height along the list of points to position (returns t along entire list of segments)
bool find (const Vector2d& point, const float width, FindData& result,bool ignoreHeight = false) const;
protected:
TerrainGeneratorFeatherFunction m_featherFunction;
float m_featherDistance;
ArrayList<Vector2d> m_pointList;
ArrayList<float> m_lengths;
ArrayList<float> m_lengthTotals;
float m_width;
Rectangle2d m_extent;
HeightData m_heightData;
private:
AffectorBoundaryPoly (const AffectorBoundaryPoly& rhs);
AffectorBoundaryPoly& operator= (const AffectorBoundaryPoly& rhs);
private:
static bool ms_enabled;
};
//===================================================================
inline const ArrayList<Vector2d>& AffectorBoundaryPoly::getPointList () const
{
return m_pointList;
}
//-------------------------------------------------------------------
inline int AffectorBoundaryPoly::getNumberOfPoints () const
{
return m_pointList.getNumberOfElements ();
}
//-------------------------------------------------------------------
inline const Vector2d& AffectorBoundaryPoly::getPoint (int index) const
{
return m_pointList [index];
}
//-------------------------------------------------------------------
inline const Vector2d AffectorBoundaryPoly::getCenter () const
{
return m_extent.getCenter ();
}
//-------------------------------------------------------------------
inline float AffectorBoundaryPoly::getWidth () const
{
return m_width;
}
//-------------------------------------------------------------------
inline TerrainGeneratorFeatherFunction AffectorBoundaryPoly::getFeatherFunction () const
{
return m_featherFunction;
}
//-------------------------------------------------------------------
inline float AffectorBoundaryPoly::getFeatherDistance () const
{
return m_featherDistance;
}
//-------------------------------------------------------------------
inline const Rectangle2d& AffectorBoundaryPoly::getExtent () const
{
return m_extent;
}
//-------------------------------------------------------------------
inline const HeightData& AffectorBoundaryPoly::getHeightData () const
{
return m_heightData;
}
//===================================================================
#endif
@@ -0,0 +1,616 @@
//
// AffectorColor.cpp
// asommers 9-30-2000
//
// copyright 2000, verant interactive
//
//-------------------------------------------------------------------
#include "sharedTerrain/FirstSharedTerrain.h"
#include "sharedTerrain/AffectorColor.h"
#include "sharedFile/Iff.h"
#include "sharedFractal/MultiFractal.h"
#include "sharedFractal/MultiFractalReaderWriter.h"
#include "sharedImage/Image.h"
#include "sharedImage/ImageFormatList.h"
#include "sharedTerrain/Affector.h"
#include "sharedSynchronization/Mutex.h"
#include <algorithm>
#include <string>
//-------------------------------------------------------------------
static const PackedRgb computeColor (const PackedRgb& oldColor, const PackedRgb& desiredColor, const TerrainGeneratorOperation operation, const float amount)
{
PackedRgb newColor = desiredColor;
if (amount < 1.f)
{
newColor.r = static_cast<uint8> (desiredColor.r * amount);
newColor.g = static_cast<uint8> (desiredColor.g * amount);
newColor.b = static_cast<uint8> (desiredColor.b * amount);
}
switch (operation)
{
case TGO_add:
{
newColor.r = static_cast<uint8> (std::min (oldColor.r + newColor.r, 255));
newColor.g = static_cast<uint8> (std::min (oldColor.g + newColor.g, 255));
newColor.b = static_cast<uint8> (std::min (oldColor.b + newColor.b, 255));
}
break;
case TGO_subtract:
{
newColor.r = static_cast<uint8> (std::max (oldColor.r - newColor.r, 0));
newColor.g = static_cast<uint8> (std::max (oldColor.g - newColor.g, 0));
newColor.b = static_cast<uint8> (std::max (oldColor.b - newColor.b, 0));
}
break;
case TGO_multiply:
{
newColor.r = static_cast<uint8> (amount * (0.5f * desiredColor.r + 0.5f * oldColor.r) + (1.f - amount) * oldColor.r);
newColor.g = static_cast<uint8> (amount * (0.5f * desiredColor.g + 0.5f * oldColor.g) + (1.f - amount) * oldColor.g);
newColor.b = static_cast<uint8> (amount * (0.5f * desiredColor.b + 0.5f * oldColor.b) + (1.f - amount) * oldColor.b);
}
break;
case TGO_replace:
default:
{
newColor.r = static_cast<uint8> (amount * desiredColor.r + (1.f - amount) * oldColor.r);
newColor.g = static_cast<uint8> (amount * desiredColor.g + (1.f - amount) * oldColor.g);
newColor.b = static_cast<uint8> (amount * desiredColor.b + (1.f - amount) * oldColor.b);
}
break;
case TGO_COUNT:
FATAL (true, ("invalid operation"));
break;
}
return newColor;
}
//-------------------------------------------------------------------
//
// AffectorColorConstant
//
AffectorColorConstant::AffectorColorConstant () :
TerrainGenerator::Affector (TAG_ACCN, TGAT_colorConstant),
operation (TGO_replace),
color ()
{
}
//-------------------------------------------------------------------
AffectorColorConstant::~AffectorColorConstant ()
{
}
//-------------------------------------------------------------------
void AffectorColorConstant::setOperation (const TerrainGeneratorOperation newOperation)
{
operation = newOperation;
}
//-------------------------------------------------------------------
void AffectorColorConstant::setColor (const PackedRgb& newColor)
{
color = newColor;
}
//-------------------------------------------------------------------
unsigned AffectorColorConstant::getAffectedMaps() const
{
return TGM_color;
}
//-------------------------------------------------------------------
void AffectorColorConstant::affect (const float /*worldX*/, const float /*worldZ*/, const int x, const int z, const float amount, const TerrainGenerator::GeneratorChunkData& generatorChunkData) const
{
if (amount > 0.f)
{
const PackedRgb oldColor = generatorChunkData.colorMap->getData (x, z);
const PackedRgb newColor = computeColor (oldColor, color, operation, amount);
generatorChunkData.colorMap->setData (x, z, newColor);
}
}
//-------------------------------------------------------------------
void AffectorColorConstant::load (Iff& iff)
{
switch (iff.getCurrentName ())
{
case TAG_0000:
load_0000 (iff);
break;
default:
{
char tagBuffer [5];
ConvertTagToString (iff.getCurrentName (), tagBuffer);
char buffer [128];
iff.formatLocation (buffer, sizeof (buffer));
DEBUG_FATAL (true, ("invalid AffectorColorConstant version %s/%s", buffer, tagBuffer));
}
break;
}
}
//-------------------------------------------------------------------
void AffectorColorConstant::load_0000 (Iff& iff)
{
iff.enterForm (TAG_0000);
//-- load the base data
LayerItem::load (iff);
//-- load specific data
iff.enterChunk (TAG_DATA);
int newOperation = iff.read_int32 ();
DEBUG_FATAL (newOperation < 0 || newOperation >= TGO_COUNT, ("operation out of bounds for %s (%i)", getName (), newOperation));
operation = static_cast<TerrainGeneratorOperation> (newOperation);
color.r = iff.read_uint8 ();
color.g = iff.read_uint8 ();
color.b = iff.read_uint8 ();
iff.exitChunk (TAG_DATA);
iff.exitForm (TAG_0000);
}
//-------------------------------------------------------------------
void AffectorColorConstant::save (Iff& iff) const
{
iff.insertForm (TAG_0000);
//-- save the base
LayerItem::save (iff);
//-- save specific data
iff.insertChunk (TAG_DATA);
iff.insertChunkData (static_cast<int32> (operation));
iff.insertChunkData (color.r);
iff.insertChunkData (color.g);
iff.insertChunkData (color.b);
iff.exitChunk (TAG_DATA);
iff.exitForm (TAG_0000);
}
//-------------------------------------------------------------------
//
// AffectorColorRampHeight
//
AffectorColorRampHeight::AffectorColorRampHeight () :
TerrainGenerator::Affector (TAG_ACRH, TGAT_colorRampHeight),
image (0),
operation (TGO_replace),
lowHeight (0),
highHeight (0),
imageName (NON_NULL (new std::string))
{
}
//-------------------------------------------------------------------
AffectorColorRampHeight::~AffectorColorRampHeight ()
{
if (image)
{
delete image;
image = 0;
}
delete imageName;
imageName = 0;
}
//-------------------------------------------------------------------
void AffectorColorRampHeight::setOperation (const TerrainGeneratorOperation newOperation)
{
operation = newOperation;
}
//-------------------------------------------------------------------
void AffectorColorRampHeight::setLowHeight (const float newLowHeight)
{
lowHeight = newLowHeight;
}
//-------------------------------------------------------------------
void AffectorColorRampHeight::setHighHeight (const float newHighHeight)
{
highHeight = newHighHeight;
}
//-------------------------------------------------------------------
void AffectorColorRampHeight::setImage (const std::string& newImageName)
{
*imageName = newImageName;
if (image)
delete image;
image = ImageFormatList::loadImage (imageName->c_str ());
if (image)
{
DEBUG_WARNING (image->getHeight () != 1, ("height != 1"));
DEBUG_WARNING (! (image->getPixelFormat () == Image::PF_bgr_888 || image->getPixelFormat () == Image::PF_rgb_888), ("image is not in rgb or bgr format"));
}
}
//-------------------------------------------------------------------
static const PackedRgb getPixel (const Image* image, const int x, const int y)
{
PackedRgb result = PackedRgb::solidBlack;
if (x >= 0 && x < image->getWidth () &&
y >= 0 && y < image->getHeight ())
{
static Mutex mutex;
mutex.enter ();
const uint8* data = image->lockReadOnly ();
data += y * image->getStride () + x * image->getBytesPerPixel ();
if (image->getPixelFormat () == Image::PF_bgr_888)
{
result.b = *data++;
result.g = *data++;
result.r = *data++;
}
else
{
result.r = *data++;
result.g = *data++;
result.b = *data++;
}
image->unlock ();
mutex.leave ();
}
return result;
}
//-------------------------------------------------------------------
unsigned AffectorColorRampHeight::getAffectedMaps() const
{
return TGM_color;
}
//-------------------------------------------------------------------
void AffectorColorRampHeight::affect (const float /*worldX*/, const float /*worldZ*/, const int x, const int z, const float amount, const TerrainGenerator::GeneratorChunkData& generatorChunkData) const
{
if (image && amount > 0.f)
{
const float height = generatorChunkData.heightMap->getData (x, z);
if (WithinRangeInclusiveInclusive (lowHeight, height, highHeight))
{
const PackedRgb oldColor = generatorChunkData.colorMap->getData (x, z);
const float t = (height - lowHeight) / (highHeight - lowHeight);
const PackedRgb color = getPixel (image, static_cast<int> (t * (image->getWidth () - 1)), 0);
const PackedRgb newColor = computeColor (oldColor, color, operation, amount);
generatorChunkData.colorMap->setData (x, z, newColor);
}
}
}
//-------------------------------------------------------------------
void AffectorColorRampHeight::load (Iff& iff)
{
switch (iff.getCurrentName ())
{
case TAG_0000:
load_0000 (iff);
break;
default:
{
char tagBuffer [5];
ConvertTagToString (iff.getCurrentName (), tagBuffer);
char buffer [128];
iff.formatLocation (buffer, sizeof (buffer));
DEBUG_FATAL (true, ("invalid AffectorColorRampHeight version %s/%s", buffer, tagBuffer));
}
break;
}
}
//-------------------------------------------------------------------
void AffectorColorRampHeight::load_0000 (Iff& iff)
{
iff.enterForm (TAG_0000);
//-- load the base data
LayerItem::load (iff);
//-- load specific data
iff.enterChunk (TAG_DATA);
int newOperation = iff.read_int32 ();
DEBUG_FATAL (newOperation < 0 || newOperation >= TGO_COUNT, ("operation out of bounds for %s (%i)", getName (), newOperation));
operation = static_cast<TerrainGeneratorOperation> (newOperation);
lowHeight = iff.read_float ();
highHeight = iff.read_float ();
char* newImageName = iff.read_string ();
setImage (newImageName);
delete [] newImageName;
iff.exitChunk (TAG_DATA);
iff.exitForm (TAG_0000);
}
//-------------------------------------------------------------------
void AffectorColorRampHeight::save (Iff& iff) const
{
iff.insertForm (TAG_0000);
//-- save the base
LayerItem::save (iff);
//-- save specific data
iff.insertChunk (TAG_DATA);
iff.insertChunkData (static_cast<int32> (operation));
iff.insertChunkData (lowHeight);
iff.insertChunkData (highHeight);
iff.insertChunkString (imageName->c_str ());
iff.exitChunk (TAG_DATA);
iff.exitForm (TAG_0000);
}
//-------------------------------------------------------------------
//
// AffectorColorRampFractal
//
AffectorColorRampFractal::AffectorColorRampFractal () :
TerrainGenerator::Affector (TAG_ACRF, TGAT_colorRampFractal),
m_multiFractal (0),
m_cachedFamilyId (-1),
image (0),
m_familyId (0),
operation (TGO_replace),
imageName (NON_NULL (new std::string))
{
}
//-------------------------------------------------------------------
AffectorColorRampFractal::~AffectorColorRampFractal ()
{
if (image)
{
delete image;
image = 0;
}
delete imageName;
imageName = 0;
m_multiFractal = 0;
}
//-------------------------------------------------------------------
void AffectorColorRampFractal::setFamilyId (const int newFamilyId)
{
m_familyId = newFamilyId;
}
//-------------------------------------------------------------------
void AffectorColorRampFractal::setOperation (const TerrainGeneratorOperation newOperation)
{
operation = newOperation;
}
//-------------------------------------------------------------------
void AffectorColorRampFractal::setImage (const std::string& newImageName)
{
*imageName = newImageName;
if (image)
delete image;
image = ImageFormatList::loadImage (imageName->c_str ());
if (image)
{
DEBUG_WARNING (image->getHeight () != 1, ("height != 1"));
DEBUG_WARNING (! (image->getPixelFormat () == Image::PF_bgr_888 || image->getPixelFormat () == Image::PF_rgb_888), ("image is not in rgb or bgr format"));
}
}
//-------------------------------------------------------------------
unsigned AffectorColorRampFractal::getAffectedMaps() const
{
return TGM_color;
}
//-------------------------------------------------------------------
void AffectorColorRampFractal::affect (const float worldX, const float worldZ, const int x, const int z, const float amount, const TerrainGenerator::GeneratorChunkData& generatorChunkData) const
{
if (image && amount > 0.f)
{
if (m_cachedFamilyId != m_familyId)
{
m_cachedFamilyId = m_familyId;
m_multiFractal = generatorChunkData.fractalGroup->getFamilyMultiFractal (m_familyId);
}
NOT_NULL (m_multiFractal);
const PackedRgb oldColor = generatorChunkData.colorMap->getData (x, z);
const float t = m_multiFractal->getValueCache (worldX, worldZ, x, z);
const PackedRgb color = getPixel (image, static_cast<int> (t * (image->getWidth () - 1)), 0);
const PackedRgb newColor = computeColor (oldColor, color, operation, amount);
generatorChunkData.colorMap->setData (x, z, newColor);
}
}
//-------------------------------------------------------------------
void AffectorColorRampFractal::load (Iff& iff, FractalGroup& fractalGroup)
{
switch (iff.getCurrentName ())
{
case TAG_0000:
load_0000 (iff, fractalGroup);
break;
case TAG_0001:
load_0001 (iff);
break;
default:
{
char tagBuffer [5];
ConvertTagToString (iff.getCurrentName (), tagBuffer);
char buffer [128];
iff.formatLocation (buffer, sizeof (buffer));
DEBUG_FATAL (true, ("invalid AffectorColorRampFractal version %s/%s", buffer, tagBuffer));
}
break;
}
}
//-------------------------------------------------------------------
void AffectorColorRampFractal::load_0000 (Iff& iff, FractalGroup& fractalGroup)
{
iff.enterForm (TAG_0000);
//-- load the base data
LayerItem::load (iff);
//-- load specific data
iff.enterForm (TAG_DATA);
//-- load the fractal settings
MultiFractal multiFractal;
MultiFractalReaderWriter::load (iff, multiFractal);
setFamilyId (fractalGroup.createFamily (&multiFractal, getName ()));
//-- load parameters
iff.enterChunk (TAG_PARM);
int newOperation = iff.read_int32 ();
DEBUG_FATAL (newOperation < 0 || newOperation >= TGO_COUNT, ("operation out of bounds for %s (%i)", getName (), newOperation));
operation = static_cast<TerrainGeneratorOperation> (newOperation);
char* newImageName = iff.read_string ();
setImage (newImageName);
delete [] newImageName;
iff.exitChunk ();
iff.exitForm (TAG_DATA);
iff.exitForm (TAG_0000);
}
//-------------------------------------------------------------------
void AffectorColorRampFractal::load_0001 (Iff& iff)
{
iff.enterForm (TAG_0001);
//-- load the base data
LayerItem::load (iff);
//-- load specific data
iff.enterForm (TAG_DATA);
//-- load parameters
iff.enterChunk (TAG_PARM);
setFamilyId (iff.read_int32 ());
int newOperation = iff.read_int32 ();
DEBUG_FATAL (newOperation < 0 || newOperation >= TGO_COUNT, ("operation out of bounds for %s (%i)", getName (), newOperation));
setOperation (static_cast<TerrainGeneratorOperation> (newOperation));
char* newImageName = iff.read_string ();
setImage (newImageName);
delete [] newImageName;
iff.exitChunk ();
iff.exitForm (TAG_DATA);
iff.exitForm (TAG_0001);
}
//-------------------------------------------------------------------
void AffectorColorRampFractal::save (Iff& iff) const
{
iff.insertForm (TAG_0001);
//-- save the base
LayerItem::save (iff);
//-- save specific data
iff.insertForm (TAG_DATA);
iff.insertChunk (TAG (P,A,R,M));
iff.insertChunkData (getFamilyId ());
iff.insertChunkData (static_cast<int32> (getOperation ()));
iff.insertChunkString (getImageName ().c_str ());
iff.exitChunk ();
iff.exitForm ();
iff.exitForm ();
}
//-------------------------------------------------------------------
@@ -0,0 +1,213 @@
//===================================================================
//
// AffectorColor.h
// asommers 9-30-2000
//
// copyright 2000, verant interactive
//
//===================================================================
#ifndef INCLUDED_AffectorColor_H
#define INCLUDED_AffectorColor_H
//===================================================================
#include "sharedTerrain/TerrainGenerator.h"
class Image;
//===================================================================
class AffectorColorConstant : public TerrainGenerator::Affector
{
private:
//-- accessible
TerrainGeneratorOperation operation;
PackedRgb color;
private:
void load_0000 (Iff& iff);
private:
AffectorColorConstant (const AffectorColorConstant& rhs);
AffectorColorConstant& operator= (const AffectorColorConstant& rhs);
public:
AffectorColorConstant ();
virtual ~AffectorColorConstant ();
virtual void affect (float worldX, float worldZ, int x, int z, float amount, const TerrainGenerator::GeneratorChunkData& generatorChunkData) const;
virtual void load (Iff& iff);
virtual void save (Iff& iff) const;
virtual unsigned getAffectedMaps() const;
TerrainGeneratorOperation getOperation () const;
void setOperation (TerrainGeneratorOperation newOperation);
const PackedRgb& getColor () const;
void setColor (const PackedRgb& newColor);
};
//-------------------------------------------------------------------
inline TerrainGeneratorOperation AffectorColorConstant::getOperation () const
{
return operation;
}
//-------------------------------------------------------------------
inline const PackedRgb& AffectorColorConstant::getColor () const
{
return color;
}
//-------------------------------------------------------------------
class AffectorColorRampHeight : public TerrainGenerator::Affector
{
private:
//-- not accessible
Image* image;
//-- accessible
TerrainGeneratorOperation operation;
float lowHeight;
float highHeight;
std::string* imageName;
private:
void load_0000 (Iff& iff);
private:
AffectorColorRampHeight (const AffectorColorRampHeight& rhs);
AffectorColorRampHeight& operator= (const AffectorColorRampHeight& rhs);
public:
AffectorColorRampHeight ();
virtual ~AffectorColorRampHeight ();
virtual void affect (float worldX, float worldZ, int x, int z, float amount, const TerrainGenerator::GeneratorChunkData& generatorChunkData) const;
virtual void load (Iff& iff);
virtual void save (Iff& iff) const;
virtual unsigned getAffectedMaps() const;
TerrainGeneratorOperation getOperation () const;
void setOperation (TerrainGeneratorOperation newOperation);
float getLowHeight () const;
void setLowHeight (float newLowHeight);
float getHighHeight () const;
void setHighHeight (float newHighHeight);
const std::string& getImageName () const;
void setImage (const std::string& newImageName);
};
//-------------------------------------------------------------------
inline TerrainGeneratorOperation AffectorColorRampHeight::getOperation () const
{
return operation;
}
//-------------------------------------------------------------------
inline float AffectorColorRampHeight::getLowHeight () const
{
return lowHeight;
}
//-------------------------------------------------------------------
inline float AffectorColorRampHeight::getHighHeight () const
{
return highHeight;
}
//-------------------------------------------------------------------
inline const std::string& AffectorColorRampHeight::getImageName () const
{
return *imageName;
}
//-------------------------------------------------------------------
class AffectorColorRampFractal : public TerrainGenerator::Affector
{
private:
//-- not accessible
mutable const MultiFractal* m_multiFractal;
mutable int m_cachedFamilyId;
Image* image;
//-- accessible
int m_familyId;
TerrainGeneratorOperation operation;
std::string* imageName;
private:
void load_0000 (Iff& iff, FractalGroup& fractalGroup);
void load_0001 (Iff& iff);
private:
AffectorColorRampFractal (const AffectorColorRampFractal& rhs);
AffectorColorRampFractal& operator= (const AffectorColorRampFractal& rhs);
public:
AffectorColorRampFractal ();
virtual ~AffectorColorRampFractal ();
virtual void affect (float worldX, float worldZ, int x, int z, float amount, const TerrainGenerator::GeneratorChunkData& generatorChunkData) const;
virtual void load (Iff& iff, FractalGroup& fractalGroup);
virtual void save (Iff& iff) const;
virtual unsigned getAffectedMaps() const;
TerrainGeneratorOperation getOperation () const;
void setOperation (TerrainGeneratorOperation newOperation);
const std::string& getImageName () const;
void setImage (const std::string& newImageName);
int getFamilyId () const;
void setFamilyId (int id);
};
//-------------------------------------------------------------------
inline int AffectorColorRampFractal::getFamilyId () const
{
return m_familyId;
}
//-------------------------------------------------------------------
inline TerrainGeneratorOperation AffectorColorRampFractal::getOperation () const
{
return operation;
}
//-------------------------------------------------------------------
inline const std::string& AffectorColorRampFractal::getImageName () const
{
return *imageName;
}
//===================================================================
#endif
@@ -0,0 +1,161 @@
//===================================================================
//
// AffectorEnvironment.cpp
// asommers 9-30-2000
//
// copyright 2000, verant interactive
//
//===================================================================
#include "sharedTerrain/FirstSharedTerrain.h"
#include "sharedTerrain/AffectorEnvironment.h"
#include "sharedTerrain/Affector.h"
#include "sharedFile/Iff.h"
//-------------------------------------------------------------------
//
// AffectorEnvironment
//
AffectorEnvironment::AffectorEnvironment () :
TerrainGenerator::Affector (TAG_AENV, TGAT_environment),
m_cachedFamilyId (-1),
m_cachedEgi (),
m_cachedFeatherClamp (0.f),
m_familyId (0),
m_useFeatherClampOverride (false),
m_featherClampOverride (1.f)
{
}
//-------------------------------------------------------------------
AffectorEnvironment::~AffectorEnvironment ()
{
}
//-------------------------------------------------------------------
void AffectorEnvironment::setFamilyId (const int familyId)
{
m_familyId = familyId;
}
//-------------------------------------------------------------------
void AffectorEnvironment::setUseFeatherClampOverride (const bool useFeatherClampOverride)
{
m_useFeatherClampOverride = useFeatherClampOverride;
}
//-------------------------------------------------------------------
void AffectorEnvironment::setFeatherClampOverride (const float featherClampOverride)
{
m_featherClampOverride = featherClampOverride;
}
//-------------------------------------------------------------------
void AffectorEnvironment::prepare ()
{
m_cachedFamilyId = -1;
}
//-------------------------------------------------------------------
unsigned AffectorEnvironment::getAffectedMaps() const
{
return TGM_environment;
}
//-------------------------------------------------------------------
void AffectorEnvironment::affect (const float /*worldX*/, const float /*worldZ*/, const int x, const int z, const float amount, const TerrainGenerator::GeneratorChunkData& generatorChunkData) const
{
if (amount > 0.f)
{
if (m_cachedFamilyId != m_familyId)
{
m_cachedFamilyId = m_familyId;
m_cachedEgi = generatorChunkData.environmentGroup->chooseEnvironment (m_familyId);
m_cachedFeatherClamp = generatorChunkData.environmentGroup->getFamilyFeatherClamp (m_familyId);
}
const float featherClamp = m_useFeatherClampOverride ? m_featherClampOverride : m_cachedFeatherClamp;
if (amount >= featherClamp)
{
EnvironmentGroup::Info egi = m_cachedEgi;
generatorChunkData.environmentMap->setData (x, z, egi);
}
}
}
//-------------------------------------------------------------------
void AffectorEnvironment::load (Iff& iff)
{
switch (iff.getCurrentName ())
{
case TAG_0000:
load_0000 (iff);
break;
default:
{
char tagBuffer [5];
ConvertTagToString (iff.getCurrentName (), tagBuffer);
char buffer [128];
iff.formatLocation (buffer, sizeof (buffer));
DEBUG_FATAL (true, ("invalid AffectorEnvironment version %s/%s", buffer, tagBuffer));
}
break;
}
}
//-------------------------------------------------------------------
void AffectorEnvironment::load_0000 (Iff& iff)
{
iff.enterForm (TAG_0000);
//-- load the base data
LayerItem::load (iff);
//-- load specific data
iff.enterChunk (TAG_DATA);
setFamilyId (iff.read_int32 ());
setUseFeatherClampOverride (iff.read_int32 () != 0);
setFeatherClampOverride (iff.read_float ());
iff.exitChunk (TAG_DATA);
iff.exitForm (TAG_0000);
}
//-------------------------------------------------------------------
void AffectorEnvironment::save (Iff& iff) const
{
iff.insertForm (TAG_0000);
//-- save the base
LayerItem::save (iff);
//-- save specific data
iff.insertChunk (TAG_DATA);
iff.insertChunkData (getFamilyId ());
iff.insertChunkData (getUseFeatherClampOverride () ? static_cast<int32> (1) : static_cast<int32> (0));
iff.insertChunkData (getFeatherClampOverride ());
iff.exitChunk (TAG_DATA);
iff.exitForm (TAG_0000);
}
//===================================================================
@@ -0,0 +1,86 @@
//===================================================================
//
// AffectorEnvironment.h
// asommers 9-30-2000
//
// copyright 2000, verant interactive
//
//===================================================================
#ifndef INCLUDED_AffectorEnvironment_H
#define INCLUDED_AffectorEnvironment_H
//===================================================================
#include "sharedTerrain/TerrainGenerator.h"
//===================================================================
class AffectorEnvironment : public TerrainGenerator::Affector
{
private:
//-- not accessible
mutable int m_cachedFamilyId;
mutable EnvironmentGroup::Info m_cachedEgi;
mutable float m_cachedFeatherClamp;
//-- accessible
int m_familyId;
bool m_useFeatherClampOverride;
float m_featherClampOverride;
private:
void load_0000 (Iff& iff);
private:
AffectorEnvironment (const AffectorEnvironment& rhs);
AffectorEnvironment& operator= (const AffectorEnvironment& rhs);
public:
AffectorEnvironment ();
virtual ~AffectorEnvironment ();
virtual void prepare ();
virtual void affect (float worldX, float worldZ, int x, int z, float amount, const TerrainGenerator::GeneratorChunkData& generatorChunkData) const;
virtual void load (Iff& iff);
virtual void save (Iff& iff) const;
virtual unsigned getAffectedMaps() const;
int getFamilyId () const;
void setFamilyId (int newFamilyId);
bool getUseFeatherClampOverride () const;
void setUseFeatherClampOverride (bool useFeatherClampOverride);
float getFeatherClampOverride () const;
void setFeatherClampOverride (float featherClampOverride);
};
//-------------------------------------------------------------------
inline int AffectorEnvironment::getFamilyId () const
{
return m_familyId;
}
//-------------------------------------------------------------------
inline bool AffectorEnvironment::getUseFeatherClampOverride () const
{
return m_useFeatherClampOverride;
}
//-------------------------------------------------------------------
inline float AffectorEnvironment::getFeatherClampOverride () const
{
return m_featherClampOverride;
}
//===================================================================
#endif
@@ -0,0 +1,101 @@
//
// AffectorExclude.cpp
// asommers 9-30-2000
//
// copyright 2000, verant interactive
//
//-------------------------------------------------------------------
#include "sharedTerrain/FirstSharedTerrain.h"
#include "sharedTerrain/AffectorExclude.h"
#include "sharedFile/Iff.h"
//-------------------------------------------------------------------
//
// AffectorExclude
//
AffectorExclude::AffectorExclude () :
TerrainGenerator::Affector (TAG_AEXC, TGAT_exclude)
{
}
//-------------------------------------------------------------------
AffectorExclude::~AffectorExclude ()
{
}
//-------------------------------------------------------------------
unsigned AffectorExclude::getAffectedMaps() const
{
return TGM_exclude;
}
//-------------------------------------------------------------------
void AffectorExclude::affect (const float /*worldX*/, const float /*worldZ*/, const int x, const int z, const float amount, const TerrainGenerator::GeneratorChunkData& generatorChunkData) const
{
if (amount > 0.f)
generatorChunkData.excludeMap->setData (x, z, true);
}
//-------------------------------------------------------------------
void AffectorExclude::load (Iff& iff)
{
switch (iff.getCurrentName ())
{
case TAG_0000:
load_0000 (iff);
break;
default:
{
char tagBuffer [5];
ConvertTagToString (iff.getCurrentName (), tagBuffer);
char buffer [128];
iff.formatLocation (buffer, sizeof (buffer));
DEBUG_FATAL (true, ("invalid AffectorExclude version %s/%s", buffer, tagBuffer));
}
break;
}
}
//-------------------------------------------------------------------
void AffectorExclude::load_0000 (Iff& iff)
{
iff.enterForm (TAG_0000);
//-- load the base data
LayerItem::load (iff);
//-- load specific data
iff.enterChunk (TAG_DATA);
iff.exitChunk (TAG_DATA);
iff.exitForm (TAG_0000);
}
//-------------------------------------------------------------------
void AffectorExclude::save (Iff& iff) const
{
iff.insertForm (TAG_0000);
//-- save the base
LayerItem::save (iff);
//-- save specific data
iff.insertChunk (TAG_DATA);
iff.exitChunk (TAG_DATA);
iff.exitForm (TAG_0000);
}
//-------------------------------------------------------------------
@@ -0,0 +1,44 @@
//===================================================================
//
// AffectorExclude.h
// asommers 9-30-2000
//
// copyright 2000, verant interactive
//
//===================================================================
#ifndef INCLUDED_AffectorExclude_H
#define INCLUDED_AffectorExclude_H
//===================================================================
#include "sharedTerrain/TerrainGenerator.h"
//===================================================================
class AffectorExclude : public TerrainGenerator::Affector
{
private:
void load_0000 (Iff& iff);
private:
AffectorExclude (const AffectorExclude& rhs);
AffectorExclude& operator= (const AffectorExclude& rhs);
public:
AffectorExclude ();
virtual ~AffectorExclude ();
virtual void affect (float worldX, float worldZ, int x, int z, float amount, const TerrainGenerator::GeneratorChunkData& generatorChunkData) const;
virtual void load (Iff& iff);
virtual void save (Iff& iff) const;
virtual unsigned getAffectedMaps() const;
};
//===================================================================
#endif
@@ -0,0 +1,383 @@
//===================================================================
//
// AffectorFloraDynamic.cpp
// asommers 9-30-2000
//
// copyright 2000, verant interactive
//
//===================================================================
#include "sharedTerrain/FirstSharedTerrain.h"
#include "sharedTerrain/AffectorFloraDynamic.h"
#include "sharedTerrain/Affector.h"
#include "sharedTerrain/CoordinateHash.h"
#include "sharedRandom/FastRandomGenerator.h"
#include "sharedFile/Iff.h"
//===================================================================
//
// AffectorFloraDynamic
//
AffectorFloraDynamic::AffectorFloraDynamic (const Tag newTag, const TerrainGeneratorAffectorType newType) :
TerrainGenerator::Affector (newTag, newType),
cachedFamilyId (-1),
cachedRgi (),
cachedDensity (0.f),
familyId (0),
operation (TGO_add),
removeAll (false),
densityOverride (false),
densityOverrideDensity (1.f)
{
}
//-------------------------------------------------------------------
AffectorFloraDynamic::~AffectorFloraDynamic ()
{
}
//-------------------------------------------------------------------
void AffectorFloraDynamic::setFamilyId (const int newFamilyId)
{
familyId = newFamilyId;
}
//-------------------------------------------------------------------
void AffectorFloraDynamic::setOperation (const TerrainGeneratorOperation newOperation)
{
operation = newOperation;
}
//-------------------------------------------------------------------
void AffectorFloraDynamic::setRemoveAll (const bool newRemoveAll)
{
removeAll = newRemoveAll;
}
//-------------------------------------------------------------------
void AffectorFloraDynamic::setDensityOverride (const bool newDensityOverride)
{
densityOverride = newDensityOverride;
}
//-------------------------------------------------------------------
void AffectorFloraDynamic::setDensityOverrideDensity (const float newDensityOverrideDensity)
{
densityOverrideDensity = newDensityOverrideDensity;
}
//-------------------------------------------------------------------
void AffectorFloraDynamic::prepare ()
{
cachedFamilyId = -1;
}
//-------------------------------------------------------------------
void AffectorFloraDynamic::affect (const float worldX, const float worldZ, const int x, const int z, const float amount, const TerrainGenerator::GeneratorChunkData& generatorChunkData) const
{
if (generatorChunkData.m_legacyRandomGenerator)
{
_legacyAffect(worldX, worldZ, x, z, amount, generatorChunkData);
return;
}
if (amount > 0.f)
{
Array2d<RadialGroup::Info>* const floraMap = getFloraMap (generatorChunkData);
if (removeAll)
{
//-- we want to remove all radial
floraMap->setData (x, z, generatorChunkData.radialGroup->getDefaultRadial ());
}
else
{
DEBUG_FATAL (familyId == 0, ("familyId == 0 for %s", getName ()));
if (cachedFamilyId != familyId)
{
cachedFamilyId = familyId;
cachedRgi = generatorChunkData.radialGroup->chooseRadial (familyId);
cachedDensity = generatorChunkData.radialGroup->getFamilyDensity (familyId);
}
//-- do we place flora here?
const float density = densityOverride ? densityOverrideDensity : cachedDensity;
FastRandomGenerator randomGenerator(CoordinateHash::hashTuple(worldX, worldZ));
if (randomGenerator.randomFloat() <= amount * density)
{
RadialGroup::Info rgi = cachedRgi;
if (rgi.getFamilyId() != 0)
{
switch (operation)
{
case TGO_add:
{
rgi.setChildChoice(randomGenerator.randomFloat());
floraMap->setData (x, z, rgi);
}
break;
case TGO_replace:
{
//-- replace is a remove of a specific type
if (floraMap->getData(x, z).getFamilyId() == familyId)
floraMap->setData (x, z, generatorChunkData.radialGroup->getDefaultRadial ());
}
break;
case TGO_subtract:
case TGO_multiply:
case TGO_COUNT:
default:
DEBUG_FATAL (true, ("invalid operation"));
}
}
}
}
}
}
void AffectorFloraDynamic::_legacyAffect (const float /*worldX*/, const float /*worldZ*/, const int x, const int z, const float amount, const TerrainGenerator::GeneratorChunkData& generatorChunkData) const
{
if (amount > 0.f)
{
Array2d<RadialGroup::Info>* const floraMap = getFloraMap (generatorChunkData);
if (removeAll)
{
//-- we want to remove all radial
floraMap->setData (x, z, generatorChunkData.radialGroup->getDefaultRadial ());
}
else
{
DEBUG_FATAL (familyId == 0, ("familyId == 0 for %s", getName ()));
if (cachedFamilyId != familyId)
{
cachedFamilyId = familyId;
cachedRgi = generatorChunkData.radialGroup->chooseRadial (familyId);
cachedDensity = generatorChunkData.radialGroup->getFamilyDensity (familyId);
}
//-- do we place flora here?
const float density = densityOverride ? densityOverrideDensity : cachedDensity;
if (generatorChunkData.m_legacyRandomGenerator->randomReal (0.f, 1.f) <= amount * density)
{
RadialGroup::Info rgi = cachedRgi;
if (rgi.getFamilyId() != 0)
{
switch (operation)
{
case TGO_add:
{
rgi.setChildChoice(generatorChunkData.m_legacyRandomGenerator->randomReal(0.f, 1.f));
floraMap->setData (x, z, rgi);
}
break;
case TGO_replace:
{
//-- replace is a remove of a specific type
if (floraMap->getData(x, z).getFamilyId() == familyId)
floraMap->setData (x, z, generatorChunkData.radialGroup->getDefaultRadial ());
}
break;
case TGO_subtract:
case TGO_multiply:
case TGO_COUNT:
default:
DEBUG_FATAL (true, ("invalid operation"));
}
}
}
}
}
}
//-------------------------------------------------------------------
void AffectorFloraDynamic::load (Iff& iff)
{
switch (iff.getCurrentName ())
{
case TAG_0000:
load_0000 (iff);
break;
case TAG_0001:
load_0001 (iff);
break;
case TAG_0002:
load_0002 (iff);
break;
default:
{
char tagBuffer [5];
ConvertTagToString (iff.getCurrentName (), tagBuffer);
char buffer [128];
iff.formatLocation (buffer, sizeof (buffer));
DEBUG_FATAL (true, ("invalid AffectorFloraDynamic version %s/%s", buffer, tagBuffer));
}
break;
}
}
//-------------------------------------------------------------------
void AffectorFloraDynamic::load_0000 (Iff& iff)
{
iff.enterForm (TAG_0000);
//-- load the base data
LayerItem::load (iff);
//-- load specific data
iff.enterChunk (TAG_DATA);
familyId = iff.read_int32 ();
iff.exitChunk (TAG_DATA);
iff.exitForm (TAG_0000);
}
//-------------------------------------------------------------------
void AffectorFloraDynamic::load_0001 (Iff& iff)
{
iff.enterForm (TAG_0001);
//-- load the base data
LayerItem::load (iff);
//-- load specific data
iff.enterChunk (TAG_DATA);
familyId = iff.read_int32 ();
int newOperation = iff.read_int32 ();
DEBUG_FATAL (newOperation < 0 || newOperation >= TGO_COUNT, ("operation out of bounds for %s", getName ()));
operation = static_cast<TerrainGeneratorOperation> (newOperation);
removeAll = iff.read_int32 () != 0;
iff.exitChunk (TAG_DATA);
iff.exitForm (TAG_0001);
}
//-------------------------------------------------------------------
void AffectorFloraDynamic::load_0002 (Iff& iff)
{
iff.enterForm (TAG_0002);
//-- load the base data
LayerItem::load (iff);
//-- load specific data
iff.enterChunk (TAG_DATA);
familyId = iff.read_int32 ();
int newOperation = iff.read_int32 ();
DEBUG_FATAL (newOperation < 0 || newOperation >= TGO_COUNT, ("operation out of bounds for %s", getName ()));
operation = static_cast<TerrainGeneratorOperation> (newOperation);
removeAll = iff.read_int32 () != 0;
densityOverride = iff.read_int32 () != 0;
densityOverrideDensity = iff.read_float ();
iff.exitChunk (TAG_DATA);
iff.exitForm (TAG_0002);
}
//-------------------------------------------------------------------
void AffectorFloraDynamic::save (Iff& iff) const
{
iff.insertForm (TAG_0002);
//-- save the base
LayerItem::save (iff);
//-- save specific data
iff.insertChunk (TAG_DATA);
iff.insertChunkData (familyId);
iff.insertChunkData (static_cast<int32> (operation));
iff.insertChunkData (removeAll ? static_cast<int32> (1) : static_cast<int32> (0));
iff.insertChunkData (densityOverride ? static_cast<int32> (1) : static_cast<int32> (0));
iff.insertChunkData (densityOverrideDensity);
iff.exitChunk (TAG_DATA);
iff.exitForm (TAG_0002);
}
//===================================================================
AffectorFloraDynamicNearConstant::AffectorFloraDynamicNearConstant () :
AffectorFloraDynamic (TAG_AFDN, TGAT_floraDynamicNearConstant)
{
}
//-------------------------------------------------------------------
AffectorFloraDynamicNearConstant::~AffectorFloraDynamicNearConstant ()
{
}
//-------------------------------------------------------------------
unsigned AffectorFloraDynamicNearConstant::getAffectedMaps() const
{
return TGM_floraDynamicNear;
}
//===================================================================
//
// AffectorFloraFloraDynamicFarConstant
//
AffectorFloraDynamicFarConstant::AffectorFloraDynamicFarConstant () :
AffectorFloraDynamic (TAG_AFDF, TGAT_floraDynamicFarConstant)
{
}
//-------------------------------------------------------------------
AffectorFloraDynamicFarConstant::~AffectorFloraDynamicFarConstant ()
{
}
//-------------------------------------------------------------------
unsigned AffectorFloraDynamicFarConstant::getAffectedMaps() const
{
return TGM_floraDynamicFar;
}
//===================================================================
@@ -0,0 +1,170 @@
//===================================================================
//
// AffectorFloraDynamic.h
// asommers 9-30-2000
//
// copyright 2000, verant interactive
//
//===================================================================
#ifndef INCLUDED_AffectorFloraDynamic_H
#define INCLUDED_AffectorFloraDynamic_H
//===================================================================
#include "sharedTerrain/TerrainGenerator.h"
//===================================================================
class AffectorFloraDynamic : public TerrainGenerator::Affector
{
private:
//-- not accessible
mutable int cachedFamilyId;
mutable RadialGroup::Info cachedRgi;
mutable float cachedDensity;
//-- accessible
int familyId;
TerrainGeneratorOperation operation;
bool removeAll;
bool densityOverride;
float densityOverrideDensity;
private:
void load_0000 (Iff& iff);
void load_0001 (Iff& iff);
void load_0002 (Iff& iff);
private:
AffectorFloraDynamic (const AffectorFloraDynamic& rhs);
AffectorFloraDynamic& operator= (const AffectorFloraDynamic& rhs);
protected:
virtual Array2d<RadialGroup::Info>* getFloraMap (const TerrainGenerator::GeneratorChunkData& generatorChunkData) const=0;
void _legacyAffect(float worldX, float worldZ, int x, int z, float amount, const TerrainGenerator::GeneratorChunkData& generatorChunkData) const;
public:
AffectorFloraDynamic (Tag newTag, TerrainGeneratorAffectorType newType);
virtual ~AffectorFloraDynamic ();
virtual void prepare ();
virtual void affect (float worldX, float worldZ, int x, int z, float amount, const TerrainGenerator::GeneratorChunkData& generatorChunkData) const;
virtual void load (Iff& iff);
virtual void save (Iff& iff) const;
int getFamilyId () const;
void setFamilyId (int newFamilyId);
TerrainGeneratorOperation getOperation () const;
void setOperation (TerrainGeneratorOperation newOperation);
bool getRemoveAll () const;
void setRemoveAll (bool newRemoveAll);
bool getDensityOverride () const;
void setDensityOverride (bool newDensityOverride);
float getDensityOverrideDensity () const;
void setDensityOverrideDensity (float newDensityOverrideDensity);
};
//-------------------------------------------------------------------
inline int AffectorFloraDynamic::getFamilyId () const
{
return familyId;
}
//-------------------------------------------------------------------
inline TerrainGeneratorOperation AffectorFloraDynamic::getOperation () const
{
return operation;
}
//-------------------------------------------------------------------
inline bool AffectorFloraDynamic::getRemoveAll () const
{
return removeAll;
}
//-------------------------------------------------------------------
inline bool AffectorFloraDynamic::getDensityOverride () const
{
return densityOverride;
}
//-------------------------------------------------------------------
inline float AffectorFloraDynamic::getDensityOverrideDensity () const
{
return densityOverrideDensity;
}
//===================================================================
class AffectorFloraDynamicNearConstant : public AffectorFloraDynamic
{
private:
AffectorFloraDynamicNearConstant (const AffectorFloraDynamicNearConstant& rhs);
AffectorFloraDynamicNearConstant& operator= (const AffectorFloraDynamicNearConstant& rhs);
private:
virtual Array2d<RadialGroup::Info>* getFloraMap (const TerrainGenerator::GeneratorChunkData& generatorChunkData) const;
public:
AffectorFloraDynamicNearConstant ();
virtual ~AffectorFloraDynamicNearConstant ();
virtual unsigned getAffectedMaps() const;
};
//-------------------------------------------------------------------
inline Array2d<RadialGroup::Info>* AffectorFloraDynamicNearConstant::getFloraMap (const TerrainGenerator::GeneratorChunkData& generatorChunkData) const
{
return generatorChunkData.floraDynamicNearMap;
}
//===================================================================
class AffectorFloraDynamicFarConstant : public AffectorFloraDynamic
{
private:
AffectorFloraDynamicFarConstant (const AffectorFloraDynamicFarConstant& rhs);
AffectorFloraDynamicFarConstant& operator= (const AffectorFloraDynamicFarConstant& rhs);
private:
virtual Array2d<RadialGroup::Info>* getFloraMap (const TerrainGenerator::GeneratorChunkData& generatorChunkData) const;
public:
AffectorFloraDynamicFarConstant ();
virtual ~AffectorFloraDynamicFarConstant ();
virtual unsigned getAffectedMaps() const;
};
//-------------------------------------------------------------------
inline Array2d<RadialGroup::Info>* AffectorFloraDynamicFarConstant::getFloraMap (const TerrainGenerator::GeneratorChunkData& generatorChunkData) const
{
return generatorChunkData.floraDynamicFarMap;
}
//===================================================================
#endif
@@ -0,0 +1,431 @@
//===================================================================
//
// AffectorFloraStatic.cpp
// asommers 9-30-2000
//
// copyright 2000, verant interactive
//
//===================================================================
#include "sharedTerrain/FirstSharedTerrain.h"
#include "sharedTerrain/AffectorFloraStatic.h"
#include "sharedTerrain/Affector.h"
#include "sharedTerrain/CoordinateHash.h"
#include "sharedRandom/FastRandomGenerator.h"
#include "sharedFile/Iff.h"
//===================================================================
//
// AffectorFloraStatic
//
AffectorFloraStatic::AffectorFloraStatic (const Tag newTag, const TerrainGeneratorAffectorType newType) :
TerrainGenerator::Affector (newTag, newType),
cachedFamilyId (-1),
cachedFgi (),
cachedDensity (0.f),
familyId (0),
operation (TGO_add),
removeAll (false),
densityOverride (false),
densityOverrideDensity (1.f)
{
}
//-------------------------------------------------------------------
AffectorFloraStatic::~AffectorFloraStatic ()
{
}
//-------------------------------------------------------------------
void AffectorFloraStatic::setFamilyId (const int newFamilyId)
{
familyId = newFamilyId;
}
//-------------------------------------------------------------------
void AffectorFloraStatic::setOperation (const TerrainGeneratorOperation newOperation)
{
operation = newOperation;
}
//-------------------------------------------------------------------
void AffectorFloraStatic::setRemoveAll (const bool newRemoveAll)
{
removeAll = newRemoveAll;
}
//-------------------------------------------------------------------
void AffectorFloraStatic::setDensityOverride (const bool newDensityOverride)
{
densityOverride = newDensityOverride;
}
//-------------------------------------------------------------------
void AffectorFloraStatic::setDensityOverrideDensity (const float newDensityOverrideDensity)
{
densityOverrideDensity = newDensityOverrideDensity;
}
//-------------------------------------------------------------------
void AffectorFloraStatic::prepare ()
{
cachedFamilyId = -1;
}
//-------------------------------------------------------------------
unsigned AffectorFloraStaticCollidableConstant::getAffectedMaps() const
{
return TGM_floraStaticCollidable;
}
//-------------------------------------------------------------------
unsigned AffectorFloraStaticNonCollidableConstant::getAffectedMaps() const
{
return TGM_floraStaticNonCollidable;
}
//-------------------------------------------------------------------
void AffectorFloraStatic::affect (const float worldX, const float worldZ, const int x, const int z, const float amount, const TerrainGenerator::GeneratorChunkData& generatorChunkData) const
{
if (generatorChunkData.m_legacyRandomGenerator)
{
_legacyAffect(worldX, worldZ, x, z, amount, generatorChunkData);
return;
}
if (amount > 0.f)
{
Array2d<FloraGroup::Info>* const floraMap = getFloraMap (generatorChunkData);
if (removeAll)
{
//-- we want to remove all flora
floraMap->setData (x, z, generatorChunkData.floraGroup->getDefaultFlora ());
}
else
{
DEBUG_FATAL (familyId == 0, ("familyId == 0 for %s", getName ()));
if (cachedFamilyId != familyId)
{
cachedFamilyId = familyId;
cachedFgi = generatorChunkData.floraGroup->chooseFlora (familyId);
cachedDensity = generatorChunkData.floraGroup->getFamilyDensity (familyId);
}
//-- do we place flora here?
const float density = densityOverride ? densityOverrideDensity : cachedDensity;
FastRandomGenerator randomGenerator(CoordinateHash::hashTuple(worldX, worldZ));
float rf = randomGenerator.randomFloat();
if (rf <= amount * density)
{
FloraGroup::Info fgi = cachedFgi;
if (fgi.getFamilyId () != 0)
{
switch (operation)
{
case TGO_add:
{
rf = randomGenerator.randomFloat();
fgi.setChildChoice(rf);
floraMap->setData (x, z, fgi);
}
break;
case TGO_replace:
{
//-- replace is a remove of a specific type
if (floraMap->getData (x, z).getFamilyId () == familyId)
floraMap->setData (x, z, generatorChunkData.floraGroup->getDefaultFlora ());
}
break;
case TGO_subtract:
case TGO_multiply:
case TGO_COUNT:
default:
DEBUG_FATAL (true, ("invalid operation"));
}
}
}
}
}
}
void AffectorFloraStatic::_legacyAffect(float /*worldX*/, float /*worldZ*/, int x, int z, float amount, const TerrainGenerator::GeneratorChunkData& generatorChunkData) const
{
if (amount > 0.f)
{
Array2d<FloraGroup::Info>* const floraMap = getFloraMap (generatorChunkData);
if (removeAll)
{
//-- we want to remove all flora
floraMap->setData (x, z, generatorChunkData.floraGroup->getDefaultFlora ());
}
else
{
DEBUG_FATAL (familyId == 0, ("familyId == 0 for %s", getName ()));
if (cachedFamilyId != familyId)
{
cachedFamilyId = familyId;
cachedFgi = generatorChunkData.floraGroup->chooseFlora (familyId);
cachedDensity = generatorChunkData.floraGroup->getFamilyDensity (familyId);
}
//-- do we place flora here?
const float density = densityOverride ? densityOverrideDensity : cachedDensity;
if (generatorChunkData.m_legacyRandomGenerator->randomReal (0.f, 1.f) <= amount * density)
{
FloraGroup::Info fgi = cachedFgi;
if (fgi.getFamilyId () != 0)
{
switch (operation)
{
case TGO_add:
{
fgi.setChildChoice (generatorChunkData.m_legacyRandomGenerator->randomReal (0.0f, 1.0f));
floraMap->setData (x, z, fgi);
}
break;
case TGO_replace:
{
//-- replace is a remove of a specific type
if (floraMap->getData (x, z).getFamilyId () == familyId)
floraMap->setData (x, z, generatorChunkData.floraGroup->getDefaultFlora ());
}
break;
case TGO_subtract:
case TGO_multiply:
case TGO_COUNT:
default:
DEBUG_FATAL (true, ("invalid operation"));
}
}
}
}
}
}
//-------------------------------------------------------------------
void AffectorFloraStatic::load (Iff& iff)
{
switch (iff.getCurrentName ())
{
case TAG_0000:
load_0000 (iff);
break;
case TAG_0001:
load_0001 (iff);
break;
case TAG_0002:
load_0002 (iff);
break;
case TAG_0003:
load_0003 (iff);
break;
case TAG_0004:
load_0004 (iff);
break;
default:
{
char tagBuffer [5];
ConvertTagToString (iff.getCurrentName (), tagBuffer);
char buffer [128];
iff.formatLocation (buffer, sizeof (buffer));
DEBUG_FATAL (true, ("invalid AffectorFloraStatic version %s/%s", buffer, tagBuffer));
}
break;
}
}
//-------------------------------------------------------------------
void AffectorFloraStatic::load_0000 (Iff& iff)
{
iff.enterForm (TAG_0000);
//-- load the base data
LayerItem::load (iff);
//-- load specific data
iff.enterChunk (TAG_DATA);
operation = TGO_replace;
iff.exitChunk (TAG_DATA);
iff.exitForm (TAG_0000);
}
//-------------------------------------------------------------------
void AffectorFloraStatic::load_0001 (Iff& iff)
{
iff.enterForm (TAG_0001);
//-- load the base data
LayerItem::load (iff);
//-- load specific data
iff.enterChunk (TAG_DATA);
familyId = iff.read_int32 ();
operation = TGO_replace;
iff.exitChunk (TAG_DATA);
iff.exitForm (TAG_0001);
}
//-------------------------------------------------------------------
void AffectorFloraStatic::load_0002 (Iff& iff)
{
iff.enterForm (TAG_0002);
//-- load the base data
LayerItem::load (iff);
//-- load specific data
iff.enterChunk (TAG_DATA);
familyId = iff.read_int32 ();
int newOperation = iff.read_int32 ();
DEBUG_FATAL (newOperation < 0 || newOperation >= static_cast<int> (TGO_COUNT), ("operation out of bounds for %s", getName ()));
operation = static_cast<TerrainGeneratorOperation> (newOperation);
iff.exitChunk (TAG_DATA);
iff.exitForm (TAG_0002);
}
//-------------------------------------------------------------------
void AffectorFloraStatic::load_0003 (Iff& iff)
{
iff.enterForm (TAG_0003);
//-- load the base data
LayerItem::load (iff);
//-- load specific data
iff.enterChunk (TAG_DATA);
familyId = iff.read_int32 ();
int newOperation = iff.read_int32 ();
DEBUG_FATAL (newOperation < 0 || newOperation >= static_cast<int> (TGO_COUNT), ("operation out of bounds for %s", getName ()));
operation = static_cast<TerrainGeneratorOperation> (newOperation);
removeAll = iff.read_int32 () != 0;
iff.exitChunk (TAG_DATA);
iff.exitForm (TAG_0003);
}
//-------------------------------------------------------------------
void AffectorFloraStatic::load_0004 (Iff& iff)
{
iff.enterForm (TAG_0004);
//-- load the base data
LayerItem::load (iff);
//-- load specific data
iff.enterChunk (TAG_DATA);
familyId = iff.read_int32 ();
int newOperation = iff.read_int32 ();
DEBUG_FATAL (newOperation < 0 || newOperation >= static_cast<int> (TGO_COUNT), ("operation out of bounds for %s", getName ()));
operation = static_cast<TerrainGeneratorOperation> (newOperation);
removeAll = iff.read_int32 () != 0;
densityOverride = iff.read_int32 () != 0;
densityOverrideDensity = iff.read_float ();
iff.exitChunk (TAG_DATA);
iff.exitForm (TAG_0004);
}
//-------------------------------------------------------------------
void AffectorFloraStatic::save (Iff& iff) const
{
iff.insertForm (TAG_0004);
//-- save the base
LayerItem::save (iff);
//-- save specific data
iff.insertChunk (TAG_DATA);
iff.insertChunkData (familyId);
iff.insertChunkData (static_cast<int32> (operation));
iff.insertChunkData (removeAll ? static_cast<int32> (1) : static_cast<int32> (0));
iff.insertChunkData (densityOverride ? static_cast<int32> (1) : static_cast<int32> (0));
iff.insertChunkData (densityOverrideDensity);
iff.exitChunk (TAG_DATA);
iff.exitForm (TAG_0004);
}
//===================================================================
//
// AffectorFloraStaticCollidableConstant
//
AffectorFloraStaticCollidableConstant::AffectorFloraStaticCollidableConstant () :
AffectorFloraStatic (TAG_AFSC, TGAT_floraStaticCollidableConstant)
{
}
//-------------------------------------------------------------------
AffectorFloraStaticCollidableConstant::~AffectorFloraStaticCollidableConstant ()
{
}
//===================================================================
//
// AffectorFloraStaticNonCollidableConstant
//
AffectorFloraStaticNonCollidableConstant::AffectorFloraStaticNonCollidableConstant () :
AffectorFloraStatic (TAG_AFSN, TGAT_floraStaticNonCollidableConstant)
{
}
//-------------------------------------------------------------------
AffectorFloraStaticNonCollidableConstant::~AffectorFloraStaticNonCollidableConstant ()
{
}
//===================================================================
@@ -0,0 +1,171 @@
//===================================================================
//
// AffectorFloraStatic.h
// asommers 9-30-2000
//
// copyright 2000, verant interactive
//
//===================================================================
#ifndef INCLUDED_AffectorFloraStatic_H
#define INCLUDED_AffectorFloraStatic_H
//===================================================================
#include "sharedTerrain/TerrainGenerator.h"
//===================================================================
class AffectorFloraStatic : public TerrainGenerator::Affector
{
protected:
//-- not accessible
mutable int cachedFamilyId;
mutable FloraGroup::Info cachedFgi;
mutable float cachedDensity;
//-- accessible
int familyId;
TerrainGeneratorOperation operation;
bool removeAll;
bool densityOverride;
float densityOverrideDensity;
private:
void load_0000 (Iff& iff);
void load_0001 (Iff& iff);
void load_0002 (Iff& iff);
void load_0003 (Iff& iff);
void load_0004 (Iff& iff);
private:
AffectorFloraStatic (const AffectorFloraStatic& rhs);
AffectorFloraStatic& operator= (const AffectorFloraStatic& rhs);
protected:
virtual Array2d<FloraGroup::Info>* getFloraMap (const TerrainGenerator::GeneratorChunkData& generatorChunkData) const=0;
void _legacyAffect(float worldX, float worldZ, int x, int z, float amount, const TerrainGenerator::GeneratorChunkData& generatorChunkData) const;
public:
AffectorFloraStatic (Tag newTag, TerrainGeneratorAffectorType newType);
virtual ~AffectorFloraStatic ();
virtual void prepare ();
virtual void affect (float worldX, float worldZ, int x, int z, float amount, const TerrainGenerator::GeneratorChunkData& generatorChunkData) const;
virtual void load (Iff& iff);
virtual void save (Iff& iff) const;
int getFamilyId () const;
void setFamilyId (int newFamilyId);
TerrainGeneratorOperation getOperation () const;
void setOperation (TerrainGeneratorOperation newOperation);
bool getRemoveAll () const;
void setRemoveAll (bool newRemoveAll);
bool getDensityOverride () const;
void setDensityOverride (bool newDensityOverride);
float getDensityOverrideDensity () const;
void setDensityOverrideDensity (float newDensityOverrideDensity);
};
//-------------------------------------------------------------------
inline int AffectorFloraStatic::getFamilyId () const
{
return familyId;
}
//-------------------------------------------------------------------
inline TerrainGeneratorOperation AffectorFloraStatic::getOperation () const
{
return operation;
}
//-------------------------------------------------------------------
inline bool AffectorFloraStatic::getRemoveAll () const
{
return removeAll;
}
//-------------------------------------------------------------------
inline bool AffectorFloraStatic::getDensityOverride () const
{
return densityOverride;
}
//-------------------------------------------------------------------
inline float AffectorFloraStatic::getDensityOverrideDensity () const
{
return densityOverrideDensity;
}
//-------------------------------------------------------------------
class AffectorFloraStaticCollidableConstant : public AffectorFloraStatic
{
private:
AffectorFloraStaticCollidableConstant (const AffectorFloraStaticCollidableConstant& rhs);
AffectorFloraStaticCollidableConstant& operator= (const AffectorFloraStaticCollidableConstant& rhs);
private:
virtual Array2d<FloraGroup::Info>* getFloraMap (const TerrainGenerator::GeneratorChunkData& generatorChunkData) const;
public:
AffectorFloraStaticCollidableConstant ();
virtual ~AffectorFloraStaticCollidableConstant ();
virtual unsigned getAffectedMaps() const;
};
//-------------------------------------------------------------------
inline Array2d<FloraGroup::Info>* AffectorFloraStaticCollidableConstant::getFloraMap (const TerrainGenerator::GeneratorChunkData& generatorChunkData) const
{
return generatorChunkData.floraStaticCollidableMap;
}
//-------------------------------------------------------------------
class AffectorFloraStaticNonCollidableConstant : public AffectorFloraStatic
{
private:
AffectorFloraStaticNonCollidableConstant (const AffectorFloraStaticNonCollidableConstant& rhs);
AffectorFloraStaticNonCollidableConstant& operator= (const AffectorFloraStaticNonCollidableConstant& rhs);
private:
virtual Array2d<FloraGroup::Info>* getFloraMap (const TerrainGenerator::GeneratorChunkData& generatorChunkData) const;
public:
AffectorFloraStaticNonCollidableConstant ();
virtual ~AffectorFloraStaticNonCollidableConstant ();
virtual unsigned getAffectedMaps() const;
};
//-------------------------------------------------------------------
inline Array2d<FloraGroup::Info>* AffectorFloraStaticNonCollidableConstant::getFloraMap (const TerrainGenerator::GeneratorChunkData& generatorChunkData) const
{
return generatorChunkData.floraStaticNonCollidableMap;
}
//===================================================================
#endif
@@ -0,0 +1,731 @@
//
// AffectorHeight.cpp
// asommers 9-30-2000
//
// copyright 2000, verant interactive
//
//-------------------------------------------------------------------
#include "sharedTerrain/FirstSharedTerrain.h"
#include "sharedTerrain/AffectorHeight.h"
#include "sharedFile/Iff.h"
#include "sharedFractal/MultiFractal.h"
#include "sharedFractal/MultiFractalReaderWriter.h"
#include "sharedTerrain/Affector.h"
//-------------------------------------------------------------------
//
// AffectorHeightConstant
//
AffectorHeightConstant::AffectorHeightConstant () :
TerrainGenerator::Affector (TAG_AHCN, TGAT_heightConstant),
operation (TGO_replace),
height (0)
{
}
//-------------------------------------------------------------------
AffectorHeightConstant::~AffectorHeightConstant ()
{
}
//-------------------------------------------------------------------
void AffectorHeightConstant::setOperation (const TerrainGeneratorOperation newOperation)
{
operation = newOperation;
}
//-------------------------------------------------------------------
void AffectorHeightConstant::setHeight (const float newHeight)
{
height = newHeight;
}
//-------------------------------------------------------------------
unsigned AffectorHeightConstant::getAffectedMaps() const
{
return TGM_height;
}
//-------------------------------------------------------------------
void AffectorHeightConstant::affect (const float /*worldX*/, const float /*worldZ*/, const int x, const int z, const float amount, const TerrainGenerator::GeneratorChunkData& generatorChunkData) const
{
if (amount > 0.f)
{
float newHeight = 0.f;
switch (operation)
{
case TGO_add:
newHeight = generatorChunkData.heightMap->getData (x, z) + amount*height;
break;
case TGO_subtract:
newHeight = generatorChunkData.heightMap->getData (x, z) - amount*height;
break;
case TGO_multiply:
{
const float oldHeight = generatorChunkData.heightMap->getData (x, z);
const float desiredHeight = generatorChunkData.heightMap->getData (x, z) * height;
newHeight = linearInterpolate (oldHeight, desiredHeight, amount);
}
break;
case TGO_replace:
default:
newHeight = amount * height + (1.f - amount) * generatorChunkData.heightMap->getData (x, z);
break;
case TGO_COUNT:
FATAL (true, ("invalid operation"));
break;
}
generatorChunkData.heightMap->setData (x, z, newHeight);
}
}
//-------------------------------------------------------------------
bool AffectorHeightConstant::affectsHeight () const
{
return true;
}
//-------------------------------------------------------------------
void AffectorHeightConstant::load (Iff& iff)
{
switch (iff.getCurrentName ())
{
case TAG_0000:
load_0000 (iff);
break;
default:
{
char tagBuffer [5];
ConvertTagToString (iff.getCurrentName (), tagBuffer);
char buffer [128];
iff.formatLocation (buffer, sizeof (buffer));
DEBUG_FATAL (true, ("invalid AffectorHeightConstant version %s/%s", buffer, tagBuffer));
}
break;
}
}
//-------------------------------------------------------------------
void AffectorHeightConstant::load_0000 (Iff& iff)
{
iff.enterForm (TAG_0000);
//-- load the base data
LayerItem::load (iff);
//-- load specific data
iff.enterChunk (TAG_DATA);
int newOperation = iff.read_int32 ();
DEBUG_FATAL (newOperation < 0 || newOperation >= TGO_COUNT, ("operation out of bounds for %s", getName ()));
operation = static_cast<TerrainGeneratorOperation> (newOperation);
height = iff.read_float ();
iff.exitChunk (TAG_DATA);
iff.exitForm (TAG_0000);
}
//-------------------------------------------------------------------
void AffectorHeightConstant::save (Iff& iff) const
{
iff.insertForm (TAG_0000);
//-- save the base
LayerItem::save (iff);
//-- save specific data
iff.insertChunk (TAG_DATA);
iff.insertChunkData (static_cast<int32> (operation));
iff.insertChunkData (height);
iff.exitChunk (TAG_DATA);
iff.exitForm (TAG_0000);
}
//-------------------------------------------------------------------
//
// AffectorHeightFractal
//
AffectorHeightFractal::AffectorHeightFractal () :
TerrainGenerator::Affector (TAG_AHFR, TGAT_heightFractal),
m_multiFractal (0),
m_cachedFamilyId (-1),
m_familyId (0),
m_scaleY (1),
m_operation (TGO_replace)
{
}
AffectorHeightFractal::~AffectorHeightFractal ()
{
m_multiFractal = 0;
}
//-------------------------------------------------------------------
void AffectorHeightFractal::setOperation (const TerrainGeneratorOperation newOperation)
{
m_operation = newOperation;
}
//-------------------------------------------------------------------
void AffectorHeightFractal::setFamilyId (const int newFamilyId)
{
m_familyId = newFamilyId;
}
//-------------------------------------------------------------------
void AffectorHeightFractal::setScaleY (const float newScale)
{
m_scaleY = newScale;
}
//-------------------------------------------------------------------
unsigned AffectorHeightFractal::getAffectedMaps() const
{
return TGM_height;
}
//-------------------------------------------------------------------
void AffectorHeightFractal::affect (const float worldX, const float worldZ, const int x, const int z, const float amount, const TerrainGenerator::GeneratorChunkData& generatorChunkData) const
{
if (amount > 0.f)
{
if (m_cachedFamilyId != m_familyId)
{
m_cachedFamilyId = m_familyId;
m_multiFractal = generatorChunkData.fractalGroup->getFamilyMultiFractal (m_familyId);
}
NOT_NULL (m_multiFractal);
const float fractalHeight = m_scaleY * m_multiFractal->getValueCache (worldX, worldZ, x, z);
const float oldHeight = generatorChunkData.heightMap->getData (x, z);
float newHeight = oldHeight;
switch (m_operation)
{
case TGO_add:
newHeight += amount * fractalHeight;
break;
case TGO_subtract:
newHeight -= amount * fractalHeight;
break;
case TGO_multiply:
{
const float desiredHeight = oldHeight * fractalHeight;
newHeight = linearInterpolate (oldHeight, desiredHeight, amount);
}
break;
case TGO_replace:
default:
newHeight = linearInterpolate (oldHeight, fractalHeight, amount);
break;
case TGO_COUNT:
FATAL (true, ("invalid operation"));
break;
}
generatorChunkData.heightMap->setData (x, z, newHeight);
}
}
//-------------------------------------------------------------------
bool AffectorHeightFractal::affectsHeight () const
{
return true;
}
//-------------------------------------------------------------------
void AffectorHeightFractal::load (Iff& iff, FractalGroup& fractalGroup)
{
switch (iff.getCurrentName ())
{
case TAG_0000:
load_0000 (iff, fractalGroup);
break;
case TAG_0001:
load_0001 (iff, fractalGroup);
break;
case TAG_0002:
load_0002 (iff, fractalGroup);
break;
case TAG_0003:
load_0003 (iff);
break;
default:
{
char tagBuffer [5];
ConvertTagToString (iff.getCurrentName (), tagBuffer);
char buffer [128];
iff.formatLocation (buffer, sizeof (buffer));
DEBUG_FATAL (true, ("invalid AffectorHeightFractal version %s/%s", buffer, tagBuffer));
}
break;
}
}
//-------------------------------------------------------------------
void AffectorHeightFractal::load_0000 (Iff& iff, FractalGroup& fractalGroup)
{
iff.enterForm (TAG_0000);
//-- load the base data
LayerItem::load (iff);
//-- load specific data
iff.enterChunk (TAG_DATA);
MultiFractal multiFractal;
int newOperation = iff.read_int32 ();
DEBUG_FATAL (newOperation < 0 || newOperation >= TGO_COUNT, ("operation out of bounds for %s (%i)", getName (), newOperation));
setOperation (static_cast<TerrainGeneratorOperation> (newOperation));
const int fractalType = iff.read_int32 ();
DEBUG_FATAL (fractalType < 0 || fractalType >= MultiFractal::CR_COUNT, ("fractal type out of range (%i >= %i", fractalType, MultiFractal::CR_COUNT));
multiFractal.setCombinationRule (static_cast<MultiFractal::CombinationRule> (fractalType));
const uint32 seed = iff.read_uint32 ();
multiFractal.setSeed (seed);
const Vector scale = iff.read_floatVector ();
multiFractal.setScale (scale.x, scale.z);
setScaleY (scale.y);
setFamilyId (fractalGroup.createFamily (&multiFractal, getName ()));
iff.exitChunk (TAG_DATA);
iff.exitForm (TAG_0000);
}
//-------------------------------------------------------------------
void AffectorHeightFractal::load_0001 (Iff& iff, FractalGroup& fractalGroup)
{
iff.enterForm (TAG_0001);
//-- load the base data
LayerItem::load (iff);
//-- load specific data
iff.enterChunk (TAG_DATA);
MultiFractal multiFractal;
int newOperation = iff.read_int32 ();
DEBUG_FATAL (newOperation < 0 || newOperation >= TGO_COUNT, ("operation out of bounds for %s (%i)", getName (), newOperation));
setOperation (static_cast<TerrainGeneratorOperation> (newOperation));
const int fractalType = iff.read_int32 ();
DEBUG_FATAL (fractalType < 0 || fractalType >= MultiFractal::CR_COUNT, ("fractal type out of range (%i >= %i", fractalType, MultiFractal::CR_COUNT));
multiFractal.setCombinationRule (static_cast<MultiFractal::CombinationRule> (fractalType));
multiFractal.setNumberOfOctaves (iff.read_int32 ());
multiFractal.setFrequency (iff.read_float ());
Vector scale;
const int n = iff.read_int32 ();
int i;
for (i = 0; i < n; i++)
{
const int unused = iff.read_int32 ();
UNREF (unused);
scale.x = iff.read_float ();
scale.z = iff.read_float ();
}
const uint32 seed = iff.read_uint32 ();
multiFractal.setSeed (seed);
for (i = 0; i < multiFractal.getNumberOfOctaves (); i++)
{
const int dummy1 = iff.read_int32 ();
UNREF (dummy1);
const int dummy2 = iff.read_int32 ();
UNREF (dummy2);
}
setScaleY (iff.read_float ());
multiFractal.setScale (scale.x, scale.z);
setFamilyId (fractalGroup.createFamily (&multiFractal, getName ()));
iff.exitChunk (TAG_DATA);
iff.exitForm (TAG_0001);
}
//-------------------------------------------------------------------
void AffectorHeightFractal::load_0002 (Iff& iff, FractalGroup& fractalGroup)
{
iff.enterForm (TAG_0002);
//-- load the base data
LayerItem::load (iff);
//-- load specific data
iff.enterForm (TAG_DATA);
//-- load the fractal settings
MultiFractal multiFractal;
MultiFractalReaderWriter::load (iff, multiFractal);
setFamilyId (fractalGroup.createFamily (&multiFractal, getName ()));
//-- load parameters
iff.enterChunk (TAG_PARM);
int newOperation = iff.read_int32 ();
DEBUG_FATAL (newOperation < 0 || newOperation >= TGO_COUNT, ("operation out of bounds for %s (%i)", getName (), newOperation));
setOperation (static_cast<TerrainGeneratorOperation> (newOperation));
setScaleY (iff.read_float ());
iff.exitChunk ();
iff.exitForm (TAG_DATA);
iff.exitForm (TAG_0002);
}
//-------------------------------------------------------------------
void AffectorHeightFractal::load_0003 (Iff& iff)
{
iff.enterForm (TAG_0003);
//-- load the base data
LayerItem::load (iff);
//-- load specific data
iff.enterForm (TAG_DATA);
//-- load parameters
iff.enterChunk (TAG_PARM);
setFamilyId (iff.read_int32 ());
int newOperation = iff.read_int32 ();
DEBUG_FATAL (newOperation < 0 || newOperation >= TGO_COUNT, ("operation out of bounds for %s (%i)", getName (), newOperation));
setOperation (static_cast<TerrainGeneratorOperation> (newOperation));
setScaleY (iff.read_float ());
iff.exitChunk ();
iff.exitForm (TAG_DATA);
iff.exitForm (TAG_0003);
}
//-------------------------------------------------------------------
void AffectorHeightFractal::save (Iff& iff) const
{
iff.insertForm (TAG_0003);
//-- save the base
LayerItem::save (iff);
//-- save specific data
iff.insertForm (TAG_DATA);
iff.insertChunk (TAG (P,A,R,M));
iff.insertChunkData (getFamilyId ());
iff.insertChunkData (static_cast<int32> (getOperation ()));
iff.insertChunkData (getScaleY ());
iff.exitChunk ();
iff.exitForm ();
iff.exitForm ();
}
//-------------------------------------------------------------------
//
// AffectorHeightTerrace
//
AffectorHeightTerrace::AffectorHeightTerrace () :
TerrainGenerator::Affector (TAG_AHTR, TGAT_heightTerrace),
height (20.0f),
fraction (0.25f)
{
}
//-------------------------------------------------------------------
AffectorHeightTerrace::~AffectorHeightTerrace ()
{
}
//-------------------------------------------------------------------
unsigned AffectorHeightTerrace::getAffectedMaps() const
{
return TGM_height;
}
//-------------------------------------------------------------------
void AffectorHeightTerrace::affect (const float /*worldX*/, const float /*worldZ*/, const int x, const int z, const float amount, const TerrainGenerator::GeneratorChunkData& generatorChunkData) const
{
if (amount > 0.f && height > 0.f)
{
const float terraceHeight = height;
if (terraceHeight > 0.f)
{
const float originalHeight = generatorChunkData.heightMap->getData (x, z);
const float lowHeight = originalHeight - ((originalHeight < 0) ? (terraceHeight + fmodf (originalHeight, terraceHeight)) : fmodf (originalHeight, terraceHeight));
const float midHeight = lowHeight + terraceHeight * fraction;
const float highHeight = lowHeight + terraceHeight;
float newHeight = lowHeight;
if (originalHeight > midHeight)
{
const float t = (originalHeight - midHeight) / (highHeight - midHeight);
newHeight = linearInterpolate (lowHeight, highHeight, t);
}
generatorChunkData.heightMap->setData (x, z, linearInterpolate (originalHeight, newHeight, amount));
}
}
}
//-------------------------------------------------------------------
bool AffectorHeightTerrace::affectsHeight () const
{
return true;
}
//-------------------------------------------------------------------
void AffectorHeightTerrace::load (Iff& iff)
{
switch (iff.getCurrentName ())
{
case TAG_0000:
load_0000 (iff);
break;
case TAG_0001:
load_0001 (iff);
break;
case TAG_0002:
load_0002 (iff);
break;
case TAG_0003:
load_0003 (iff);
break;
case TAG_0004:
load_0004 (iff);
break;
default:
{
char tagBuffer [5];
ConvertTagToString (iff.getCurrentName (), tagBuffer);
char buffer [128];
iff.formatLocation (buffer, sizeof (buffer));
DEBUG_FATAL (true, ("invalid AffectorHeightTerrace version %s/%s", buffer, tagBuffer));
}
break;
}
}
//-------------------------------------------------------------------
void AffectorHeightTerrace::load_0000 (Iff& iff)
{
iff.enterForm (TAG_0000);
//-- load the base data
LayerItem::load (iff);
//-- load specific data
iff.enterChunk (TAG_DATA);
fraction = iff.read_float ();
height = iff.read_float ();
iff.exitChunk (TAG_DATA);
iff.exitForm (TAG_0000);
}
//-------------------------------------------------------------------
void AffectorHeightTerrace::load_0001 (Iff& iff)
{
iff.enterForm (TAG_0001);
//-- load the base data
LayerItem::load (iff);
//-- load specific data
iff.enterChunk (TAG_DATA);
fraction = iff.read_float ();
height = iff.read_float ();
iff.exitChunk (TAG_DATA, true);
iff.exitForm (TAG_0001);
}
//-------------------------------------------------------------------
void AffectorHeightTerrace::load_0002 (Iff& iff)
{
iff.enterForm (TAG_0002);
//-- load the base data
LayerItem::load (iff);
//-- load specific data
iff.enterChunk (TAG_DATA);
fraction = iff.read_float ();
height = iff.read_float ();
iff.exitChunk (TAG_DATA, true);
iff.exitForm (TAG_0002);
}
//-------------------------------------------------------------------
void AffectorHeightTerrace::load_0003 (Iff& iff)
{
iff.enterForm (TAG_0003);
//-- load the base data
LayerItem::load (iff);
//-- load specific data
iff.enterForm (TAG_DATA);
//-- load the fractal settings
{
MultiFractal multiFractal;
MultiFractalReaderWriter::load (iff, multiFractal);
}
//-- load parameters
iff.enterChunk (TAG_PARM);
fraction = iff.read_float ();
height = iff.read_float ();
const int unused = iff.read_int32 ();
UNREF (unused);
iff.exitChunk ();
iff.exitForm (TAG_DATA);
iff.exitForm (TAG_0003);
}
//-------------------------------------------------------------------
void AffectorHeightTerrace::load_0004 (Iff& iff)
{
iff.enterForm (TAG_0004);
//-- load the base data
LayerItem::load (iff);
//-- load specific data
iff.enterChunk (TAG_DATA);
fraction = iff.read_float ();
height = iff.read_float ();
iff.exitChunk (TAG_DATA);
iff.exitForm (TAG_0004);
}
//-------------------------------------------------------------------
void AffectorHeightTerrace::save (Iff& iff) const
{
iff.insertForm (TAG_0004);
//-- save the base
LayerItem::save (iff);
//-- save specific data
iff.insertChunk (TAG_DATA);
iff.insertChunkData (fraction);
iff.insertChunkData (height);
iff.exitChunk ();
iff.exitForm (TAG_0004);
}
//-------------------------------------------------------------------
void AffectorHeightTerrace::setHeight (const float newHeight)
{
height = newHeight;
}
//-------------------------------------------------------------------
void AffectorHeightTerrace::setFraction (const float newFraction)
{
fraction = newFraction;
}
//-------------------------------------------------------------------
@@ -0,0 +1,193 @@
//===================================================================
//
// AffectorHeight.h
// asommers 9-30-2000
//
// copyright 2000, verant interactive
//
//===================================================================
#ifndef INCLUDED_AffectorHeight_H
#define INCLUDED_AffectorHeight_H
//===================================================================
#include "sharedTerrain/TerrainGenerator.h"
//===================================================================
class AffectorHeightConstant : public TerrainGenerator::Affector
{
private:
//-- accessible
TerrainGeneratorOperation operation;
float height;
private:
void load_0000 (Iff& iff);
private:
AffectorHeightConstant (const AffectorHeightConstant& rhs);
AffectorHeightConstant& operator= (const AffectorHeightConstant& rhs);
public:
AffectorHeightConstant ();
virtual ~AffectorHeightConstant ();
virtual void affect (float worldX, float worldZ, int x, int z, float amount, const TerrainGenerator::GeneratorChunkData& generatorChunkData) const;
virtual bool affectsHeight () const;
virtual void load (Iff& iff);
virtual void save (Iff& iff) const;
virtual unsigned getAffectedMaps() const;
TerrainGeneratorOperation getOperation () const;
void setOperation (TerrainGeneratorOperation newOperation);
float getHeight () const;
void setHeight (float newHeight);
};
//-------------------------------------------------------------------
inline TerrainGeneratorOperation AffectorHeightConstant::getOperation () const
{
return operation;
}
//-------------------------------------------------------------------
inline float AffectorHeightConstant::getHeight () const
{
return height;
}
//===================================================================
class AffectorHeightFractal : public TerrainGenerator::Affector
{
private:
//-- not accessible
mutable const MultiFractal* m_multiFractal;
mutable int m_cachedFamilyId;
//-- accessible
int m_familyId;
float m_scaleY;
TerrainGeneratorOperation m_operation;
private:
void load_0000 (Iff& iff, FractalGroup& fractalGroup);
void load_0001 (Iff& iff, FractalGroup& fractalGroup);
void load_0002 (Iff& iff, FractalGroup& fractalGroup);
void load_0003 (Iff& iff);
private:
AffectorHeightFractal (const AffectorHeightFractal& rhs);
AffectorHeightFractal& operator= (const AffectorHeightFractal& rhs);
public:
AffectorHeightFractal ();
virtual ~AffectorHeightFractal ();
virtual void affect (float worldX, float worldZ, int x, int z, float amount, const TerrainGenerator::GeneratorChunkData& generatorChunkData) const;
virtual bool affectsHeight () const;
virtual void load (Iff& iff, FractalGroup& fractalGroup);
virtual void save (Iff& iff) const;
virtual unsigned getAffectedMaps() const;
TerrainGeneratorOperation getOperation () const;
void setOperation (TerrainGeneratorOperation newOperation);
int getFamilyId () const;
void setFamilyId (int id);
float getScaleY () const;
void setScaleY (float newScaleY);
};
//===================================================================
inline TerrainGeneratorOperation AffectorHeightFractal::getOperation () const
{
return m_operation;
}
//-------------------------------------------------------------------
inline int AffectorHeightFractal::getFamilyId () const
{
return m_familyId;
}
//-------------------------------------------------------------------
inline float AffectorHeightFractal::getScaleY () const
{
return m_scaleY;
}
//===================================================================
class AffectorHeightTerrace : public TerrainGenerator::Affector
{
private:
float height;
float fraction;
private:
void load_0000 (Iff& iff);
void load_0001 (Iff& iff);
void load_0002 (Iff& iff);
void load_0003 (Iff& iff);
void load_0004 (Iff& iff);
private:
AffectorHeightTerrace (const AffectorHeightTerrace& rhs);
AffectorHeightTerrace& operator= (const AffectorHeightTerrace& rhs);
public:
AffectorHeightTerrace ();
virtual ~AffectorHeightTerrace ();
virtual void affect (float worldX, float worldZ, int x, int z, float amount, const TerrainGenerator::GeneratorChunkData& generatorChunkData) const;
virtual bool affectsHeight () const;
virtual void load (Iff& iff);
virtual void save (Iff& iff) const;
virtual unsigned getAffectedMaps() const;
float getHeight () const;
void setHeight (float newHeight);
float getFraction () const;
void setFraction (float newFraction);
};
//-------------------------------------------------------------------
inline float AffectorHeightTerrace::getHeight () const
{
return height;
}
//-------------------------------------------------------------------
inline float AffectorHeightTerrace::getFraction () const
{
return fraction;
}
//===================================================================
#endif
@@ -0,0 +1,137 @@
// ======================================================================
//
// AffectorPassable.cpp
// Copyright 2004 Sony Online Entertainment
//
// ======================================================================
#include "sharedTerrain/FirstSharedTerrain.h"
#include "sharedTerrain/AffectorPassable.h"
#include "sharedFile/Iff.h"
//-------------------------------------------------------------------
//
// AffectorExclude
//
AffectorPassable::AffectorPassable () :
TerrainGenerator::Affector (TAG_APAS, TGAT_passable),
m_passable(true),
m_featherThreshold(0.0f)
{
}
//-------------------------------------------------------------------
AffectorPassable::~AffectorPassable ()
{
}
//-------------------------------------------------------------------
unsigned AffectorPassable::getAffectedMaps() const
{
return TGM_passable;
}
//-------------------------------------------------------------------
void AffectorPassable::affect (const float /*worldX*/, const float /*worldZ*/, const int x, const int z, const float amount, const TerrainGenerator::GeneratorChunkData& generatorChunkData) const
{
if (amount >= m_featherThreshold)
generatorChunkData.passableMap->setData (x, z, m_passable);
}
//-------------------------------------------------------------------
void AffectorPassable::load (Iff& iff)
{
switch (iff.getCurrentName ())
{
case TAG_0000:
load_0000 (iff);
break;
default:
{
char tagBuffer [5];
ConvertTagToString (iff.getCurrentName (), tagBuffer);
char buffer [128];
iff.formatLocation (buffer, sizeof (buffer));
DEBUG_FATAL (true, ("invalid AffectorPassable version %s/%s", buffer, tagBuffer));
}
break;
}
}
//-------------------------------------------------------------------
void AffectorPassable::load_0000 (Iff& iff)
{
iff.enterForm (TAG_0000);
{
//-- load the base data
LayerItem::load (iff);
//-- load specific data
iff.enterChunk (TAG_DATA);
{
m_passable = iff.read_bool8();
m_featherThreshold = iff.read_float();
}
iff.exitChunk (TAG_DATA);
}
iff.exitForm (TAG_0000);
}
//-------------------------------------------------------------------
void AffectorPassable::save (Iff& iff) const
{
iff.insertForm (TAG_0000);
{
//-- save the base
LayerItem::save (iff);
//-- save specific data
iff.insertChunk (TAG_DATA);
{
iff.insertChunkData(m_passable);
iff.insertChunkData(m_featherThreshold);
}
iff.exitChunk (TAG_DATA);
}
iff.exitForm (TAG_0000);
}
//----------------------------------------------------------------------
bool AffectorPassable::isPassable() const
{
return m_passable;
}
//----------------------------------------------------------------------
float AffectorPassable::getFeatherThreshold() const
{
return m_featherThreshold;
}
//----------------------------------------------------------------------
void AffectorPassable::setPassable(bool const passable)
{
m_passable = passable;
}
//----------------------------------------------------------------------
void AffectorPassable::setFeatherThreshold(float const featherThreshold)
{
m_featherThreshold = featherThreshold;
}
//-------------------------------------------------------------------
@@ -0,0 +1,53 @@
//======================================================================
//
// AffectorPassable.h
// copyright (c) 2004 Sony Online Entertainment
//
//======================================================================
#ifndef INCLUDED_AffectorPassable_H
#define INCLUDED_AffectorPassable_H
//===================================================================
#include "sharedTerrain/TerrainGenerator.h"
//===================================================================
class AffectorPassable : public TerrainGenerator::Affector
{
private:
void load_0000 (Iff& iff);
private:
AffectorPassable (const AffectorPassable& rhs);
AffectorPassable& operator= (const AffectorPassable& rhs);
public:
AffectorPassable ();
virtual ~AffectorPassable ();
virtual void affect (float worldX, float worldZ, int x, int z, float amount, const TerrainGenerator::GeneratorChunkData& generatorChunkData) const;
virtual void load (Iff& iff);
virtual void save (Iff& iff) const;
virtual unsigned getAffectedMaps() const;
bool isPassable() const;
float getFeatherThreshold() const;
void setPassable(bool passable);
void setFeatherThreshold(float featherThreshold);
private:
bool m_passable;
float m_featherThreshold;
};
//===================================================================
#endif
@@ -0,0 +1,749 @@
//
// AffectorRibbon.cpp
//
// copyright 2005, Sony Online Entertainment
//
//-------------------------------------------------------------------
#include "sharedTerrain/FirstSharedTerrain.h"
#include "sharedTerrain/AffectorRibbon.h"
#include "sharedFile/Iff.h"
#include "sharedMath/Vector2d.h"
#include "sharedRandom/FastRandomGenerator.h"
#include "sharedTerrain/Affector.h"
#include "sharedTerrain/CoordinateHash.h"
//-------------------------------------------------------------------
//
// AffectorRibbon
//
AffectorRibbon::AffectorRibbon () :
AffectorBoundaryPoly (TAG_ARIB, TGAT_ribbon),
m_cachedTerrainShaderFamilyId (-1),
m_cachedSgi (),
m_waterShaderSize(64.0f),
m_velocity(1.0f),
m_capWidth(4.0f),
m_terrainShaderFamilyId (0),
m_featherFunctionTerrainShader (TGFF_linear),
m_featherDistanceTerrainShader (0.5f),
m_ribbonWaterShaderTemplateName (0),
m_waterType(TGWT_water),
m_heightList (),
m_endCapPointList (),
m_endCapExtent()
{
}
//-------------------------------------------------------------------
AffectorRibbon::~AffectorRibbon ()
{
if (m_ribbonWaterShaderTemplateName)
{
delete [] m_ribbonWaterShaderTemplateName;
m_ribbonWaterShaderTemplateName = 0;
}
}
//-------------------------------------------------------------------
void AffectorRibbon::setWaterShaderSize (float val)
{
m_waterShaderSize = val;
}
//-------------------------------------------------------------------
void AffectorRibbon::setVelocity (float val)
{
m_velocity = val;
}
//-------------------------------------------------------------------
void AffectorRibbon::setCapWidth (float val)
{
m_capWidth = val;
}
//-------------------------------------------------------------------
bool AffectorRibbon::affectsHeight () const
{
return false;
}
//-------------------------------------------------------------------
void AffectorRibbon::setTerrainShaderFamilyId (const int newFamilyId)
{
m_terrainShaderFamilyId = newFamilyId;
}
//-------------------------------------------------------------------
void AffectorRibbon::setFeatherFunctionTerrainShader (TerrainGeneratorFeatherFunction newFeatherFunction)
{
m_featherFunctionTerrainShader = newFeatherFunction;
}
//-------------------------------------------------------------------
void AffectorRibbon::setFeatherDistanceTerrainShader (const float newFeatherDistance)
{
m_featherDistanceTerrainShader = newFeatherDistance;
}
//-------------------------------------------------------------------
bool AffectorRibbon::affectsShader () const
{
return true;
}
//-------------------------------------------------------------------
void AffectorRibbon::prepare ()
{
m_cachedTerrainShaderFamilyId = -1;
}
//-------------------------------------------------------------------
void AffectorRibbon::copyHeightList (const ArrayList<float>& newHeightList)
{
m_heightList = newHeightList;
}
//-------------------------------------------------------------------
void AffectorRibbon::createInitialHeightList ()
{
m_heightList.clear ();
int size = m_pointList.getNumberOfElements ();
for(int i = 0; i < size; i++)
{
m_heightList.add(0.0f);
}
}
//-------------------------------------------------------------------
void AffectorRibbon::generateEndCapPointList ()
{
// tapered square - 8 sides - not a perfect octagon
m_endCapPointList.clear();
if(m_capWidth > 0 && m_pointList.getNumberOfElements() > 1)
{
Vector2d up_vect = m_pointList[0] - m_pointList[1];
up_vect.normalize();
Vector2d down_vect = -up_vect;
Vector2d right_vect = Vector2d(up_vect.y,-up_vect.x);
Vector2d left_vect = -right_vect;
// 0
Vector2d currentPoint = m_pointList[0] + (left_vect * m_capWidth/2.0f);
m_endCapPointList.add(currentPoint);
up_vect *= m_capWidth;
down_vect *= m_capWidth;
right_vect *= m_capWidth;
left_vect *= m_capWidth;
// 1
currentPoint = m_endCapPointList[0] + up_vect + left_vect;
m_endCapPointList.add(currentPoint);
// 2
currentPoint = m_endCapPointList[1] + up_vect;
m_endCapPointList.add(currentPoint);
// 3
currentPoint = m_endCapPointList[2] + right_vect + up_vect;
m_endCapPointList.add(currentPoint);
// 4
currentPoint = m_endCapPointList[3] + right_vect;
m_endCapPointList.add(currentPoint);
// 5
currentPoint = m_endCapPointList[4] + down_vect + right_vect;
m_endCapPointList.add(currentPoint);
// 6
currentPoint = m_endCapPointList[5] + down_vect;
m_endCapPointList.add(currentPoint);
// 7
currentPoint = m_endCapPointList[6] + left_vect + down_vect;
m_endCapPointList.add(currentPoint);
}
}
//-------------------------------------------------------------------
unsigned AffectorRibbon::getAffectedMaps() const
{
return unsigned(TGM_ALL);
// TODO - make this correctly report the maps set by 'affect'
}
//-------------------------------------------------------------------
void AffectorRibbon::affect (const float worldX, const float worldZ, const int x, const int z, const float amount, const TerrainGenerator::GeneratorChunkData& generatorChunkData) const
{
if (!isEnabled ())
return;
if (m_terrainShaderFamilyId == 0)
return;
if (amount > 0.f)
{
if (m_extent.isWithin (worldX, worldZ))
{
const float width_2 = m_width * 0.5f;
bool found = false;
FindData result;
if (find (Vector2d (worldX, worldZ), width_2, result,true)) // check the strip
{
const float distanceToCenter = fabsf (result.distanceToCenter);
if (WithinRangeInclusiveInclusive (0.f, distanceToCenter, width_2 * (1.f - getFeatherDistanceTerrainShader ())))
{
found = true;
}
}
if(!found && m_endCapExtent.isWithin(worldX, worldZ)) // check the endcap
{
Vector2d centerOfEndCap = m_endCapExtent.getCenter();
const float distanceToCenter = centerOfEndCap.magnitudeBetween(Vector2d(worldX,worldZ));
if(WithinRangeInclusiveInclusive (0.f, distanceToCenter, (width_2 * 3.0f) * (1.f - getFeatherDistanceTerrainShader())))
{
found = true;
}
}
if(found)
{
//-- set the shader
if (m_cachedTerrainShaderFamilyId != m_terrainShaderFamilyId)
{
m_cachedTerrainShaderFamilyId = m_terrainShaderFamilyId;
m_cachedSgi = generatorChunkData.shaderGroup->chooseShader (m_terrainShaderFamilyId);
}
FastRandomGenerator randomGenerator(CoordinateHash::hashTuple(worldX, worldZ));
ShaderGroup::Info sgi = m_cachedSgi;
sgi.setChildChoice (randomGenerator.randomFloat());
generatorChunkData.shaderMap->setData (x, z, sgi);
}
}
}
}
//-------------------------------------------------------------------
void AffectorRibbon::setRibbonWaterShaderTemplateName (const char* newRibbonWaterShaderTemplateName)
{
if (m_ribbonWaterShaderTemplateName)
{
delete [] m_ribbonWaterShaderTemplateName;
m_ribbonWaterShaderTemplateName = 0;
}
if (newRibbonWaterShaderTemplateName)
m_ribbonWaterShaderTemplateName = DuplicateString (newRibbonWaterShaderTemplateName);
}
//-------------------------------------------------------------------
void AffectorRibbon::setWaterType (TerrainGeneratorWaterType newWaterType)
{
m_waterType = newWaterType;
}
//-------------------------------------------------------------------
void AffectorRibbon::load (Iff& iff)
{
switch (iff.getCurrentName ())
{
case TAG_0000:
load_0000 (iff);
break;
case TAG_0001:
load_0001 (iff);
break;
case TAG_0002:
load_0002 (iff);
break;
case TAG_0003:
load_0003 (iff);
break;
case TAG_0004:
load_0004 (iff);
break;
case TAG_0005:
load_0005 (iff);
break;
default:
{
char tagBuffer [5];
ConvertTagToString (iff.getCurrentName (), tagBuffer);
char buffer [128];
iff.formatLocation (buffer, sizeof (buffer));
DEBUG_FATAL (true, ("invalid AffectorRibbon version %s/%s", buffer, tagBuffer));
}
break;
}
generateEndCapPointList();
recalculate ();
}
//-------------------------------------------------------------------
void AffectorRibbon::load_0000 (Iff& iff)
{
iff.enterForm (TAG_0000);
//-- load the base data
LayerItem::load (iff);
//-- load specific data
iff.enterForm (TAG_DATA);
m_heightData.load (iff);
m_heightData.clear(); // we don't use m_heightdata anymore
iff.enterChunk (TAG_DATA);
const int n = iff.read_int32 ();
int i;
for (i = 0; i < n; ++i)
{
Vector2d point;
point.x = iff.read_float ();
point.y = iff.read_float ();
addPoint (point);
m_heightList.add(0.0f);
}
setWidth (iff.read_float ());
IGNORE_RETURN(iff.read_float ()); // old depth
setWaterShaderSize (64.0f);
setVelocity (1.0f);
setCapWidth(getWidth()); // default cap size of old ribbons to width of ribbon
IGNORE_RETURN(iff.read_int32 ()); // old forward direction
char* templateName = iff.read_string ();
setRibbonWaterShaderTemplateName (templateName);
delete [] templateName;
iff.exitChunk (TAG_DATA);
iff.exitForm (TAG_DATA);
iff.exitForm (TAG_0000);
}
//-------------------------------------------------------------------
void AffectorRibbon::load_0001 (Iff& iff)
{
iff.enterForm (TAG_0001);
//-- load the base data
LayerItem::load (iff);
//-- load specific data
iff.enterForm (TAG_DATA);
m_heightData.load (iff);
m_heightData.clear(); // we don't use m_heightdata anymore
iff.enterChunk (TAG_DATA);
const int n = iff.read_int32 ();
int i;
for (i = 0; i < n; ++i)
{
Vector2d point;
point.x = iff.read_float ();
point.y = iff.read_float ();
addPoint (point);
m_heightList.add(0.0f);
}
setWidth (iff.read_float ());
IGNORE_RETURN(iff.read_float ()); // old depth
setWaterShaderSize (iff.read_float ());
setVelocity (iff.read_float ());
setCapWidth(getWidth()); // default cap size of old ribbons to width of ribbon
IGNORE_RETURN(iff.read_int32 ()); // old forward direction
char* templateName = iff.read_string ();
setRibbonWaterShaderTemplateName (templateName);
delete [] templateName;
iff.exitChunk (TAG_DATA);
iff.exitForm (TAG_DATA);
iff.exitForm (TAG_0001);
}
//-------------------------------------------------------------------
void AffectorRibbon::load_0002 (Iff& iff)
{
iff.enterForm (TAG_0002);
//-- load the base data
LayerItem::load (iff);
//-- load specific data
iff.enterForm (TAG_DATA);
m_heightData.load (iff);
m_heightData.clear(); // we don't use m_heightdata anymore
iff.enterChunk (TAG_DATA);
const int n = iff.read_int32 ();
int i;
for (i = 0; i < n; ++i)
{
Vector2d point;
point.x = iff.read_float ();
point.y = iff.read_float ();
addPoint (point);
m_heightList.add(0.0f);
}
setWidth (iff.read_float ());
IGNORE_RETURN(iff.read_float ()); // old depth
setWaterShaderSize (iff.read_float ());
setVelocity (iff.read_float ());
setCapWidth(getWidth()); // default cap size of old ribbons to width of ribbon
IGNORE_RETURN(iff.read_int32 ()); // old forward direction
char* templateName = iff.read_string ();
setRibbonWaterShaderTemplateName (templateName);
delete [] templateName;
setWaterType(static_cast<TerrainGeneratorWaterType> (iff.read_int32 ()));
iff.exitChunk (TAG_DATA);
iff.exitForm (TAG_DATA);
iff.exitForm (TAG_0002);
}
//-------------------------------------------------------------------
void AffectorRibbon::load_0003 (Iff& iff)
{
iff.enterForm (TAG_0003);
//-- load the base data
LayerItem::load (iff);
//-- load specific data
iff.enterForm (TAG_DATA);
//m_heightData.load (iff);
iff.enterChunk (TAG_DATA);
const int n = iff.read_int32 ();
int i;
for (i = 0; i < n; ++i)
{
Vector2d point;
point.x = iff.read_float ();
point.y = iff.read_float ();
addPoint (point);
m_heightList.add(iff.read_float());
}
setWidth (iff.read_float ());
setWaterShaderSize (iff.read_float ());
setVelocity (iff.read_float ());
setCapWidth(getWidth()); // default cap size of old ribbons to width of ribbon
IGNORE_RETURN(iff.read_int32 ()); // old forward direction
char* templateName = iff.read_string ();
setRibbonWaterShaderTemplateName (templateName);
delete [] templateName;
setWaterType(static_cast<TerrainGeneratorWaterType> (iff.read_int32 ()));
iff.exitChunk (TAG_DATA);
iff.exitForm (TAG_DATA);
iff.exitForm (TAG_0003);
}
//-------------------------------------------------------------------
void AffectorRibbon::load_0004 (Iff& iff)
{
iff.enterForm (TAG_0004);
//-- load the base data
LayerItem::load (iff);
//-- load specific data
iff.enterForm (TAG_DATA);
//m_heightData.load (iff);
iff.enterChunk (TAG_DATA);
const int n = iff.read_int32 ();
int i;
for (i = 0; i < n; ++i)
{
Vector2d point;
point.x = iff.read_float ();
point.y = iff.read_float ();
addPoint (point);
m_heightList.add(iff.read_float());
}
setWidth (iff.read_float ());
setWaterShaderSize (iff.read_float ());
setVelocity (iff.read_float ());
setCapWidth(iff.read_float ());
char* templateName = iff.read_string ();
setRibbonWaterShaderTemplateName (templateName);
delete [] templateName;
setWaterType(static_cast<TerrainGeneratorWaterType> (iff.read_int32 ()));
iff.exitChunk (TAG_DATA);
iff.exitForm (TAG_DATA);
iff.exitForm (TAG_0004);
}
//-------------------------------------------------------------------
void AffectorRibbon::load_0005 (Iff& iff)
{
iff.enterForm (TAG_0005);
//-- load the base data
LayerItem::load (iff);
//-- load specific data
iff.enterForm (TAG_DATA);
//m_heightData.load (iff);
iff.enterChunk (TAG_DATA);
const int n = iff.read_int32 ();
int i;
for (i = 0; i < n; ++i)
{
Vector2d point;
point.x = iff.read_float ();
point.y = iff.read_float ();
addPoint (point);
m_heightList.add(iff.read_float());
}
setWidth (iff.read_float ());
setWaterShaderSize (iff.read_float ());
setVelocity (iff.read_float ());
setCapWidth(iff.read_float ());
setTerrainShaderFamilyId(iff.read_int32());
setFeatherFunctionTerrainShader (static_cast<TerrainGeneratorFeatherFunction> (iff.read_int32 ()));
const float newFeatherDistanceTerrainShader = clamp (0.f, iff.read_float (), 1.f);
setFeatherDistanceTerrainShader (newFeatherDistanceTerrainShader);
char* templateName = iff.read_string ();
setRibbonWaterShaderTemplateName (templateName);
delete [] templateName;
setWaterType(static_cast<TerrainGeneratorWaterType> (iff.read_int32 ()));
iff.exitChunk (TAG_DATA);
iff.exitForm (TAG_DATA);
iff.exitForm (TAG_0005);
}
//-------------------------------------------------------------------
void AffectorRibbon::save (Iff& iff) const
{
iff.insertForm (TAG_0005);
//-- save the base
LayerItem::save (iff);
//-- save specific data
iff.insertForm (TAG_DATA);
//m_heightData.save (iff);
iff.insertChunk (TAG_DATA);
iff.insertChunkData (m_pointList.getNumberOfElements ());
int i;
for (i = 0; i < m_pointList.getNumberOfElements (); ++i)
{
iff.insertChunkData (getPoint (i).x);
iff.insertChunkData (getPoint (i).y);
iff.insertChunkData (m_heightList[i]);
}
iff.insertChunkData (getWidth ());
iff.insertChunkData (getWaterShaderSize ());
iff.insertChunkData (getVelocity ());
iff.insertChunkData (getCapWidth ());
iff.insertChunkData (getTerrainShaderFamilyId ());
iff.insertChunkData (static_cast<int32> (getFeatherFunctionTerrainShader ()));
iff.insertChunkData (getFeatherDistanceTerrainShader ());
iff.insertChunkString (getRibbonWaterShaderTemplateName () ? getRibbonWaterShaderTemplateName () : "");
iff.insertChunkData (static_cast<int32> (getWaterType()));
iff.exitChunk (TAG_DATA);
iff.exitForm (TAG_DATA);
iff.exitForm (TAG_0005);
}
//-------------------------------------------------------------------
struct Segment
{
Vector topControlPoint;
Vector bottomControlPoint;
Vector direction;
Vector topNormal;
Vector bottomNormal;
};
void AffectorRibbon::createQuadList (ArrayList<AffectorRibbon::Quad>& quadList) const
{
ArrayList<Segment> segmentList;
const int pointListSize = m_pointList.size();
if(pointListSize < 2)
{
DEBUG_FATAL(true,("void AffectorRibbon::createQuadList - less than 2 control points for ribbon"));
return;
}
const float width = m_width/2.0f;
// get control points, calc direction, and initial normals
int i;
for (i = 0; i < pointListSize; ++i)
{
Segment segment;
if(i == 0) // handle first segment
{
Vector nextSegmentTopControlPoint = Vector(m_pointList[i+1].x,m_heightList[i+1],m_pointList[i+1].y);
segment.bottomControlPoint = Vector(m_pointList[i].x,m_heightList[i],m_pointList[i].y);
segment.direction = nextSegmentTopControlPoint - segment.bottomControlPoint;
segment.direction.y = 0.0f;
segment.direction.normalize();
segment.topControlPoint = segment.bottomControlPoint - (segment.direction * width);
segment.topNormal = segment.bottomNormal = Vector(segment.direction.z,0.0f,-segment.direction.x);
segmentList.add(segment);
}
if(i == pointListSize - 1) // handle last segment
{
Segment lastSegment = segmentList[segmentList.size() - 1];
segment.direction = lastSegment.direction;
segment.topControlPoint = lastSegment.bottomControlPoint;
segment.bottomControlPoint = segment.topControlPoint + (segment.direction * width);
segment.bottomControlPoint.y = segment.topControlPoint.y;
segment.topNormal = segment.bottomNormal = Vector(segment.direction.z,0.0f,-segment.direction.x);
segmentList.add(segment);
}
else // handle middle segments
{
segment.topControlPoint = Vector(m_pointList[i].x,m_heightList[i],m_pointList[i].y);
segment.bottomControlPoint = Vector(m_pointList[i+1].x,m_heightList[i+1],m_pointList[i+1].y);
segment.direction = segment.bottomControlPoint - segment.topControlPoint;
segment.direction.y = 0.0f;
segment.direction.normalize();
segment.topNormal = segment.bottomNormal = Vector(segment.direction.z,0.0f,-segment.direction.x);
segmentList.add(segment);
}
}
// walk through the segment list and fix the shared normals
const int segmentListSize = segmentList.size();
for(i = 1; i < segmentListSize; i++) // skip the first segment - it's bottom normal gets fixed by the next segment
{
segmentList[i].topNormal = (segmentList[i].topNormal + segmentList[i - 1].bottomNormal) / 2.0f;
segmentList[i - 1].bottomNormal = segmentList[i].topNormal;
}
// walk the segments and build up the points for the quad
for(i = 0; i < segmentListSize; i++)
{
AffectorRibbon::Quad quad;
quad.points[0] = (segmentList[i].topNormal * width) + segmentList[i].topControlPoint;
quad.points[1] = (-segmentList[i].topNormal * width) + segmentList[i].topControlPoint;
quad.points[2] = (-segmentList[i].bottomNormal * width) + segmentList[i].bottomControlPoint;
quad.points[3] = (segmentList[i].bottomNormal * width) + segmentList[i].bottomControlPoint;
quadList.add (quad);
}
}
//-------------------------------------------------------------------
void AffectorRibbon::recalculate ()
{
AffectorBoundaryPoly::recalculate();
m_endCapExtent.x0 = FLT_MAX;
m_endCapExtent.y0 = FLT_MAX;
m_endCapExtent.x1 = -FLT_MAX;
m_endCapExtent.y1 = -FLT_MAX;
int i;
for (i = 0; i < m_endCapPointList.getNumberOfElements (); ++i)
{
m_extent.expand (m_endCapPointList [i].x, m_endCapPointList [i].y);
m_endCapExtent.expand (m_endCapPointList [i].x, m_endCapPointList [i].y);
}
}
@@ -0,0 +1,182 @@
//===================================================================
//
// AffectorRibbon.h
//
// copyright 2005, Sony Online Entertainment
//
//===================================================================
#ifndef INCLUDED_AffectorRibbon_H
#define INCLUDED_AffectorRibbon_H
//===================================================================
#include "sharedTerrain/Affector.h"
//===================================================================
class AffectorRibbon : public AffectorBoundaryPoly
{
public:
struct Quad
{
Vector points [4];
};
public:
AffectorRibbon ();
virtual ~AffectorRibbon ();
virtual void prepare ();
virtual void affect (float worldX, float worldZ, int x, int z, float amount, const TerrainGenerator::GeneratorChunkData& generatorChunkData) const;
virtual void load (Iff& iff);
virtual void save (Iff& iff) const;
virtual bool affectsHeight () const;
virtual bool affectsShader () const;
virtual void createHeightData () {};
virtual unsigned getAffectedMaps() const;
void setWaterShaderSize(float val);
float getWaterShaderSize() const;
void setVelocity(float val);
float getVelocity() const;
void setCapWidth (float newCapWidth);
float getCapWidth () const;
void createQuadList (ArrayList<Quad>& quadList) const;
const char* getRibbonWaterShaderTemplateName () const;
void setRibbonWaterShaderTemplateName (const char* newRibbonShaderTemplateName);
TerrainGeneratorWaterType getWaterType () const;
void setWaterType (TerrainGeneratorWaterType newWaterType);
const ArrayList<float>& getHeightList () const;
void copyHeightList (const ArrayList<float>& newHeightList);
void createInitialHeightList ();
void generateEndCapPointList ();
const ArrayList<Vector2d>& getEndCapPointList () const;
int getTerrainShaderFamilyId () const;
void setTerrainShaderFamilyId (int newFamilyId);
TerrainGeneratorFeatherFunction getFeatherFunctionTerrainShader () const;
void setFeatherFunctionTerrainShader (TerrainGeneratorFeatherFunction newFeatherFunction);
float getFeatherDistanceTerrainShader () const;
void setFeatherDistanceTerrainShader (float newFeatherDistance);
const Rectangle2d& getEndCapExtent() const;
private:
void load_0000 (Iff& iff);
void load_0001 (Iff& iff);
void load_0002 (Iff& iff);
void load_0003 (Iff& iff);
void load_0004 (Iff& iff);
void load_0005 (Iff& iff);
virtual void recalculate ();
private:
AffectorRibbon (const AffectorRibbon& rhs);
AffectorRibbon& operator= (const AffectorRibbon& rhs);
private:
mutable int m_cachedTerrainShaderFamilyId;
mutable ShaderGroup::Info m_cachedSgi;
float m_waterShaderSize;
float m_velocity;
float m_capWidth;
int m_terrainShaderFamilyId;
TerrainGeneratorFeatherFunction m_featherFunctionTerrainShader;
float m_featherDistanceTerrainShader;
char* m_ribbonWaterShaderTemplateName;
TerrainGeneratorWaterType m_waterType;
ArrayList<float> m_heightList;
ArrayList<Vector2d> m_endCapPointList;
Rectangle2d m_endCapExtent;
};
//-------------------------------------------------------------------
inline float AffectorRibbon::getWaterShaderSize () const
{
return m_waterShaderSize;
}
//-------------------------------------------------------------------
inline float AffectorRibbon::getVelocity () const
{
return m_velocity;
}
//-------------------------------------------------------------------
inline const char* AffectorRibbon::getRibbonWaterShaderTemplateName () const
{
return m_ribbonWaterShaderTemplateName;
}
//-------------------------------------------------------------------
inline TerrainGeneratorWaterType AffectorRibbon::getWaterType () const
{
return m_waterType;
}
//-------------------------------------------------------------------
inline const ArrayList<float>& AffectorRibbon::getHeightList () const
{
return m_heightList;
}
//-------------------------------------------------------------------
inline float AffectorRibbon::getCapWidth () const
{
return m_capWidth;
}
//-------------------------------------------------------------------
inline const ArrayList<Vector2d>& AffectorRibbon::getEndCapPointList () const
{
return m_endCapPointList;
}
//-------------------------------------------------------------------
inline int AffectorRibbon::getTerrainShaderFamilyId () const
{
return m_terrainShaderFamilyId;
}
//-------------------------------------------------------------------
inline TerrainGeneratorFeatherFunction AffectorRibbon::getFeatherFunctionTerrainShader () const
{
return m_featherFunctionTerrainShader;
}
//-------------------------------------------------------------------
inline float AffectorRibbon::getFeatherDistanceTerrainShader () const
{
return m_featherDistanceTerrainShader;
}
//-------------------------------------------------------------------
inline const Rectangle2d& AffectorRibbon::getEndCapExtent() const
{
return m_endCapExtent;
}
//===================================================================
#endif
@@ -0,0 +1,940 @@
//===================================================================
//
// AffectorRiver.cpp
// asommers 9-30-2000
//
// copyright 2000, verant interactive
//
//===================================================================
#include "sharedTerrain/FirstSharedTerrain.h"
#include "sharedTerrain/AffectorRiver.h"
#include "sharedTerrain/Affector.h"
#include "sharedTerrain/CoordinateHash.h"
#include "sharedRandom/FastRandomGenerator.h"
#include "sharedFile/Iff.h"
#include <algorithm>
//===================================================================
AffectorRiver::AffectorRiver () :
AffectorBoundaryPoly (TAG_ARIV, TGAT_river),
m_cachedBankFamilyId (-1),
m_cachedBankSgi (),
m_cachedBottomFamilyId (-1),
m_cachedBottomSgi (),
m_multiFractal (),
m_bankFamilyId (0),
m_bottomFamilyId (0),
m_trenchDepth (0.f),
m_hasLocalWaterTable (false),
m_localWaterTableDepth (2.f),
m_localWaterTableWidth (4.f),
m_localWaterTableShaderSize (2.f),
m_localWaterTableShaderTemplateName (0),
m_velocity (0.f),
m_waterType(TGWT_water)
{
m_multiFractal.setScale (0.01f);
m_multiFractal.setGain (true, 0.9f);
m_multiFractal.setNumberOfOctaves (3);
}
//-------------------------------------------------------------------
AffectorRiver::~AffectorRiver ()
{
if (m_localWaterTableShaderTemplateName)
{
delete [] m_localWaterTableShaderTemplateName;
m_localWaterTableShaderTemplateName = 0;
}
}
//-------------------------------------------------------------------
void AffectorRiver::setTrenchDepth (const float newTrenchDepth)
{
m_trenchDepth = newTrenchDepth;
}
//-------------------------------------------------------------------
void AffectorRiver::setVelocity (const float newVelocity)
{
m_velocity = newVelocity;
}
//-------------------------------------------------------------------
void AffectorRiver::setBankFamilyId (const int newBankFamilyId)
{
m_bankFamilyId = newBankFamilyId;
}
//-------------------------------------------------------------------
void AffectorRiver::setBottomFamilyId (const int newBottomFamilyId)
{
m_bottomFamilyId = newBottomFamilyId;
}
//-------------------------------------------------------------------
void AffectorRiver::setWaterType (TerrainGeneratorWaterType newWaterType)
{
m_waterType = newWaterType;
}
//-------------------------------------------------------------------
bool AffectorRiver::affectsHeight () const
{
return true;
}
//-------------------------------------------------------------------
bool AffectorRiver::affectsShader () const
{
return true;
}
//-------------------------------------------------------------------
unsigned AffectorRiver::getAffectedMaps() const
{
return
TGM_height
| TGM_shader
| TGM_floraStaticCollidable
| TGM_floraStaticNonCollidable
| TGM_floraDynamicNear
| TGM_floraDynamicFar
;
}
//-------------------------------------------------------------------
void AffectorRiver::createHeightData ()
{
m_heightData.createRiverData ();
}
//-------------------------------------------------------------------
void AffectorRiver::prepare ()
{
m_cachedBankFamilyId = -1;
m_cachedBottomFamilyId = -1;
}
//-------------------------------------------------------------------
void AffectorRiver::affect (const float worldX, const float worldZ, const int x, const int z, const float amount, const TerrainGenerator::GeneratorChunkData& generatorChunkData) const
{
if (generatorChunkData.m_legacyRandomGenerator)
{
_legacyAffect(worldX, worldZ, x, z, amount, generatorChunkData);
return;
}
if (!isEnabled ())
return;
if (amount > 0.f)
{
if (m_extent.isWithin (worldX, worldZ))
{
const float width_2 = m_width * 0.5f;
const float originalHeight = generatorChunkData.heightMap->getData (x, z);
FindData result;
if (find (Vector2d (worldX, worldZ), width_2, result))
{
//-- set the height
const float distanceToCenter = fabsf (result.distanceToCenter);
const float desiredHeight = result.height - m_trenchDepth;
const float subWidth = width_2 * m_multiFractal.getValue (result.t);
const float feather = subWidth * (1.f - getFeatherDistance ());
FastRandomGenerator randomGenerator(CoordinateHash::hashTuple(worldX, worldZ));
if (distanceToCenter <= feather)
{
generatorChunkData.heightMap->setData (x, z, desiredHeight);
//-- set the shader
if (m_cachedBottomFamilyId != m_bottomFamilyId)
{
m_cachedBottomFamilyId = m_bottomFamilyId;
m_cachedBottomSgi = generatorChunkData.shaderGroup->chooseShader (m_bottomFamilyId);
}
ShaderGroup::Info sgi = m_cachedBottomSgi;
sgi.setChildChoice (randomGenerator.randomFloat());
generatorChunkData.shaderMap->setData (x, z, sgi);
//-- clear the flora
generatorChunkData.floraStaticCollidableMap->setData (x, z, generatorChunkData.floraGroup->getDefaultFlora ());
generatorChunkData.floraStaticNonCollidableMap->setData (x, z, generatorChunkData.floraGroup->getDefaultFlora ());
generatorChunkData.floraDynamicNearMap->setData (x, z, generatorChunkData.radialGroup->getDefaultRadial ());
generatorChunkData.floraDynamicFarMap->setData (x, z, generatorChunkData.radialGroup->getDefaultRadial ());
}
else
{
if (distanceToCenter <= subWidth)
{
//-- height
const float t = distanceToCenter / subWidth;
DEBUG_FATAL (t < 0.f || t > 1.f, ("t is out of range"));
generatorChunkData.heightMap->setData (x, z, linearInterpolate (desiredHeight, originalHeight, sqr (t)));
if (m_cachedBankFamilyId != m_bankFamilyId)
{
m_cachedBankFamilyId = m_bankFamilyId;
m_cachedBankSgi = generatorChunkData.shaderGroup->chooseShader (m_bankFamilyId);
}
ShaderGroup::Info sgi = m_cachedBankSgi;
sgi.setChildChoice(randomGenerator.randomFloat());
generatorChunkData.shaderMap->setData (x, z, sgi);
}
}
}
}
}
}
void AffectorRiver::_legacyAffect(const float worldX, const float worldZ, const int x, const int z, const float amount, const TerrainGenerator::GeneratorChunkData& generatorChunkData) const
{
if (!isEnabled ())
return;
if (amount > 0.f)
{
if (m_extent.isWithin (worldX, worldZ))
{
const float width_2 = m_width * 0.5f;
const float originalHeight = generatorChunkData.heightMap->getData (x, z);
FindData result;
if (find (Vector2d (worldX, worldZ), width_2, result))
{
//-- set the height
const float distanceToCenter = fabsf (result.distanceToCenter);
const float desiredHeight = result.height - m_trenchDepth;
const float subWidth = width_2 * m_multiFractal.getValue (result.t);
const float feather = subWidth * (1.f - getFeatherDistance ());
if (distanceToCenter <= feather)
{
generatorChunkData.heightMap->setData (x, z, desiredHeight);
//-- set the shader
if (m_cachedBottomFamilyId != m_bottomFamilyId)
{
m_cachedBottomFamilyId = m_bottomFamilyId;
m_cachedBottomSgi = generatorChunkData.shaderGroup->chooseShader (m_bottomFamilyId);
}
ShaderGroup::Info sgi = m_cachedBottomSgi;
sgi.setChildChoice (generatorChunkData.m_legacyRandomGenerator->randomReal (0.0f, 1.0f));
generatorChunkData.shaderMap->setData (x, z, sgi);
//-- clear the flora
generatorChunkData.floraStaticCollidableMap->setData (x, z, generatorChunkData.floraGroup->getDefaultFlora ());
generatorChunkData.floraStaticNonCollidableMap->setData (x, z, generatorChunkData.floraGroup->getDefaultFlora ());
generatorChunkData.floraDynamicNearMap->setData (x, z, generatorChunkData.radialGroup->getDefaultRadial ());
generatorChunkData.floraDynamicFarMap->setData (x, z, generatorChunkData.radialGroup->getDefaultRadial ());
}
else
{
if (distanceToCenter <= subWidth)
{
//-- height
const float t = distanceToCenter / subWidth;
DEBUG_FATAL (t < 0.f || t > 1.f, ("t is out of range"));
generatorChunkData.heightMap->setData (x, z, linearInterpolate (desiredHeight, originalHeight, sqr (t)));
if (m_cachedBankFamilyId != m_bankFamilyId)
{
m_cachedBankFamilyId = m_bankFamilyId;
m_cachedBankSgi = generatorChunkData.shaderGroup->chooseShader (m_bankFamilyId);
}
ShaderGroup::Info sgi = m_cachedBankSgi;
sgi.setChildChoice (generatorChunkData.m_legacyRandomGenerator->randomReal (0.0f, 1.0f));
generatorChunkData.shaderMap->setData (x, z, sgi);
}
}
}
}
}
}
//-------------------------------------------------------------------
void AffectorRiver::load (Iff& iff)
{
switch (iff.getCurrentName ())
{
case TAG_0000:
load_0000 (iff);
break;
case TAG_0001:
load_0001 (iff);
break;
case TAG_0002:
load_0002 (iff);
break;
case TAG_0003:
load_0003 (iff);
break;
case TAG_0004:
load_0004 (iff);
break;
case TAG_0005:
load_0005 (iff);
break;
case TAG_0006:
load_0006 (iff);
break;
default:
{
char tagBuffer [5];
ConvertTagToString (iff.getCurrentName (), tagBuffer);
char buffer [128];
iff.formatLocation (buffer, sizeof (buffer));
DEBUG_FATAL (true, ("invalid AffectorRiver version %s/%s", buffer, tagBuffer));
}
break;
}
recalculate ();
}
//-------------------------------------------------------------------
void AffectorRiver::load_0000 (Iff& iff)
{
iff.enterForm (TAG_0000);
//-- load the base data
LayerItem::load (iff);
//-- load specific data
iff.enterForm (TAG_DATA);
m_heightData.load (iff);
iff.enterChunk (TAG_DATA);
Vector2d newStart;
newStart.x = iff.read_float ();
newStart.y = iff.read_float ();
addPoint (newStart);
Vector2d newEnd;
newEnd.x = iff.read_float ();
newEnd.y = iff.read_float ();
addPoint (newEnd);
setWidth (iff.read_float ());
setBankFamilyId (iff.read_int32 ());
setBottomFamilyId (getBankFamilyId ());
setFeatherFunction (static_cast<TerrainGeneratorFeatherFunction> (iff.read_int32 ()));
const float newFeatherDistance = clamp (0.f, iff.read_float (), 1.f);
setFeatherDistance (newFeatherDistance);
iff.exitChunk (TAG_DATA);
iff.exitForm (TAG_DATA);
iff.exitForm (TAG_0000);
}
//-------------------------------------------------------------------
void AffectorRiver::load_0001 (Iff& iff)
{
iff.enterForm (TAG_0001);
//-- load the base data
LayerItem::load (iff);
//-- load specific data
iff.enterForm (TAG_DATA);
m_heightData.load (iff);
iff.enterChunk (TAG_DATA);
Vector2d newStart;
newStart.x = iff.read_float ();
newStart.y = iff.read_float ();
addPoint (newStart);
Vector2d newEnd;
newEnd.x = iff.read_float ();
newEnd.y = iff.read_float ();
addPoint (newEnd);
setWidth (iff.read_float ());
setBankFamilyId (iff.read_int32 ());
setBottomFamilyId (getBankFamilyId ());
setFeatherFunction (static_cast<TerrainGeneratorFeatherFunction> (iff.read_int32 ()));
const float newFeatherDistance = clamp (0.f, iff.read_float (), 1.f);
setFeatherDistance (newFeatherDistance);
setTrenchDepth (iff.read_float ());
setVelocity (iff.read_float ());
setLocalWaterTableShaderSize (iff.read_float ());
char* templateName = iff.read_string ();
setLocalWaterTableShaderTemplateName (templateName);
delete [] templateName;
iff.exitChunk (TAG_DATA);
iff.exitForm (TAG_DATA);
iff.exitForm (TAG_0001);
}
//-------------------------------------------------------------------
void AffectorRiver::load_0002 (Iff& iff)
{
iff.enterForm (TAG_0002);
//-- load the base data
LayerItem::load (iff);
//-- load specific data
iff.enterForm (TAG_DATA);
m_heightData.load (iff);
iff.enterChunk (TAG_DATA);
Vector2d newStart;
newStart.x = iff.read_float ();
newStart.y = iff.read_float ();
addPoint (newStart);
Vector2d newEnd;
newEnd.x = iff.read_float ();
newEnd.y = iff.read_float ();
addPoint (newEnd);
setWidth (iff.read_float ());
setBankFamilyId (iff.read_int32 ());
setBottomFamilyId (getBankFamilyId ());
setFeatherFunction (static_cast<TerrainGeneratorFeatherFunction> (iff.read_int32 ()));
const float newFeatherDistance = clamp (0.f, iff.read_float (), 1.f);
setFeatherDistance (newFeatherDistance);
setTrenchDepth (iff.read_float ());
setVelocity (iff.read_float ());
m_hasLocalWaterTable = iff.read_int32 () != 0;
setLocalWaterTableDepth (iff.read_float ());
setLocalWaterTableShaderSize (iff.read_float ());
setLocalWaterTableWidth (getWidth ());
char* templateName = iff.read_string ();
setLocalWaterTableShaderTemplateName (templateName);
delete [] templateName;
iff.exitChunk (TAG_DATA);
iff.exitForm (TAG_DATA);
iff.exitForm (TAG_0002);
}
//-------------------------------------------------------------------
void AffectorRiver::load_0003 (Iff& iff)
{
iff.enterForm (TAG_0003);
//-- load the base data
LayerItem::load (iff);
//-- load specific data
iff.enterForm (TAG_DATA);
m_heightData.load (iff);
iff.enterChunk (TAG_DATA);
Vector2d newStart;
newStart.x = iff.read_float ();
newStart.y = iff.read_float ();
addPoint (newStart);
Vector2d newEnd;
newEnd.x = iff.read_float ();
newEnd.y = iff.read_float ();
addPoint (newEnd);
setWidth (iff.read_float ());
setBankFamilyId (iff.read_int32 ());
setBottomFamilyId (iff.read_int32 ());
setFeatherFunction (static_cast<TerrainGeneratorFeatherFunction> (iff.read_int32 ()));
const float newFeatherDistance = clamp (0.f, iff.read_float (), 1.f);
setFeatherDistance (newFeatherDistance);
setTrenchDepth (iff.read_float ());
setVelocity (iff.read_float ());
m_hasLocalWaterTable = iff.read_int32 () != 0;
setLocalWaterTableDepth (iff.read_float ());
setLocalWaterTableShaderSize (iff.read_float ());
setLocalWaterTableWidth (getWidth ());
char* templateName = iff.read_string ();
setLocalWaterTableShaderTemplateName (templateName);
delete [] templateName;
iff.exitChunk (TAG_DATA);
iff.exitForm (TAG_DATA);
iff.exitForm (TAG_0003);
}
//-------------------------------------------------------------------
void AffectorRiver::load_0004 (Iff& iff)
{
iff.enterForm (TAG_0004);
//-- load the base data
LayerItem::load (iff);
//-- load specific data
iff.enterForm (TAG_DATA);
m_heightData.load (iff);
iff.enterChunk (TAG_DATA);
const int n = iff.read_int32 ();
int i;
for (i = 0; i < n; ++i)
{
Vector2d point;
point.x = iff.read_float ();
point.y = iff.read_float ();
addPoint (point);
}
setWidth (iff.read_float ());
setBankFamilyId (iff.read_int32 ());
setBottomFamilyId (iff.read_int32 ());
setFeatherFunction (static_cast<TerrainGeneratorFeatherFunction> (iff.read_int32 ()));
const float newFeatherDistance = clamp (0.f, iff.read_float (), 1.f);
setFeatherDistance (newFeatherDistance);
setTrenchDepth (iff.read_float ());
setVelocity (iff.read_float ());
m_hasLocalWaterTable = iff.read_int32 () != 0;
setLocalWaterTableDepth (iff.read_float ());
setLocalWaterTableShaderSize (iff.read_float ());
setLocalWaterTableWidth (getWidth ());
char* templateName = iff.read_string ();
setLocalWaterTableShaderTemplateName (templateName);
delete [] templateName;
iff.exitChunk (TAG_DATA);
iff.exitForm (TAG_DATA);
iff.exitForm (TAG_0004);
}
//-------------------------------------------------------------------
void AffectorRiver::load_0005 (Iff& iff)
{
iff.enterForm (TAG_0005);
//-- load the base data
LayerItem::load (iff);
//-- load specific data
iff.enterForm (TAG_DATA);
m_heightData.load (iff);
iff.enterChunk (TAG_DATA);
const int n = iff.read_int32 ();
int i;
for (i = 0; i < n; ++i)
{
Vector2d point;
point.x = iff.read_float ();
point.y = iff.read_float ();
addPoint (point);
}
setWidth (iff.read_float ());
setBankFamilyId (iff.read_int32 ());
setBottomFamilyId (iff.read_int32 ());
setFeatherFunction (static_cast<TerrainGeneratorFeatherFunction> (iff.read_int32 ()));
const float newFeatherDistance = clamp (0.f, iff.read_float (), 1.f);
setFeatherDistance (newFeatherDistance);
setTrenchDepth (iff.read_float ());
setVelocity (iff.read_float ());
m_hasLocalWaterTable = iff.read_int32 () != 0;
setLocalWaterTableDepth (iff.read_float ());
setLocalWaterTableWidth (iff.read_float ());
setLocalWaterTableShaderSize (iff.read_float ());
char* templateName = iff.read_string ();
setLocalWaterTableShaderTemplateName (templateName);
delete [] templateName;
iff.exitChunk (TAG_DATA);
iff.exitForm (TAG_DATA);
iff.exitForm (TAG_0005);
}
//-------------------------------------------------------------------
void AffectorRiver::load_0006 (Iff& iff)
{
iff.enterForm (TAG_0006);
//-- load the base data
LayerItem::load (iff);
//-- load specific data
iff.enterForm (TAG_DATA);
m_heightData.load (iff);
iff.enterChunk (TAG_DATA);
const int n = iff.read_int32 ();
int i;
for (i = 0; i < n; ++i)
{
Vector2d point;
point.x = iff.read_float ();
point.y = iff.read_float ();
addPoint (point);
}
setWidth (iff.read_float ());
setBankFamilyId (iff.read_int32 ());
setBottomFamilyId (iff.read_int32 ());
setFeatherFunction (static_cast<TerrainGeneratorFeatherFunction> (iff.read_int32 ()));
const float newFeatherDistance = clamp (0.f, iff.read_float (), 1.f);
setFeatherDistance (newFeatherDistance);
setTrenchDepth (iff.read_float ());
setVelocity (iff.read_float ());
m_hasLocalWaterTable = iff.read_int32 () != 0;
setLocalWaterTableDepth (iff.read_float ());
setLocalWaterTableWidth (iff.read_float ());
setLocalWaterTableShaderSize (iff.read_float ());
char* templateName = iff.read_string ();
setLocalWaterTableShaderTemplateName (templateName);
delete [] templateName;
setWaterType(static_cast<TerrainGeneratorWaterType> (iff.read_int32 ()));
iff.exitChunk (TAG_DATA);
iff.exitForm (TAG_DATA);
iff.exitForm (TAG_0006);
}
//-------------------------------------------------------------------
void AffectorRiver::save (Iff& iff) const
{
iff.insertForm (TAG_0006);
//-- save the base
LayerItem::save (iff);
//-- save specific data
iff.insertForm (TAG_DATA);
m_heightData.save (iff);
iff.insertChunk (TAG_DATA);
iff.insertChunkData (m_pointList.getNumberOfElements ());
int i;
for (i = 0; i < m_pointList.getNumberOfElements (); ++i)
{
iff.insertChunkData (getPoint (i).x);
iff.insertChunkData (getPoint (i).y);
}
iff.insertChunkData (getWidth ());
iff.insertChunkData (getBankFamilyId ());
iff.insertChunkData (getBottomFamilyId ());
iff.insertChunkData (static_cast<int32> (getFeatherFunction ()));
iff.insertChunkData (getFeatherDistance ());
iff.insertChunkData (getTrenchDepth ());
iff.insertChunkData (getVelocity ());
iff.insertChunkData (getHasLocalWaterTable () ? static_cast<int32> (1) : static_cast<int32> (0));
iff.insertChunkData (getLocalWaterTableDepth ());
iff.insertChunkData (getLocalWaterTableWidth ());
iff.insertChunkData (getLocalWaterTableShaderSize ());
iff.insertChunkString (getLocalWaterTableShaderTemplateName () ? getLocalWaterTableShaderTemplateName () : "");
iff.insertChunkData (static_cast<int32> (getWaterType()));
iff.exitChunk (TAG_DATA);
iff.exitForm (TAG_DATA);
iff.exitForm (TAG_0006);
}
//-------------------------------------------------------------------
void AffectorRiver::createWaterTables (ArrayList<AffectorRiver::WaterTable>& waterTableList) const
{
Vector previousLeftStrip;
Vector previousRightStrip;
const float waterWidth = m_localWaterTableWidth * 0.5f;
int i;
for (i = 0; i < m_pointList.size () - 1; ++i)
{
//
// setup initial states
//
const bool atStart = i == 0;
const bool atEndNext = i == (m_pointList.size () - 2);
const Vector2d& currentStart = m_pointList [i];
const Vector2d& currentEnd = m_pointList [i + 1];
const Vector2d currentSegment = currentEnd - currentStart;
const Vector2d currentDirection = Vector2d::normalized (currentSegment);
const Vector2d currentNormal = Vector2d::normal (currentDirection, false);
const float currentSegmentLength = currentSegment.magnitude ();
const Vector2d currentStartLeft = currentStart - currentNormal * waterWidth;
const Vector2d currentStartRight = currentStart + currentNormal * waterWidth;
const Vector2d currentEndLeft = currentEnd - currentNormal * waterWidth;
const Vector2d currentEndRight = currentEnd + currentNormal * waterWidth;
const Vector2d& previousStart = !atStart ? m_pointList [i - 1] : m_pointList [i];
const Vector2d& previousEnd = !atStart ? m_pointList [i] : m_pointList [i];
const Vector2d previousSegment = previousEnd - previousStart;
const Vector2d previousDirection = !atStart ? Vector2d::normalized (previousSegment) : currentDirection;
const Vector2d previousNormal = !atStart ? Vector2d::normal (previousDirection, false) : currentNormal;
const float previousSegmentLength = previousSegment.magnitude ();
const Vector2d previousStartLeft = previousStart - previousNormal * waterWidth;
const Vector2d previousStartRight = previousStart + previousNormal * waterWidth;
const Vector2d previousEndLeft = previousEnd - previousNormal * waterWidth;
const Vector2d previousEndRight = previousEnd + previousNormal * waterWidth;
const Vector2d& nextStart = !atEndNext ? m_pointList [i + 1] : m_pointList [i + 1];
const Vector2d& nextEnd = !atEndNext ? m_pointList [i + 2] : m_pointList [i + 1];
const Vector2d nextSegment = nextEnd - nextStart;
const Vector2d nextDirection = !atEndNext ? Vector2d::normalized (nextSegment) : currentDirection;
const Vector2d nextNormal = !atEndNext ? Vector2d::normal (nextDirection, false) : currentNormal;
const float nextSegmentLength = nextSegment.magnitude ();
const Vector2d nextStartLeft = nextStart - nextNormal * waterWidth;
const Vector2d nextStartRight = nextStart + nextNormal * waterWidth;
const Vector2d nextEndLeft = nextEnd - nextNormal * waterWidth;
const Vector2d nextEndRight = nextEnd + nextNormal * waterWidth;
const Vector2d left [6] =
{
!atStart ? Vector2d::linearInterpolate (previousStartLeft, previousEndLeft, ((previousSegmentLength - waterWidth) / previousSegmentLength)) : currentStartLeft,
!atStart ? currentStart - (Vector2d::normalized (currentStart - (previousEndLeft + currentStartLeft) * 0.5f) * waterWidth) : currentStartLeft,
Vector2d::linearInterpolate (currentStartLeft, currentEndLeft, waterWidth / currentSegmentLength),
Vector2d::linearInterpolate (currentStartLeft, currentEndLeft, ((currentSegmentLength - waterWidth) / currentSegmentLength)),
!atEndNext ? currentEnd - (Vector2d::normalized (currentEnd - (currentEndLeft + nextStartLeft) * 0.5f) * waterWidth) : currentEndLeft,
!atEndNext ? Vector2d::linearInterpolate (nextStartLeft, nextEndLeft, waterWidth / nextSegmentLength) : nextStartLeft
};
const Vector2d right [6] =
{
!atStart ? Vector2d::linearInterpolate (previousStartRight, previousEndRight, ((previousSegmentLength - waterWidth) / previousSegmentLength)) : currentStartRight,
!atStart ? currentStart - (Vector2d::normalized (currentStart - (previousEndRight + currentStartRight) * 0.5f) * waterWidth) : currentStartRight,
Vector2d::linearInterpolate (currentStartRight, currentEndRight, waterWidth / currentSegmentLength),
Vector2d::linearInterpolate (currentStartRight, currentEndRight, ((currentSegmentLength - waterWidth) / currentSegmentLength)),
!atEndNext ? currentEnd - (Vector2d::normalized (currentEnd - (currentEndRight + nextStartRight) * 0.5f) * waterWidth) : currentEndRight,
!atEndNext ? Vector2d::linearInterpolate (nextStartRight, nextEndRight, waterWidth / nextSegmentLength) : nextStartRight
};
if (!atStart)
{
if (left [0].magnitudeBetweenSquared (left [2]) < right [0].magnitudeBetweenSquared (right [2]))
const_cast<Vector2d*> (left) [1] = (left [0] + left [2]) * 0.5f;
else
const_cast<Vector2d*> (right) [1] = (right [0] + right [2]) * 0.5f;
}
if (!atEndNext)
{
if (left [3].magnitudeBetweenSquared (left [5]) < right [3].magnitudeBetweenSquared (right [5]))
const_cast<Vector2d*> (left) [4] = (left [3] + left [5]) * 0.5f;
else
const_cast<Vector2d*> (right) [4] = (right [3] + right [5]) * 0.5f;
}
//
// walk the current segment
//
{
int j;
for (j = 0; j < m_heightData.getNumberOfPoints (i); ++j)
{
const Vector2d point (m_heightData.getPoint (i, j).x, m_heightData.getPoint (i, j).z);
Vector2d leftStrip = point - currentNormal * waterWidth;
Vector2d rightStrip = point + currentNormal * waterWidth;
const float segmentLength = currentStart.magnitudeBetween (point);
if (segmentLength < waterWidth)
{
const float t = segmentLength / waterWidth;
leftStrip = Vector2d::linearInterpolate (left [1], left [2], t);
rightStrip = Vector2d::linearInterpolate (right [1], right [2], t);
}
else
if (segmentLength > currentSegmentLength - waterWidth)
{
const float t = (segmentLength + waterWidth - currentSegmentLength) / waterWidth;
leftStrip = Vector2d::linearInterpolate (left [3], left [4], t);
rightStrip = Vector2d::linearInterpolate (right [3], right [4], t);
}
if (j == 0)
{
if (atStart)
{
const Vector2d initialLeft = currentStartLeft - (currentDirection * waterWidth);
const Vector2d initialRight = currentStartRight - (currentDirection * waterWidth);
AffectorRiver::WaterTable table;
table.points [0].set (initialRight.x, m_heightData.getPoint (i, j).y - m_localWaterTableDepth, initialRight.y);
table.points [1].set (initialLeft.x, m_heightData.getPoint (i, j).y - m_localWaterTableDepth, initialLeft.y);
table.points [2].set (leftStrip.x, m_heightData.getPoint (i, j).y - m_localWaterTableDepth, leftStrip.y);
table.points [3].set (rightStrip.x, m_heightData.getPoint (i, j).y - m_localWaterTableDepth, rightStrip.y);
table.direction = currentDirection;
waterTableList.add (table);
}
}
else
{
AffectorRiver::WaterTable table;
table.points [0] = previousRightStrip;
table.points [1] = previousLeftStrip;
table.points [2].set (leftStrip.x, m_heightData.getPoint (i, j).y - m_localWaterTableDepth, leftStrip.y);
table.points [3].set (rightStrip.x, m_heightData.getPoint (i, j).y - m_localWaterTableDepth, rightStrip.y);
table.direction = currentDirection;
waterTableList.add (table);
}
previousLeftStrip.set (leftStrip.x, m_heightData.getPoint (i, j).y - m_localWaterTableDepth, leftStrip.y);
previousRightStrip.set (rightStrip.x, m_heightData.getPoint (i, j).y - m_localWaterTableDepth, rightStrip.y);
if (j == m_heightData.getNumberOfPoints (i) - 1)
{
if (atEndNext)
{
const Vector2d finalLeft = currentEndLeft + (currentDirection * waterWidth);
const Vector2d finalRight = currentEndRight + (currentDirection * waterWidth);
AffectorRiver::WaterTable table;
table.points [0] = previousRightStrip;
table.points [1] = previousLeftStrip;
table.points [2].set (finalLeft.x, m_heightData.getPoint (i, j).y - m_localWaterTableDepth, finalLeft.y);
table.points [3].set (finalRight.x, m_heightData.getPoint (i, j).y - m_localWaterTableDepth, finalRight.y);
table.direction = currentDirection;
waterTableList.add (table);
}
}
}
}
}
}
//-------------------------------------------------------------------
void AffectorRiver::setLocalWaterTableShaderSize (const float newLocalWaterTableShaderSize)
{
m_localWaterTableShaderSize = newLocalWaterTableShaderSize;
}
//-------------------------------------------------------------------
void AffectorRiver::setLocalWaterTableShaderTemplateName (const char* newLocalWaterTableShaderTemplateName)
{
if (m_localWaterTableShaderTemplateName)
{
delete [] m_localWaterTableShaderTemplateName;
m_localWaterTableShaderTemplateName = 0;
}
if (newLocalWaterTableShaderTemplateName)
m_localWaterTableShaderTemplateName = DuplicateString (newLocalWaterTableShaderTemplateName);
}
//-------------------------------------------------------------------
void AffectorRiver::setHasLocalWaterTable (const bool newHasLocalWaterTable)
{
m_hasLocalWaterTable = newHasLocalWaterTable;
}
//-------------------------------------------------------------------
void AffectorRiver::setLocalWaterTableDepth (const float newLocalWaterTableDepth)
{
m_localWaterTableDepth = newLocalWaterTableDepth;
}
//-------------------------------------------------------------------
void AffectorRiver::setLocalWaterTableWidth (const float newLocalWaterTableWidth)
{
m_localWaterTableWidth = newLocalWaterTableWidth;
}
//===================================================================
@@ -0,0 +1,185 @@
//===================================================================
//
// AffectorRiver.h
// asommers 9-30-2000
//
// copyright 2000, verant interactive
//
//===================================================================
#ifndef INCLUDED_AffectorRiver_H
#define INCLUDED_AffectorRiver_H
//===================================================================
#include "sharedFractal/MultiFractal.h"
#include "sharedTerrain/Affector.h"
#include "sharedMath/Vector2d.h"
//===================================================================
class AffectorRiver : public AffectorBoundaryPoly
{
public:
struct WaterTable
{
Vector points [4];
Vector2d direction;
};
public:
AffectorRiver ();
virtual ~AffectorRiver ();
virtual void prepare ();
virtual void affect (float worldX, float worldZ, int x, int z, float amount, const TerrainGenerator::GeneratorChunkData& generatorChunkData) const;
virtual void load (Iff& iff);
virtual void save (Iff& iff) const;
virtual bool affectsHeight () const;
virtual bool affectsShader () const;
virtual unsigned getAffectedMaps() const;
virtual void createHeightData ();
void setTrenchDepth (float newTrenchDepth);
void setVelocity (float newVelocity);
float getTrenchDepth () const;
float getVelocity () const;
int getBankFamilyId () const;
void setBankFamilyId (int newBankFamilyId);
int getBottomFamilyId () const;
void setBottomFamilyId (int newBottomFamilyId);
void createWaterTables (ArrayList<WaterTable>& waterTableList) const;
bool getHasLocalWaterTable () const;
void setHasLocalWaterTable (bool newHasWater);
float getLocalWaterTableShaderSize () const;
void setLocalWaterTableShaderSize (float newLocalWaterTableShaderSize);
const char* getLocalWaterTableShaderTemplateName () const;
void setLocalWaterTableShaderTemplateName (const char* newLocalWaterTableShaderTemplateName);
float getLocalWaterTableDepth () const;
void setLocalWaterTableDepth (float newLocalWaterTableDepth);
float getLocalWaterTableWidth () const;
void setLocalWaterTableWidth (float newLocalWaterTableWidth);
TerrainGeneratorWaterType getWaterType () const;
void setWaterType (TerrainGeneratorWaterType newWaterType);
private:
void _legacyAffect(const float worldX, const float worldZ, const int x, const int z, const float amount, const TerrainGenerator::GeneratorChunkData& generatorChunkData) const;
void load_0000 (Iff& iff);
void load_0001 (Iff& iff);
void load_0002 (Iff& iff);
void load_0003 (Iff& iff);
void load_0004 (Iff& iff);
void load_0005 (Iff& iff);
void load_0006 (Iff& iff);
private:
AffectorRiver (const AffectorRiver& rhs);
AffectorRiver& operator= (const AffectorRiver& rhs);
private:
mutable int m_cachedBankFamilyId;
mutable ShaderGroup::Info m_cachedBankSgi;
mutable int m_cachedBottomFamilyId;
mutable ShaderGroup::Info m_cachedBottomSgi;
MultiFractal m_multiFractal;
//-- accessible
int m_bankFamilyId;
int m_bottomFamilyId;
float m_trenchDepth;
bool m_hasLocalWaterTable;
float m_localWaterTableDepth;
float m_localWaterTableWidth;
float m_localWaterTableShaderSize;
char* m_localWaterTableShaderTemplateName;
float m_velocity;
TerrainGeneratorWaterType m_waterType;
};
//-------------------------------------------------------------------
inline int AffectorRiver::getBankFamilyId () const
{
return m_bankFamilyId;
}
//-------------------------------------------------------------------
inline int AffectorRiver::getBottomFamilyId () const
{
return m_bottomFamilyId;
}
//-------------------------------------------------------------------
inline float AffectorRiver::getTrenchDepth () const
{
return m_trenchDepth;
}
//-------------------------------------------------------------------
inline float AffectorRiver::getVelocity () const
{
return m_velocity;
}
//-------------------------------------------------------------------
inline float AffectorRiver::getLocalWaterTableShaderSize () const
{
return m_localWaterTableShaderSize;
}
//-------------------------------------------------------------------
inline const char* AffectorRiver::getLocalWaterTableShaderTemplateName () const
{
return m_localWaterTableShaderTemplateName;
}
//-------------------------------------------------------------------
inline bool AffectorRiver::getHasLocalWaterTable () const
{
return m_hasLocalWaterTable;
}
//-------------------------------------------------------------------
inline float AffectorRiver::getLocalWaterTableDepth () const
{
return m_localWaterTableDepth;
}
//-------------------------------------------------------------------
inline float AffectorRiver::getLocalWaterTableWidth () const
{
return m_localWaterTableWidth;
}
//-------------------------------------------------------------------
inline TerrainGeneratorWaterType AffectorRiver::getWaterType () const
{
return m_waterType;
}
//===================================================================
#endif
@@ -0,0 +1,745 @@
//
// AffectorRoad.cpp
// asommers 9-30-2000
//
// copyright 2000, verant interactive
//
//-------------------------------------------------------------------
#include "sharedTerrain/FirstSharedTerrain.h"
#include "sharedTerrain/AffectorRoad.h"
#include "sharedFile/Iff.h"
#include "sharedMath/Line2d.h"
#include "sharedMath/Vector2d.h"
#include "sharedTerrain/CoordinateHash.h"
#include "sharedRandom/FastRandomGenerator.h"
#include "sharedTerrain/Affector.h"
#include "sharedTerrain/Feather.h"
//-------------------------------------------------------------------
//
// AffectorRoad
//
AffectorRoad::AffectorRoad () :
AffectorBoundaryPoly (TAG_AROA, TGAT_road),
m_cachedFamilyId (-1),
m_cachedSgi (),
m_familyId (0),
m_featherFunctionShader (TGFF_linear),
m_featherDistanceShader (0.5f),
m_hasFixedHeights(false),
m_heightList ()
{
}
//-------------------------------------------------------------------
AffectorRoad::~AffectorRoad ()
{
}
//-------------------------------------------------------------------
void AffectorRoad::setFamilyId (const int newFamilyId)
{
m_familyId = newFamilyId;
}
//-------------------------------------------------------------------
void AffectorRoad::setFeatherFunctionShader (TerrainGeneratorFeatherFunction newFeatherFunction)
{
m_featherFunctionShader = newFeatherFunction;
}
//-------------------------------------------------------------------
void AffectorRoad::setFeatherDistanceShader (const float newFeatherDistance)
{
m_featherDistanceShader = newFeatherDistance;
}
//-------------------------------------------------------------------
void AffectorRoad::setHasFixedHeights (const bool newVal)
{
m_hasFixedHeights = newVal;
}
//-------------------------------------------------------------------
bool AffectorRoad::affectsHeight () const
{
return true;
}
//-------------------------------------------------------------------
bool AffectorRoad::affectsShader () const
{
return true;
}
//-------------------------------------------------------------------
void AffectorRoad::createInitialHeightList ()
{
m_heightList.clear ();
int size = m_pointList.getNumberOfElements ();
for(int i = 0; i < size; i++)
{
m_heightList.add(0.0f);
}
}
//-------------------------------------------------------------------
void AffectorRoad::copyHeightList (const ArrayList<float>& newHeightList)
{
m_heightList = newHeightList;
}
//-------------------------------------------------------------------
void AffectorRoad::clearHeightList ()
{
m_heightList.clear ();
}
//-------------------------------------------------------------------
unsigned AffectorRoad::getAffectedMaps() const
{
return
TGM_height
| TGM_shader
| TGM_floraStaticCollidable
| TGM_floraStaticNonCollidable
| TGM_floraDynamicNear
| TGM_floraDynamicFar
;
}
//-------------------------------------------------------------------
void AffectorRoad::createHeightData ()
{
m_heightData.createRoadData ();
}
//-------------------------------------------------------------------
void AffectorRoad::prepare ()
{
m_cachedFamilyId = -1;
}
//-------------------------------------------------------------------
void AffectorRoad::affect (const float worldX, const float worldZ, const int x, const int z, const float amount, const TerrainGenerator::GeneratorChunkData& generatorChunkData) const
{
if (generatorChunkData.m_legacyRandomGenerator)
{
_legacyAffect(worldX, worldZ, x, z, amount, generatorChunkData);
return;
}
if (!isEnabled ())
return;
if (amount > 0.f)
{
if (m_extent.isWithin (worldX, worldZ))
{
const float width_2 = m_width * 0.5f;
const float originalHeight = generatorChunkData.heightMap->getData (x, z);
FindData result;
if (find (Vector2d (worldX, worldZ), width_2, result))
{
const float distanceToCenter = fabsf (result.distanceToCenter);
const float desiredHeight = result.height;
if (WithinRangeInclusiveInclusive (0.f, distanceToCenter, width_2 * (1.f - getFeatherDistance ())))
{
if(!m_hasFixedHeights)
{
generatorChunkData.heightMap->setData (x, z, desiredHeight);
}
else
{
// ramped road affector using fixed heights
generatorChunkData.heightMap->setData (x,z, getRampedHeight(worldX,worldZ,originalHeight));
}
//-- clear the flora
generatorChunkData.floraStaticCollidableMap->setData (x, z, generatorChunkData.floraGroup->getDefaultFlora ());
generatorChunkData.floraStaticNonCollidableMap->setData (x, z, generatorChunkData.floraGroup->getDefaultFlora ());
generatorChunkData.floraDynamicNearMap->setData (x, z, generatorChunkData.radialGroup->getDefaultRadial ());
generatorChunkData.floraDynamicFarMap->setData (x, z, generatorChunkData.radialGroup->getDefaultRadial ());
}
else
{
//-- height
const float t = distanceToCenter / width_2;
DEBUG_FATAL (t < 0.f || t > 1.f, ("t is out of range"));
if(!m_hasFixedHeights)
{
generatorChunkData.heightMap->setData (x, z, linearInterpolate (desiredHeight, originalHeight, t));
}
else
{
// ramped road affector using fixed heights
generatorChunkData.heightMap->setData (x, z, getRampedHeight(worldX,worldZ,originalHeight));
}
}
if (WithinRangeInclusiveInclusive (0.f, distanceToCenter, width_2 * (1.f - getFeatherDistanceShader ())))
{
//-- set the shader
if (m_cachedFamilyId != m_familyId)
{
m_cachedFamilyId = m_familyId;
m_cachedSgi = generatorChunkData.shaderGroup->chooseShader (m_familyId);
}
FastRandomGenerator randomGenerator(CoordinateHash::hashTuple(worldX, worldZ));
ShaderGroup::Info sgi = m_cachedSgi;
sgi.setChildChoice (randomGenerator.randomFloat());
generatorChunkData.shaderMap->setData (x, z, sgi);
}
}
}
}
}
//-------------------------------------------------------------------
float AffectorRoad::getRampedHeight (const float worldX, const float worldZ,const float terrainHeight) const
{
if (!m_extent.isWithin (worldX, worldZ))
return -100.f;
const float widthSquared = sqr (m_width/2.0f);
float distanceSquared = widthSquared;
int foundIndex = -1;
//-- first, scan how far we are from the points
{
const int n = m_pointList.getNumberOfElements ();
int i;
for (i = 0; i < n; ++i)
{
const float x = m_pointList [i].x;
const float y = m_pointList [i].y;
const float thisDistanceSquared = sqr (worldX - x) + sqr (worldZ - y);
if (thisDistanceSquared < distanceSquared)
{
distanceSquared = thisDistanceSquared;
foundIndex = i;
}
}
}
//-- next, scan each line
{
const int n = m_pointList.getNumberOfElements () - 1;
int i;
for (i = 0; i < n; ++i)
{
const float x1 = m_pointList [i].x;
const float y1 = m_pointList [i].y; //lint !e578 //-- hides y1 (double)
const float x2 = m_pointList [i + 1].x;
const float y2 = m_pointList [i + 1].y;
const float u = ((worldX - x1) * (x2 - x1) + (worldZ - y1) * (y2 - y1)) / (sqr (x2 - x1) + sqr (y2 - y1));
if (u >= 0 && u <= 1)
{
const float x = x1 + u * (x2 - x1);
const float y = y1 + u * (y2 - y1);
const float thisDistanceSquared = sqr (worldX - x) + sqr (worldZ - y);
if (thisDistanceSquared < distanceSquared)
{
distanceSquared = thisDistanceSquared;
foundIndex = i;
}
}
}
}
if (distanceSquared < widthSquared)
{
DEBUG_FATAL(foundIndex == -1,("AffectorRoad::getRampedHeight - foundIndex is -1"));
float height = 0.0f;
// start feathering
float featherMultiplier = 1.0f;
const float newFeatherDistance = (m_width/2.0f) * (1.f - getFeatherDistance ());
const float newFeatherDistanceSquared = sqr (newFeatherDistance);
if (distanceSquared >= newFeatherDistanceSquared)
{
featherMultiplier = 1.f - (sqrt (distanceSquared) - newFeatherDistance) / (m_width/2.0f - newFeatherDistance);
const Feather feather(getFeatherFunction());
featherMultiplier=feather.feather(0.f, 1.f, featherMultiplier);
}
// end feathering
const float startHeight = m_heightList[foundIndex];
if(foundIndex != m_pointList.getNumberOfElements() - 1)
{
// project the world point onto the line between the control points and interp for the height
const Vector2d position(worldX,worldZ);
const float endHeight = m_heightList[foundIndex + 1];
const Vector2d p1(m_pointList [foundIndex].x,m_pointList [foundIndex].y);
const Vector2d p2(m_pointList [foundIndex+1].x,m_pointList [foundIndex+1].y);
const float totalDistance = p1.magnitudeBetween(p2);
const Line2d line (p1,p2);
const float distToLine = line.computeDistanceTo(position);
const float realDistToPoint1 = p1.magnitudeBetween(position);
const float realDistToPoint2 = p2.magnitudeBetween(position);
const float projectedDistToPoint1 = sqrt(sqr(realDistToPoint1) - sqr(distToLine));
const float projectedDistToPoint2 = sqrt(sqr(realDistToPoint2) - sqr(distToLine));
if(totalDistance != 0.0f && projectedDistToPoint1 <= totalDistance && projectedDistToPoint2 <= totalDistance)
{
height = startHeight + (projectedDistToPoint1/totalDistance) * (endHeight - startHeight);
}
else
{
height = startHeight;
}
}
else
{
height = startHeight;
}
// don't build canyons or ridges due to feathering to 0 height
const float delta = height - terrainHeight;
height = terrainHeight + (delta * featherMultiplier);
return height;
}
return -100.f;
}
void AffectorRoad::_legacyAffect (const float worldX, const float worldZ, const int x, const int z, const float amount, const TerrainGenerator::GeneratorChunkData& generatorChunkData) const
{
if (!isEnabled ())
return;
if (amount > 0.f)
{
if (m_extent.isWithin (worldX, worldZ))
{
const float width_2 = m_width * 0.5f;
const float originalHeight = generatorChunkData.heightMap->getData (x, z);
FindData result;
if (find (Vector2d (worldX, worldZ), width_2, result))
{
const float distanceToCenter = fabsf (result.distanceToCenter);
const float desiredHeight = result.height;
if (WithinRangeInclusiveInclusive (0.f, distanceToCenter, width_2 * (1.f - getFeatherDistance ())))
{
generatorChunkData.heightMap->setData (x, z, desiredHeight);
//-- clear the flora
generatorChunkData.floraStaticCollidableMap->setData (x, z, generatorChunkData.floraGroup->getDefaultFlora ());
generatorChunkData.floraStaticNonCollidableMap->setData (x, z, generatorChunkData.floraGroup->getDefaultFlora ());
generatorChunkData.floraDynamicNearMap->setData (x, z, generatorChunkData.radialGroup->getDefaultRadial ());
generatorChunkData.floraDynamicFarMap->setData (x, z, generatorChunkData.radialGroup->getDefaultRadial ());
}
else
{
//-- height
const float t = distanceToCenter / width_2;
DEBUG_FATAL (t < 0.f || t > 1.f, ("t is out of range"));
generatorChunkData.heightMap->setData (x, z, linearInterpolate (desiredHeight, originalHeight, t));
}
if (WithinRangeInclusiveInclusive (0.f, distanceToCenter, width_2 * (1.f - getFeatherDistanceShader ())))
{
//-- set the shader
if (m_cachedFamilyId != m_familyId)
{
m_cachedFamilyId = m_familyId;
m_cachedSgi = generatorChunkData.shaderGroup->chooseShader (m_familyId);
}
ShaderGroup::Info sgi = m_cachedSgi;
sgi.setChildChoice (generatorChunkData.m_legacyRandomGenerator->randomReal (0.0f, 1.0f));
generatorChunkData.shaderMap->setData (x, z, sgi);
}
}
}
}
}
//-------------------------------------------------------------------
void AffectorRoad::load (Iff& iff)
{
switch (iff.getCurrentName ())
{
case TAG_0000:
load_0000 (iff);
break;
case TAG_0001:
load_0001 (iff);
break;
case TAG_0002:
load_0002 (iff);
break;
case TAG_0003:
load_0003 (iff);
break;
case TAG_0004:
load_0004 (iff);
break;
case TAG_0005:
load_0005 (iff);
break;
case TAG_0006:
load_0006 (iff);
break;
default:
{
char tagBuffer [5];
ConvertTagToString (iff.getCurrentName (), tagBuffer);
char buffer [128];
iff.formatLocation (buffer, sizeof (buffer));
DEBUG_FATAL (true, ("invalid AffectorRoad version %s/%s", buffer, tagBuffer));
}
break;
}
recalculate ();
}
//-------------------------------------------------------------------
void AffectorRoad::load_0000 (Iff& iff)
{
iff.enterForm (TAG_0000);
//-- load the base data
LayerItem::load (iff);
//-- load specific data
iff.enterChunk (TAG_DATA);
iff.exitChunk (TAG_DATA);
iff.exitForm (TAG_0000);
}
//-------------------------------------------------------------------
void AffectorRoad::load_0001 (Iff& iff)
{
iff.enterForm (TAG_0001);
//-- load the base data
LayerItem::load (iff);
//-- load specific data
iff.enterChunk (TAG_DATA);
Vector2d newStart;
newStart.x = iff.read_float ();
newStart.y = iff.read_float ();
addPoint (newStart);
Vector2d newEnd;
newEnd.x = iff.read_float ();
newEnd.y = iff.read_float ();
addPoint (newEnd);
setWidth (iff.read_float ());
iff.exitChunk (TAG_DATA);
iff.exitForm (TAG_0001);
}
//-------------------------------------------------------------------
void AffectorRoad::load_0002 (Iff& iff)
{
iff.enterForm (TAG_0002);
//-- load the base data
LayerItem::load (iff);
//-- load specific data
iff.enterForm (TAG_DATA);
m_heightData.load (iff);
iff.enterChunk (TAG_DATA);
Vector2d newStart;
newStart.x = iff.read_float ();
newStart.y = iff.read_float ();
addPoint (newStart);
Vector2d newEnd;
newEnd.x = iff.read_float ();
newEnd.y = iff.read_float ();
addPoint (newEnd);
setWidth (iff.read_float ());
iff.exitChunk (TAG_DATA);
iff.exitForm (TAG_DATA);
iff.exitForm (TAG_0002);
}
//-------------------------------------------------------------------
void AffectorRoad::load_0003 (Iff& iff)
{
iff.enterForm (TAG_0003);
//-- load the base data
LayerItem::load (iff);
//-- load specific data
iff.enterForm (TAG_DATA);
m_heightData.load (iff);
iff.enterChunk (TAG_DATA);
Vector2d newStart;
newStart.x = iff.read_float ();
newStart.y = iff.read_float ();
addPoint (newStart);
Vector2d newEnd;
newEnd.x = iff.read_float ();
newEnd.y = iff.read_float ();
addPoint (newEnd);
setWidth (iff.read_float ());
setFamilyId (iff.read_int32 ());
setFeatherFunction (static_cast<TerrainGeneratorFeatherFunction> (iff.read_int32 ()));
const float newFeatherDistance = clamp (0.f, iff.read_float (), 1.f);
setFeatherDistance (newFeatherDistance);
setFeatherFunctionShader (getFeatherFunction ());
setFeatherDistanceShader (getFeatherDistance ());
iff.exitChunk (TAG_DATA);
iff.exitForm (TAG_DATA);
iff.exitForm (TAG_0003);
}
//-------------------------------------------------------------------
void AffectorRoad::load_0004 (Iff& iff)
{
iff.enterForm (TAG_0004);
//-- load the base data
LayerItem::load (iff);
//-- load specific data
iff.enterForm (TAG_DATA);
m_heightData.load (iff);
iff.enterChunk (TAG_DATA);
const int n = iff.read_int32 ();
int i;
for (i = 0; i < n; ++i)
{
Vector2d point;
point.x = iff.read_float ();
point.y = iff.read_float ();
addPoint (point);
}
setWidth (iff.read_float ());
setFamilyId (iff.read_int32 ());
setFeatherFunction (static_cast<TerrainGeneratorFeatherFunction> (iff.read_int32 ()));
const float newFeatherDistance = clamp (0.f, iff.read_float (), 1.f);
setFeatherDistance (newFeatherDistance);
setFeatherFunctionShader (getFeatherFunction ());
setFeatherDistanceShader (getFeatherDistance ());
iff.exitChunk (TAG_DATA);
iff.exitForm (TAG_DATA);
iff.exitForm (TAG_0004);
}
//-------------------------------------------------------------------
void AffectorRoad::load_0005 (Iff& iff)
{
iff.enterForm (TAG_0005);
//-- load the base data
LayerItem::load (iff);
//-- load specific data
iff.enterForm (TAG_DATA);
m_heightData.load (iff);
iff.enterChunk (TAG_DATA);
const int n = iff.read_int32 ();
int i;
for (i = 0; i < n; ++i)
{
Vector2d point;
point.x = iff.read_float ();
point.y = iff.read_float ();
addPoint (point);
}
setWidth (iff.read_float ());
setFamilyId (iff.read_int32 ());
setFeatherFunction (static_cast<TerrainGeneratorFeatherFunction> (iff.read_int32 ()));
const float newFeatherDistance = clamp (0.f, iff.read_float (), 1.f);
setFeatherDistance (newFeatherDistance);
setFeatherFunctionShader (static_cast<TerrainGeneratorFeatherFunction> (iff.read_int32 ()));
const float newFeatherDistanceShader = clamp (0.f, iff.read_float (), 1.f);
setFeatherDistanceShader (newFeatherDistanceShader);
iff.exitChunk (TAG_DATA);
iff.exitForm (TAG_DATA);
iff.exitForm (TAG_0005);
}
//-------------------------------------------------------------------
void AffectorRoad::load_0006 (Iff& iff)
{
iff.enterForm (TAG_0006);
//-- load the base data
LayerItem::load (iff);
//-- load specific data
iff.enterForm (TAG_DATA);
m_heightData.load (iff);
iff.enterChunk (TAG_DATA);
int n = iff.read_int32 ();
int i;
for (i = 0; i < n; ++i)
{
Vector2d point;
point.x = iff.read_float ();
point.y = iff.read_float ();
addPoint (point);
}
n = iff.read_int32 ();
for(i = 0; i < n; ++i)
{
m_heightList.add(iff.read_float());
}
setWidth (iff.read_float ());
setFamilyId (iff.read_int32 ());
setFeatherFunction (static_cast<TerrainGeneratorFeatherFunction> (iff.read_int32 ()));
const float newFeatherDistance = clamp (0.f, iff.read_float (), 1.f);
setFeatherDistance (newFeatherDistance);
setFeatherFunctionShader (static_cast<TerrainGeneratorFeatherFunction> (iff.read_int32 ()));
const float newFeatherDistanceShader = clamp (0.f, iff.read_float (), 1.f);
setFeatherDistanceShader (newFeatherDistanceShader);
setHasFixedHeights(iff.read_int32() != 0);
iff.exitChunk (TAG_DATA);
iff.exitForm (TAG_DATA);
iff.exitForm (TAG_0006);
}
//-------------------------------------------------------------------
void AffectorRoad::save (Iff& iff) const
{
iff.insertForm (TAG_0006);
//-- save the base
LayerItem::save (iff);
//-- save specific data
iff.insertForm (TAG_DATA);
m_heightData.save (iff);
iff.insertChunk (TAG_DATA);
iff.insertChunkData (m_pointList.getNumberOfElements ());
int i;
for (i = 0; i < m_pointList.getNumberOfElements (); ++i)
{
iff.insertChunkData (getPoint (i).x);
iff.insertChunkData (getPoint (i).y);
}
iff.insertChunkData (m_heightList.getNumberOfElements ());
for (i = 0; i < m_heightList.getNumberOfElements (); ++i)
{
iff.insertChunkData (m_heightList[i]);
}
iff.insertChunkData (getWidth ());
iff.insertChunkData (getFamilyId ());
iff.insertChunkData (static_cast<int32> (getFeatherFunction ()));
iff.insertChunkData (getFeatherDistance ());
iff.insertChunkData (static_cast<int32> (getFeatherFunctionShader ()));
iff.insertChunkData (getFeatherDistanceShader ());
iff.insertChunkData (m_hasFixedHeights ? static_cast<int32> (1) : static_cast<int32> (0));
iff.exitChunk (TAG_DATA);
iff.exitForm (TAG_DATA);
iff.exitForm (TAG_0006);
}
//-------------------------------------------------------------------
@@ -0,0 +1,120 @@
//===================================================================
//
// AffectorRoad.h
// asommers 9-30-2000
//
// copyright 2000, verant interactive
//
//===================================================================
#ifndef INCLUDED_AffectorRoad_H
#define INCLUDED_AffectorRoad_H
//===================================================================
#include "sharedTerrain/Affector.h"
//===================================================================
class AffectorRoad : public AffectorBoundaryPoly
{
public:
AffectorRoad ();
virtual ~AffectorRoad ();
virtual void prepare ();
virtual void affect (float worldX, float worldZ, int x, int z, float amount, const TerrainGenerator::GeneratorChunkData& generatorChunkData) const;
virtual void load (Iff& iff);
virtual void save (Iff& iff) const;
virtual bool affectsHeight () const;
virtual bool affectsShader () const;
virtual unsigned getAffectedMaps() const;
virtual void createHeightData ();
int getFamilyId () const;
void setFamilyId (int newFamilyId);
TerrainGeneratorFeatherFunction getFeatherFunctionShader () const;
void setFeatherFunctionShader (TerrainGeneratorFeatherFunction newFeatherFunction);
float getFeatherDistanceShader () const;
void setFeatherDistanceShader (float newFeatherDistance);
float getRampedHeight (const float worldX, const float worldZ,const float terrainHeight) const;
bool getHasFixedHeights() const;
void setHasFixedHeights(const bool newVal);
void createInitialHeightList ();
void clearHeightList ();
const ArrayList<float>& getHeightList () const;
void copyHeightList (const ArrayList<float>& newHeightList);
private:
void _legacyAffect (const float worldX, const float worldZ, const int x, const int z, const float amount, const TerrainGenerator::GeneratorChunkData& generatorChunkData) const;
void load_0000 (Iff& iff);
void load_0001 (Iff& iff);
void load_0002 (Iff& iff);
void load_0003 (Iff& iff);
void load_0004 (Iff& iff);
void load_0005 (Iff& iff);
void load_0006 (Iff& iff);
private:
AffectorRoad (const AffectorRoad& rhs);
AffectorRoad& operator= (const AffectorRoad& rhs);
private:
mutable int m_cachedFamilyId;
mutable ShaderGroup::Info m_cachedSgi;
//-- accessible
int m_familyId;
TerrainGeneratorFeatherFunction m_featherFunctionShader;
float m_featherDistanceShader;
bool m_hasFixedHeights;
ArrayList<float> m_heightList;
};
//-------------------------------------------------------------------
inline int AffectorRoad::getFamilyId () const
{
return m_familyId;
}
//-------------------------------------------------------------------
inline TerrainGeneratorFeatherFunction AffectorRoad::getFeatherFunctionShader () const
{
return m_featherFunctionShader;
}
//-------------------------------------------------------------------
inline float AffectorRoad::getFeatherDistanceShader () const
{
return m_featherDistanceShader;
}
//-------------------------------------------------------------------
inline bool AffectorRoad::getHasFixedHeights () const
{
return m_hasFixedHeights;
}
//-------------------------------------------------------------------
inline const ArrayList<float>& AffectorRoad::getHeightList () const
{
return m_heightList;
}
//===================================================================
#endif
@@ -0,0 +1,431 @@
//
// AffectorShader.cpp
// asommers 9-30-2000
//
// copyright 2000, verant interactive
//
//-------------------------------------------------------------------
#include "sharedTerrain/FirstSharedTerrain.h"
#include "sharedTerrain/AffectorShader.h"
#include "sharedTerrain/Affector.h"
#include "sharedTerrain/CoordinateHash.h"
#include "sharedRandom/FastRandomGenerator.h"
#include "sharedFile/Iff.h"
//-------------------------------------------------------------------
//
// AffectorShaderConstant
//
AffectorShaderConstant::AffectorShaderConstant () :
TerrainGenerator::Affector (TAG_ASCN, TGAT_shaderConstant),
m_cachedFamilyId (-1),
m_cachedSgi (),
m_cachedFeatherClamp (0.f),
m_familyId (0),
m_useFeatherClampOverride (false),
m_featherClampOverride (1.f)
{
}
//-------------------------------------------------------------------
AffectorShaderConstant::~AffectorShaderConstant ()
{
}
//-------------------------------------------------------------------
void AffectorShaderConstant::setFamilyId (const int familyId)
{
m_familyId = familyId;
}
//-------------------------------------------------------------------
void AffectorShaderConstant::setUseFeatherClampOverride (const bool useFeatherClampOverride)
{
m_useFeatherClampOverride = useFeatherClampOverride;
}
//-------------------------------------------------------------------
void AffectorShaderConstant::setFeatherClampOverride (const float featherClampOverride)
{
m_featherClampOverride = featherClampOverride;
}
//-------------------------------------------------------------------
bool AffectorShaderConstant::affectsShader () const
{
return true;
}
//-------------------------------------------------------------------
void AffectorShaderConstant::prepare ()
{
m_cachedFamilyId = -1;
}
//-------------------------------------------------------------------
unsigned AffectorShaderConstant::getAffectedMaps() const
{
return TGM_shader;
}
//-------------------------------------------------------------------
void AffectorShaderConstant::affect (const float worldX, const float worldZ, const int x, const int z, const float amount, const TerrainGenerator::GeneratorChunkData& generatorChunkData) const
{
if (generatorChunkData.m_legacyRandomGenerator)
{
_legacyAffect(worldX, worldZ, x, z, amount, generatorChunkData);
return;
}
if (amount > 0.f)
{
if (m_cachedFamilyId != m_familyId)
{
m_cachedFamilyId = m_familyId;
m_cachedSgi = generatorChunkData.shaderGroup->chooseShader (m_familyId);
m_cachedFeatherClamp = generatorChunkData.shaderGroup->getFamilyFeatherClamp (m_familyId);
}
const float featherClamp = m_useFeatherClampOverride ? m_featherClampOverride : m_cachedFeatherClamp;
FastRandomGenerator randomGenerator(CoordinateHash::hashTuple(worldX, worldZ));
#if 1
if (amount >= featherClamp)
#else
//-- this causes better looking terrain, but more shader blends
if (randomGenerator.randomFloat() <= amount * featherClamp)
#endif
{
ShaderGroup::Info sgi = m_cachedSgi;
sgi.setChildChoice(randomGenerator.randomFloat());
generatorChunkData.shaderMap->setData (x, z, sgi);
}
}
}
void AffectorShaderConstant::_legacyAffect (const float /*worldX*/, const float /*worldZ*/, const int x, const int z, const float amount, const TerrainGenerator::GeneratorChunkData& generatorChunkData) const
{
if (amount > 0.f)
{
if (m_cachedFamilyId != m_familyId)
{
m_cachedFamilyId = m_familyId;
m_cachedSgi = generatorChunkData.shaderGroup->chooseShader (m_familyId);
m_cachedFeatherClamp = generatorChunkData.shaderGroup->getFamilyFeatherClamp (m_familyId);
}
const float featherClamp = m_useFeatherClampOverride ? m_featherClampOverride : m_cachedFeatherClamp;
#if 1
if (amount >= featherClamp)
#else
//-- this causes better looking terrain, but more shader blends
if (generatorChunkData.randomGenerator.randomReal (0.f, 1.f) <= amount * featherClamp)
#endif
{
ShaderGroup::Info sgi = m_cachedSgi;
sgi.setChildChoice (generatorChunkData.m_legacyRandomGenerator->randomReal (0.0f, 1.0f));
generatorChunkData.shaderMap->setData (x, z, sgi);
}
}
}
//-------------------------------------------------------------------
void AffectorShaderConstant::load (Iff& iff)
{
switch (iff.getCurrentName ())
{
case TAG_0000:
load_0000 (iff);
break;
case TAG_0001:
load_0001 (iff);
break;
default:
{
char tagBuffer [5];
ConvertTagToString (iff.getCurrentName (), tagBuffer);
char buffer [128];
iff.formatLocation (buffer, sizeof (buffer));
DEBUG_FATAL (true, ("invalid AffectorShaderConstant version %s/%s", buffer, tagBuffer));
}
break;
}
}
//-------------------------------------------------------------------
void AffectorShaderConstant::load_0000 (Iff& iff)
{
iff.enterForm (TAG_0000);
//-- load the base data
LayerItem::load (iff);
//-- load specific data
iff.enterChunk (TAG_DATA);
setFamilyId (iff.read_int32 ());
iff.exitChunk (TAG_DATA);
iff.exitForm (TAG_0000);
}
//-------------------------------------------------------------------
void AffectorShaderConstant::load_0001 (Iff& iff)
{
iff.enterForm (TAG_0001);
//-- load the base data
LayerItem::load (iff);
//-- load specific data
iff.enterChunk (TAG_DATA);
setFamilyId (iff.read_int32 ());
setUseFeatherClampOverride (iff.read_int32 () != 0);
setFeatherClampOverride (iff.read_float ());
iff.exitChunk (TAG_DATA);
iff.exitForm (TAG_0001);
}
//-------------------------------------------------------------------
void AffectorShaderConstant::save (Iff& iff) const
{
iff.insertForm (TAG_0001);
//-- save the base
LayerItem::save (iff);
//-- save specific data
iff.insertChunk (TAG_DATA);
iff.insertChunkData (getFamilyId ());
iff.insertChunkData (getUseFeatherClampOverride () ? static_cast<int32> (1) : static_cast<int32> (0));
iff.insertChunkData (getFeatherClampOverride ());
iff.exitChunk (TAG_DATA);
iff.exitForm (TAG_0001);
}
//-------------------------------------------------------------------
//
// AffectorShaderReplace
//
AffectorShaderReplace::AffectorShaderReplace () :
TerrainGenerator::Affector (TAG_ASRP, TGAT_shaderReplace),
m_cachedFamilyId (-1),
m_cachedSgi (),
m_cachedFeatherClamp (0.f),
m_sourceFamilyId (0),
m_destinationFamilyId (0),
m_useFeatherClampOverride (false),
m_featherClampOverride (1.f)
{
}
//-------------------------------------------------------------------
AffectorShaderReplace::~AffectorShaderReplace ()
{
}
//-------------------------------------------------------------------
void AffectorShaderReplace::setSourceFamilyId (const int sourceFamilyId)
{
m_sourceFamilyId = sourceFamilyId;
}
//-------------------------------------------------------------------
void AffectorShaderReplace::setDestinationFamilyId (const int destinationFamilyId)
{
m_destinationFamilyId = destinationFamilyId;
}
//-------------------------------------------------------------------
void AffectorShaderReplace::setUseFeatherClampOverride (const bool useFeatherClampOverride)
{
m_useFeatherClampOverride = useFeatherClampOverride;
}
//-------------------------------------------------------------------
void AffectorShaderReplace::setFeatherClampOverride (const float featherClampOverride)
{
m_featherClampOverride = featherClampOverride;
}
//-------------------------------------------------------------------
bool AffectorShaderReplace::affectsShader () const
{
return true;
}
//-------------------------------------------------------------------
void AffectorShaderReplace::prepare ()
{
m_cachedFamilyId = -1;
}
//-------------------------------------------------------------------
unsigned AffectorShaderReplace::getAffectedMaps() const
{
return TGM_shader;
}
//-------------------------------------------------------------------
void AffectorShaderReplace::affect (const float /*worldX*/, const float /*worldZ*/, const int x, const int z, const float amount, const TerrainGenerator::GeneratorChunkData& generatorChunkData) const
{
if (amount > 0.f)
{
const ShaderGroup::Info sgi = generatorChunkData.shaderMap->getData (x, z);
if (sgi.getFamilyId () == m_sourceFamilyId)
{
if (m_cachedFamilyId != m_destinationFamilyId)
{
m_cachedFamilyId = m_destinationFamilyId;
m_cachedSgi = generatorChunkData.shaderGroup->chooseShader (m_destinationFamilyId);
m_cachedFeatherClamp = generatorChunkData.shaderGroup->getFamilyFeatherClamp (m_destinationFamilyId);
}
const float featherClamp = m_useFeatherClampOverride ? m_featherClampOverride : m_cachedFeatherClamp;
#if 1
if (amount >= featherClamp)
#else
//-- this causes better looking terrain, but more shader blends
if (generatorChunkData.randomGenerator.randomReal (0.f, 1.f) <= amount * featherClamp)
#endif
{
m_cachedSgi.setChildChoice (sgi.getChildChoice ());
generatorChunkData.shaderMap->setData (x, z, m_cachedSgi);
}
}
}
}
//-------------------------------------------------------------------
void AffectorShaderReplace::load (Iff& iff)
{
switch (iff.getCurrentName ())
{
case TAG_0000:
load_0000 (iff);
break;
case TAG_0001:
load_0001 (iff);
break;
default:
{
char tagBuffer [5];
ConvertTagToString (iff.getCurrentName (), tagBuffer);
char buffer [128];
iff.formatLocation (buffer, sizeof (buffer));
DEBUG_FATAL (true, ("invalid AffectorShaderReplace version %s/%s", buffer, tagBuffer));
}
break;
}
}
//-------------------------------------------------------------------
void AffectorShaderReplace::load_0000 (Iff& iff)
{
iff.enterForm (TAG_0000);
//-- load the base data
LayerItem::load (iff);
//-- load specific data
iff.enterChunk (TAG_DATA);
setSourceFamilyId (iff.read_int32 ());
setDestinationFamilyId (iff.read_int32 ());
iff.exitChunk (TAG_DATA);
iff.exitForm (TAG_0000);
}
//-------------------------------------------------------------------
void AffectorShaderReplace::load_0001 (Iff& iff)
{
iff.enterForm (TAG_0001);
//-- load the base data
LayerItem::load (iff);
//-- load specific data
iff.enterChunk (TAG_DATA);
setSourceFamilyId (iff.read_int32 ());
setDestinationFamilyId (iff.read_int32 ());
setUseFeatherClampOverride (iff.read_int32 () != 0);
setFeatherClampOverride (iff.read_float ());
iff.exitChunk (TAG_DATA);
iff.exitForm (TAG_0001);
}
//-------------------------------------------------------------------
void AffectorShaderReplace::save (Iff& iff) const
{
iff.insertForm (TAG_0001);
//-- save the base
LayerItem::save (iff);
//-- save specific data
iff.insertChunk (TAG_DATA);
iff.insertChunkData (getSourceFamilyId ());
iff.insertChunkData (getDestinationFamilyId ());
iff.insertChunkData (getUseFeatherClampOverride () ? static_cast<int32> (1) : static_cast<int32> (0));
iff.insertChunkData (getFeatherClampOverride ());
iff.exitChunk (TAG_DATA);
iff.exitForm (TAG_0001);
}
//-------------------------------------------------------------------
@@ -0,0 +1,168 @@
//===================================================================
//
// AffectorShader.h
// asommers 9-30-2000
//
// copyright 2000, verant interactive
//
//===================================================================
#ifndef INCLUDED_AffectorShader_H
#define INCLUDED_AffectorShader_H
//===================================================================
#include "sharedTerrain/TerrainGenerator.h"
//===================================================================
class AffectorShaderConstant : public TerrainGenerator::Affector
{
private:
//-- not accessible
mutable int m_cachedFamilyId;
mutable ShaderGroup::Info m_cachedSgi;
mutable float m_cachedFeatherClamp;
//-- accessible
int m_familyId;
bool m_useFeatherClampOverride;
float m_featherClampOverride;
private:
void load_0000 (Iff& iff);
void load_0001 (Iff& iff);
private:
AffectorShaderConstant (const AffectorShaderConstant& rhs);
AffectorShaderConstant& operator= (const AffectorShaderConstant& rhs);
void _legacyAffect (const float /*worldX*/, const float /*worldZ*/, const int x, const int z, const float amount, const TerrainGenerator::GeneratorChunkData& generatorChunkData) const;
public:
AffectorShaderConstant ();
virtual ~AffectorShaderConstant ();
virtual void prepare ();
virtual void affect (float worldX, float worldZ, int x, int z, float amount, const TerrainGenerator::GeneratorChunkData& generatorChunkData) const;
virtual void load (Iff& iff);
virtual void save (Iff& iff) const;
virtual bool affectsShader () const;
virtual unsigned getAffectedMaps() const;
int getFamilyId () const;
void setFamilyId (int newFamilyId);
bool getUseFeatherClampOverride () const;
void setUseFeatherClampOverride (bool useFeatherClampOverride);
float getFeatherClampOverride () const;
void setFeatherClampOverride (float featherClampOverride);
};
//-------------------------------------------------------------------
inline int AffectorShaderConstant::getFamilyId () const
{
return m_familyId;
}
//-------------------------------------------------------------------
inline bool AffectorShaderConstant::getUseFeatherClampOverride () const
{
return m_useFeatherClampOverride;
}
//-------------------------------------------------------------------
inline float AffectorShaderConstant::getFeatherClampOverride () const
{
return m_featherClampOverride;
}
//===================================================================
class AffectorShaderReplace : public TerrainGenerator::Affector
{
private:
//-- not accessible
mutable int m_cachedFamilyId;
mutable ShaderGroup::Info m_cachedSgi;
mutable float m_cachedFeatherClamp;
//-- accessible
int m_sourceFamilyId;
int m_destinationFamilyId;
bool m_useFeatherClampOverride;
float m_featherClampOverride;
private:
void load_0000 (Iff& iff);
void load_0001 (Iff& iff);
private:
AffectorShaderReplace (const AffectorShaderReplace& rhs);
AffectorShaderReplace& operator= (const AffectorShaderReplace& rhs);
public:
AffectorShaderReplace ();
virtual ~AffectorShaderReplace ();
virtual void prepare ();
virtual void affect (float worldX, float worldZ, int x, int z, float amount, const TerrainGenerator::GeneratorChunkData& generatorChunkData) const;
virtual void load (Iff& iff);
virtual void save (Iff& iff) const;
virtual bool affectsShader () const;
virtual unsigned getAffectedMaps() const;
int getSourceFamilyId () const;
void setSourceFamilyId (int newSourceFamilyId);
int getDestinationFamilyId () const;
void setDestinationFamilyId (int newDestinationFamilyId);
bool getUseFeatherClampOverride () const;
void setUseFeatherClampOverride (bool useFeatherClampOverride);
float getFeatherClampOverride () const;
void setFeatherClampOverride (float featherClampOverride);
};
//-------------------------------------------------------------------
inline int AffectorShaderReplace::getSourceFamilyId () const
{
return m_sourceFamilyId;
}
//-------------------------------------------------------------------
inline int AffectorShaderReplace::getDestinationFamilyId () const
{
return m_destinationFamilyId;
}
//-------------------------------------------------------------------
inline bool AffectorShaderReplace::getUseFeatherClampOverride () const
{
return m_useFeatherClampOverride;
}
//-------------------------------------------------------------------
inline float AffectorShaderReplace::getFeatherClampOverride () const
{
return m_featherClampOverride;
}
//===================================================================
#endif
@@ -0,0 +1,238 @@
//===================================================================
//
// Array2d.h
// asommers 9-11-2000
//
// copyright 2000, verant interactive
//
//--
//
// Array2d abstracts a 2d array of values. When accessing an entry
// in the 2d array, if you specify an out-of-bounds entry, the coordinate
// will clamp
//
//===================================================================
#ifndef INCLUDED_Array2d_H
#define INCLUDED_Array2d_H
//===================================================================
template <class T>
class Array2d
{
private:
int width;
int height;
T* data;
private:
void deallocate ();
private:
Array2d (const Array2d& rhs);
Array2d& operator= (const Array2d& rhs);
public:
Array2d ();
~Array2d ();
int getWidth () const;
int getHeight () const;
bool isEmpty () const;
void allocate (int width, int height);
void allocateAndSet (int width, int height, const T* newData);
void makeZero ();
void makeValue (const T& newValue);
void makeCopy (const Array2d<T>& rhs);
const T* getData () const;
const T& getData (int x, int z) const;
T& getData (int x, int z);
void setData (int x, int z, const T& newData);
};
//===================================================================
template <class T>
Array2d<T>::Array2d () :
width (0),
height (0),
data (0)
{
}
//-------------------------------------------------------------------
template <class T>
Array2d<T>::~Array2d ()
{
width = height = 0;
deallocate ();
} //lint !e1740 // pointer member data not freed
//-------------------------------------------------------------------
template <class T>
int Array2d<T>::getWidth () const
{
return width;
}
//-------------------------------------------------------------------
template <class T>
int Array2d<T>::getHeight () const
{
return height;
}
//-------------------------------------------------------------------
template <class T>
bool Array2d<T>::isEmpty () const
{
return width == 0 || height == 0;
}
//-------------------------------------------------------------------
template <class T>
void Array2d<T>::deallocate ()
{
if (data)
{
delete [] data;
data = 0;
}
}
//-------------------------------------------------------------------
template <class T>
void Array2d<T>::allocate (int newWidth, int newHeight)
{
DEBUG_FATAL (newWidth <= 0, ("newWidth <= 0"));
DEBUG_FATAL (newHeight <= 0, ("newHeight <= 0"));
if (newWidth > width || newHeight > height)
{
deallocate ();
width = newWidth;
height = newHeight;
data = new T [newWidth * newHeight]; //lint !e737 //-- sizeof
}
}
//-------------------------------------------------------------------
template <class T>
void Array2d<T>::allocateAndSet (int newWidth, int newHeight, const T* newData)
{
NOT_NULL (newData);
allocate (newWidth, newHeight);
NOT_NULL (data);
memcpy (data, newData, width * height * sizeof (T)); //lint !e737 //-- sizeof
}
//-------------------------------------------------------------------
template <class T>
const T* Array2d<T>::getData () const
{
return data;
}
//-------------------------------------------------------------------
template <class T>
const T& Array2d<T>::getData (int x, int z) const
{
NOT_NULL (data);
DEBUG_FATAL (isEmpty (), ("Array2d<T> is empty"));
DEBUG_FATAL (x < 0 || x >= width, ("x is out of range"));
DEBUG_FATAL (z < 0 || z >= height, ("z is out of range"));
return data [z * width + x];
}
//-------------------------------------------------------------------
template<class T>
T& Array2d<T>::getData (int x, int z)
{
NOT_NULL (data);
DEBUG_FATAL (isEmpty (), ("Array2d<T> is empty"));
DEBUG_FATAL (x < 0 || x >= width, ("x is out of range"));
DEBUG_FATAL (z < 0 || z >= height, ("z is out of range"));
return data [z * width + x];
}
//-------------------------------------------------------------------
template <class T>
void Array2d<T>::setData (int x, int z, const T& newData)
{
NOT_NULL (data);
DEBUG_FATAL (isEmpty (), ("Array2d<T> is empty"));
DEBUG_FATAL (x < 0 || x >= width, ("x is out of range"));
DEBUG_FATAL (z < 0 || z >= height, ("z is out of range"));
data [z * width + x] = newData;
}
//-------------------------------------------------------------------
template <class T>
void Array2d<T>::makeZero ()
{
NOT_NULL (data);
DEBUG_FATAL (isEmpty (), ("Array2d<T> is empty"));
memset (data, 0, width * height * sizeof (T)); //lint !e737 //-- sizeof
}
//-------------------------------------------------------------------
template <class T>
void Array2d<T>::makeValue (const T& newValue)
{
NOT_NULL (data);
DEBUG_FATAL (isEmpty (), ("Array2d<T> is empty"));
int i;
int j;
for (j = 0; j < height; j++)
for (i = 0; i < width; i++)
data [j * width + i] = newValue;
}
//-------------------------------------------------------------------
template <class T>
void Array2d<T>::makeCopy (const Array2d<T>& rhs)
{
DEBUG_FATAL (width != rhs.getWidth (), ("width (%i) != rhs.getWidth (%i)", width, rhs.getWidth ()));
DEBUG_FATAL (height != rhs.getHeight (), ("height (%i) != rhs.getHeight (%i)", height, rhs.getHeight ()));
NOT_NULL (data);
NOT_NULL (rhs.data);
memcpy (data, rhs.data, width * height * sizeof (T)); //lint !e737 //-- sizeof
}
//===================================================================
#endif
@@ -0,0 +1,611 @@
//===================================================================
//
// BitmapGroup.cpp
//
// copyright 2004, sony online entertainment
//
//===================================================================
#include "sharedTerrain/FirstSharedTerrain.h"
#include "sharedTerrain/BitmapGroup.h"
#include "sharedFile/Iff.h"
#include "sharedImage/Image.h"
#include "sharedImage/ImageFormatList.h"
#include <map>
#include <string>
#include <cstdio>
//===================================================================
namespace
{
const Tag TAG_MGRP = TAG (M,G,R,P);
const Tag TAG_MFAM = TAG (M,F,A,M);
}
//===================================================================
//
// BitmapGroup::Family
//
class BitmapGroup::Family
{
public:
explicit Family (int familyId);
~Family ();
const char* getName () const;
void setName (const char* name);
void setBitmapName (const char* name);
const char* getBitmapName() const;
int getFamilyId () const;
void setFamilyId (int familyId);
const Image& getBitmap () const;
Image& getBitmap ();
void loadBitmap(const char* bitmapName);
void loadBitmapByFilename();
void setBitmap(const Image* image);
private:
Family ();
Family (const Family& rhs);
Family& operator= (const Family& rhs);
private:
char* m_name;
char* m_bitmapName;
int m_familyId;
Image* m_bitmap;
};
//-------------------------------------------------------------------
BitmapGroup::Family::Family (int familyId) :
m_name (0),
m_bitmapName (0),
m_familyId (familyId),
m_bitmap(0)
{
}
//-------------------------------------------------------------------
BitmapGroup::Family::~Family ()
{
if(m_name)
{
delete [] m_name;
m_name = 0;
}
if(m_bitmapName)
{
delete [] m_bitmapName;
m_bitmapName = 0;
}
if(m_bitmap)
{
delete m_bitmap;
m_bitmap = 0;
}
}
//-------------------------------------------------------------------
void BitmapGroup::Family::loadBitmap(const char* bitmapName)
{
if(m_bitmap)
{
delete m_bitmap;
m_bitmap = 0;
}
bool valid = false;
char name[256];
sprintf(name,"terrain/%s.tga",bitmapName);
m_bitmap = ImageFormatList::loadImage (name);
if (!m_bitmap)
{
DEBUG_WARNING (true, ("BitmapGroup::Family::loadBitmap - invalid image (%s)",name));
}
else
{
if(!(m_bitmap->getPixelFormat() == Image::PF_w_8))
{
DEBUG_WARNING (true, ("BitmapGroup::Family::loadBitmap %s - m_bitmap->getPixelFormat() returned %d - should be Image::PF_w_8",name,m_bitmap->getPixelFormat()));
}
else
{
valid = true;
}
}
if (!valid)
{
delete m_bitmap;
m_bitmap = 0;
}
else
{
setBitmapName(name);
}
}
//-------------------------------------------------------------------
void BitmapGroup::Family::loadBitmapByFilename()
{
if(m_bitmap)
{
delete m_bitmap;
m_bitmap = 0;
}
bool valid = false;
m_bitmap = ImageFormatList::loadImage (this->m_bitmapName);
if (!m_bitmap)
{
if(!m_bitmapName)
{
DEBUG_WARNING (true, ("BitmapGroup::Family::loadBitmapByFilename() - invalid image - m_bitmapName is NULL"));
}
else
{
DEBUG_WARNING (true, ("BitmapGroup::Family::loadBitmapByFilename() - invalid image - %s",m_bitmapName));
}
}
else
{
if(!(m_bitmap->getPixelFormat() == Image::PF_w_8))
{
DEBUG_WARNING (true, ("BitmapGroup::Family::loadBitmapByFilename() %s - m_bitmap->getPixelFormat() returned %d - should be Image::PF_w_8",this->m_bitmapName,m_bitmap->getPixelFormat()));
}
else
{
valid = true;
}
}
if (!valid)
{
delete m_bitmap;
m_bitmap = 0;
}
}
//-------------------------------------------------------------------
const char* BitmapGroup::Family::getName () const
{
return m_name;
}
//-------------------------------------------------------------------
void BitmapGroup::Family::setName (const char* name)
{
if (m_name)
{
delete [] m_name;
m_name = 0;
}
if (name)
m_name = DuplicateString (name);
}
//-------------------------------------------------------------------
const char* BitmapGroup::Family::getBitmapName() const
{
return m_bitmapName;
}
//-------------------------------------------------------------------
void BitmapGroup::Family::setBitmapName (const char* name)
{
if (m_bitmapName)
{
delete [] m_bitmapName;
m_bitmapName = 0;
}
if (name)
{
m_bitmapName = DuplicateString (name);
}
}
//-------------------------------------------------------------------
void BitmapGroup::Family::setBitmap(const Image* image)
{
if(m_bitmap)
{
delete m_bitmap;
m_bitmap = 0;
}
m_bitmap = (Image*)image;
}
int BitmapGroup::Family::getFamilyId () const
{
return m_familyId;
}
//-------------------------------------------------------------------
void BitmapGroup::Family::setFamilyId (int familyId)
{
m_familyId = familyId;
}
//-------------------------------------------------------------------
const Image& BitmapGroup::Family::getBitmap () const
{
return *m_bitmap;
}
//-------------------------------------------------------------------
Image& BitmapGroup::Family::getBitmap ()
{
return *m_bitmap;
}
BitmapGroup::BitmapGroup () :
m_familyMap (new FamilyMap)
{
}
//-------------------------------------------------------------------
BitmapGroup::~BitmapGroup ()
{
//-- delete family list
reset ();
delete m_familyMap;
m_familyMap = 0;
}
//-------------------------------------------------------------------
void BitmapGroup::load (Iff& iff)
{
//-- delete family list first
reset ();
//-- load data
if (iff.enterForm (TAG_MGRP, true))
{
DEBUG_WARNING (iff.getCurrentName () != TAG_0000, ("BitmapGroup::load - loading old version"));
switch (iff.getCurrentName ())
{
case TAG_0000:
load_0000 (iff);
break;
default:
DEBUG_FATAL (true, ("BitmapGroup::load unknown tag"));
}
iff.exitForm ();
}
}
//-------------------------------------------------------------------
void BitmapGroup::save (Iff& iff) const
{
iff.insertForm (TAG_MGRP);
iff.insertForm (TAG_0000);
for (FamilyMap::iterator iter = m_familyMap->begin (); iter != m_familyMap->end (); ++iter)
{
const Family* family = iter->second;
iff.insertForm (TAG_MFAM);
iff.insertChunk (TAG_DATA);
iff.insertChunkData (static_cast<int32> (family->getFamilyId ()));
iff.insertChunkString (family->getName ());
iff.insertChunkString (family->getBitmapName());
iff.exitChunk ();
iff.exitForm ();
}
iff.exitForm ();
iff.exitForm ();
}
//-------------------------------------------------------------------
void BitmapGroup::reset ()
{
for (FamilyMap::iterator iter = m_familyMap->begin (); iter != m_familyMap->end (); ++iter)
delete iter->second;
m_familyMap->clear ();
}
//-------------------------------------------------------------------
const char* BitmapGroup::getFamilyName (int familyId) const
{
const Family* const family = getFamily (familyId);
return family->getName ();
}
//-------------------------------------------------------------------
void BitmapGroup::setFamilyName (int familyId, const char* name)
{
Family* const family = getFamily (familyId);
family->setName (name);
}
void BitmapGroup::loadFamilyBitmap(int familyId, const char* bitmapName)
{
Family* const family = getFamily(familyId);
family->loadBitmap(bitmapName);
}
//-------------------------------------------------------------------
const Image* BitmapGroup::getFamilyBitmap (int familyId) const
{
const Family* const family = getFamily (familyId);
return &family->getBitmap ();
}
//-------------------------------------------------------------------
Image* BitmapGroup::getFamilyBitmap (int familyId)
{
Family* const family = getFamily (familyId);
return &family->getBitmap ();
}
//-------------------------------------------------------------------
void BitmapGroup::reloadAllFamilyBitmaps()
{
int i;
for(i = 0; i < getNumberOfFamilies(); ++i)
{
const int id = getFamilyId(i);
Family* const family = getFamily(id);
NOT_NULL (family);
family->loadBitmapByFilename();
}
}
//-------------------------------------------------------------------
void BitmapGroup::addFamily (int familyId, const char* name, const char* bitmapName)
{
DEBUG_FATAL (getFamily (familyId) != 0, ("family with id %i already exists", familyId));
Family* family = new Family (familyId);
family->setName (name);
family->setBitmapName(bitmapName);
IGNORE_RETURN (m_familyMap->insert (FamilyMap::value_type (familyId, family)));
}
//-------------------------------------------------------------------
void BitmapGroup::removeFamily (int familyId)
{
FamilyMap::iterator iter = m_familyMap->find (familyId);
DEBUG_FATAL (iter == m_familyMap->end (), ("family with id %i not found", familyId));
Family* family = iter->second;
delete family;
m_familyMap->erase (iter);
}
//-------------------------------------------------------------------
bool BitmapGroup::hasFamily (int familyId) const
{
return getFamily (familyId) != 0;
}
//-------------------------------------------------------------------
bool BitmapGroup::findFamily (const char* name, int& familyId) const
{
const Family* const family = getFamily (name);
if (family)
familyId = family->getFamilyId ();
return family != 0;
}
//-------------------------------------------------------------------
int BitmapGroup::getNumberOfFamilies () const
{
return static_cast<int> (m_familyMap->size ());
}
//-------------------------------------------------------------------
const BitmapGroup::Family* BitmapGroup::getFamily (int familyId) const
{
FamilyMap::const_iterator iter = m_familyMap->find (familyId);
if (iter != m_familyMap->end ())
return iter->second;
return 0;
}
//-------------------------------------------------------------------
BitmapGroup::Family* BitmapGroup::getFamily (int familyId)
{
FamilyMap::iterator iter = m_familyMap->find (familyId);
if (iter != m_familyMap->end ())
return iter->second;
return 0;
}
//-------------------------------------------------------------------
const BitmapGroup::Family* BitmapGroup::getFamily (const char* familyName) const
{
FamilyMap::iterator iter = m_familyMap->begin ();
for (; iter != m_familyMap->end (); ++iter)
{
const Family* const family = iter->second;
if (_stricmp (familyName, family->getName ()) == 0)
return family;
}
return 0;
}
//-------------------------------------------------------------------
BitmapGroup::Family* BitmapGroup::getFamily (const char* familyName)
{
FamilyMap::iterator iter = m_familyMap->begin ();
for (; iter != m_familyMap->end (); ++iter)
{
Family* const family = iter->second;
if (_stricmp (familyName, family->getName ()) == 0)
return family;
}
return 0;
}
//-------------------------------------------------------------------
void BitmapGroup::setFamilyId (int familyIndex, int familyId)
{
VALIDATE_RANGE_INCLUSIVE_EXCLUSIVE (0, familyIndex, getNumberOfFamilies ());
Family* const family = getFamily (familyIndex);
NOT_NULL (family);
family->setFamilyId (familyId);
}
//-------------------------------------------------------------------
void BitmapGroup::load_0000 (Iff& iff)
{
iff.enterForm (TAG_0000);
int n = iff.getNumberOfBlocksLeft ();
int i;
for (i = 0; i < n; i++)
{
iff.enterForm (TAG_MFAM);
iff.enterChunk (TAG_DATA);
int familyId = iff.read_int32 ();
//-- see if family id is already in use
DEBUG_FATAL (getFamily (familyId) != 0, ("BitmapGroup::load familyId %i is already in use", familyId));
char* nameBuffer = iff.read_string ();
char* bitmapNameBuffer = iff.read_string();
//-- add family
addFamily (familyId, nameBuffer, bitmapNameBuffer);
Family* const family = getFamily(familyId);
NOT_NULL (family);
family->loadBitmapByFilename();
delete [] nameBuffer;
delete [] bitmapNameBuffer;
iff.exitChunk ();
iff.exitForm ();
} //lint !e429 //-- family not freed or returned
iff.exitForm ();
}
//-------------------------------------------------------------------
int BitmapGroup::getFamilyId (int familyIndex) const
{
VALIDATE_RANGE_INCLUSIVE_EXCLUSIVE (0, familyIndex, static_cast<int> (m_familyMap->size ()));
FamilyMap::iterator iter = m_familyMap->begin ();
int i = 0;
for (; i < familyIndex || iter == m_familyMap->end (); ++i, ++iter)
;
DEBUG_FATAL (iter == m_familyMap->end (), (""));
return iter->second->getFamilyId ();
}
//-------------------------------------------------------------------
int BitmapGroup::createUniqueFamilyId () const
{
int familyId = 1;
while (getFamily (familyId) != 0)
++familyId;
return familyId;
}
//-------------------------------------------------------------------
std::string BitmapGroup::createUniqueFamilyName (const char* baseName) const
{
char familyName [1000];
int i = 0;
do
{
++i;
sprintf (familyName, "%s_%i", baseName, i);
}
while (getFamily (familyName) != 0);
return std::string (familyName);
}
//===================================================================
@@ -0,0 +1,78 @@
//===================================================================
//
// BitmapGroup.h
//
// copyright 2004, sony online entertainment
//
//===================================================================
#ifndef INCLUDED_BitmapGroup_H
#define INCLUDED_BitmapGroup_H
//===================================================================
class Iff;
class Image;
//===================================================================
class BitmapGroup
{
public:
BitmapGroup ();
~BitmapGroup ();
//-- creation routines (for editor)
void load (Iff& iff);
void save (Iff& iff) const;
void reset ();
void prepare (int cacheX, int cacheY);
//--
const char* getFamilyName (int familyId) const;
void setFamilyName (int familyId, const char* name);
void loadFamilyBitmap(int familyId, const char* name);
const Image* getFamilyBitmap (int familyId) const;
Image* getFamilyBitmap (int familyId);
void reloadAllFamilyBitmaps(); // reloads all the bitmaps - called from the terrain editor
//-- family id routines
void addFamily (int familyId, const char* name, const char* bitmapName);
void removeFamily (int familyId);
bool hasFamily (int familyId) const;
bool findFamily (const char* name, int& familyId) const;
//-- family index routines
int getNumberOfFamilies () const;
int getFamilyId (int familyIndex) const;
void setFamilyId (int familyIndex, int newId);
private:
//-- list of families
class Family;
typedef stdmap<int, Family*>::fwd FamilyMap;
FamilyMap* m_familyMap;
private:
const Family* getFamily (int familyId) const;
Family* getFamily (int familyId);
const Family* getFamily (const char* familyName) const;
Family* getFamily (const char* familyName);
int createUniqueFamilyId () const;
std::string createUniqueFamilyName (const char* baseName) const;
void load_0000 (Iff& iff);
private:
BitmapGroup (const BitmapGroup& rhs);
BitmapGroup& operator= (const BitmapGroup& rhs);
};
//===================================================================
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,378 @@
//===================================================================
//
// Boundary.h
// asommers 9-30-2000
//
// copyright 2000, verant interactive
//
//===================================================================
#ifndef INCLUDED_Boundary_H
#define INCLUDED_Boundary_H
//===================================================================
#include "sharedMath/Rectangle2d.h"
#include "sharedMath/Transform2d.h"
#include "sharedMath/Vector2d.h"
#include "sharedTerrain/TerrainGenerator.h"
//===================================================================
class BoundaryCircle : public TerrainGenerator::Boundary
{
private:
float centerX;
float centerZ;
float radius;
float radiusSquared;
private:
void load_0000 (Iff& iff);
void load_0001 (Iff& iff);
void load_0002 (Iff& iff);
private:
BoundaryCircle (const BoundaryCircle& rhs);
BoundaryCircle& operator= (const BoundaryCircle& rhs);
public:
BoundaryCircle ();
virtual ~BoundaryCircle ();
float getCenterX () const;
float getCenterZ () const;
float getRadius () const;
void setCircle (float newCenterX, float newCenterZ, float newRadius);
virtual void translate (const Vector2d& translation);
virtual void scale (float scalar);
virtual float isWithin (float worldX, float worldZ) const;
virtual bool intersects(const Rectangle2d& other) const;
virtual void scanConvertGT(float *o_data, const Rectangle2d &scanArea, int numberOfPoles) const;
virtual void load (Iff& iff);
virtual void save (Iff& iff) const;
virtual void expand (Rectangle2d& extent) const;
virtual const Vector2d getCenter () const;
virtual void setCenter (const Vector2d& center);
};
//-------------------------------------------------------------------
inline float BoundaryCircle::getCenterX () const
{
return centerX;
}
//-------------------------------------------------------------------
inline float BoundaryCircle::getCenterZ () const
{
return centerZ;
}
//-------------------------------------------------------------------
inline float BoundaryCircle::getRadius () const
{
return radius;
}
//===================================================================
class BoundaryRectangle : public TerrainGenerator::Boundary
{
private:
typedef TerrainGenerator::Boundary BaseClass;
Rectangle2d rectangle;
Rectangle2d innerRectangle;
bool m_useTransform;
Transform2d m_transform;
bool m_localWaterTable;
bool m_localGlobalWaterTable;
float m_localWaterTableHeight;
float m_localWaterTableShaderSize;
char * m_localWaterTableShaderTemplateName;
TerrainGeneratorWaterType m_waterType;
private:
void recalculate ();
void load_0000 (Iff& iff);
void load_0001 (Iff& iff);
void load_0002 (Iff& iff);
void load_0003 (Iff& iff);
void load_0004 (Iff& iff);
private:
BoundaryRectangle (const BoundaryRectangle& rhs);
BoundaryRectangle& operator= (const BoundaryRectangle& rhs);
public:
BoundaryRectangle ();
virtual ~BoundaryRectangle ();
void setRectangle (const Rectangle2d& newRectangle);
const Rectangle2d& getRectangle () const;
virtual void setFeatherDistance (float newFeatherDistance);
virtual void translate (const Vector2d& translation);
virtual void scale (float scalar);
virtual float isWithin (float worldX, float worldZ) const;
virtual bool intersects(const Rectangle2d& other) const;
virtual void scanConvertGT(float *o_data, const Rectangle2d &scanArea, int numberOfPoles) const;
virtual void load (Iff& iff);
virtual void save (Iff& iff) const;
virtual void expand (Rectangle2d& extent) const;
virtual const Vector2d getCenter () const;
virtual void setCenter (const Vector2d& center);
virtual void setRotation (float angle);
bool isLocalWaterTable () const;
void setLocalWaterTable (bool localWaterTable);
bool isLocalGlobalWaterTable () const;
void setLocalGlobalWaterTable (bool localGlobalWaterTable);
float getLocalWaterTableHeight () const;
void setLocalWaterTableHeight (float localWaterTableHeight);
float getLocalWaterTableShaderSize () const;
void setLocalWaterTableShaderSize (float localWaterTableShaderSize);
char const * getLocalWaterTableShaderTemplateName () const;
void setLocalWaterTableShaderTemplateName (char const * localWaterTableShaderTemplateName);
TerrainGeneratorWaterType getWaterType () const;
void setWaterType (TerrainGeneratorWaterType newWaterType);
};
//-------------------------------------------------------------------
inline const Rectangle2d& BoundaryRectangle::getRectangle () const
{
return rectangle;
}
//-------------------------------------------------------------------
inline float BoundaryRectangle::getLocalWaterTableHeight () const
{
return m_localWaterTableHeight;
}
//-------------------------------------------------------------------
inline float BoundaryRectangle::getLocalWaterTableShaderSize () const
{
return m_localWaterTableShaderSize;
}
//-------------------------------------------------------------------
inline const char* BoundaryRectangle::getLocalWaterTableShaderTemplateName () const
{
return m_localWaterTableShaderTemplateName;
}
//-------------------------------------------------------------------
inline TerrainGeneratorWaterType BoundaryRectangle::getWaterType () const
{
return m_waterType;
}
//===================================================================
class BoundaryPoly : public TerrainGenerator::Boundary
{
protected:
ArrayList<Vector2d> pointList;
Rectangle2d extent;
protected:
virtual void recalculate ();
private:
BoundaryPoly (const BoundaryPoly& rhs);
BoundaryPoly& operator= (const BoundaryPoly& rhs);
public:
BoundaryPoly (Tag newTag, TerrainGeneratorBoundaryType newType);
virtual ~BoundaryPoly ()=0;
virtual void rotate (float angle);
virtual void rotate (float angle, const Vector2d& center);
virtual void translate (const Vector2d& translation);
virtual void scale (float scalar);
virtual void expand (Rectangle2d& extent) const;
virtual const Vector2d getCenter () const;
virtual bool intersects(const Rectangle2d& other) const;
const ArrayList<Vector2d>& getPointList () const;
int getNumberOfPoints () const;
const Vector2d& getPoint (int index) const;
void addPoint (const Vector2d& point);
void replacePoint (int index, const Vector2d& point);
void removePoint (int index);
void clearPointList ();
void copyPointList (const ArrayList<Vector2d>& newPointList);
};
//-------------------------------------------------------------------
inline const ArrayList<Vector2d>& BoundaryPoly::getPointList () const
{
return pointList;
}
//-------------------------------------------------------------------
inline int BoundaryPoly::getNumberOfPoints () const
{
return pointList.getNumberOfElements ();
}
//-------------------------------------------------------------------
inline const Vector2d& BoundaryPoly::getPoint (int index) const
{
return pointList [index];
}
//===================================================================
class BoundaryPolygon : public BoundaryPoly
{
private:
bool localWaterTable;
float localWaterTableHeight;
float localWaterTableShaderSize;
char* localWaterTableShaderTemplateName;
TerrainGeneratorWaterType m_waterType;
private:
void load_0000 (Iff& iff);
void load_0001 (Iff& iff);
void load_0002 (Iff& iff);
void load_0003 (Iff& iff);
void load_0004 (Iff& iff);
void load_0005 (Iff& iff);
void load_0006 (Iff& iff);
void load_0007 (Iff& iff);
private:
BoundaryPolygon (const BoundaryPolygon& rhs);
BoundaryPolygon& operator= (const BoundaryPolygon& rhs);
public:
BoundaryPolygon ();
virtual ~BoundaryPolygon ();
virtual float isWithin (float worldX, float worldZ) const;
virtual void load (Iff& iff);
virtual void save (Iff& iff) const;
bool isLocalWaterTable () const;
void setLocalWaterTable (bool newLocalWaterTable);
float getLocalWaterTableHeight () const;
void setLocalWaterTableHeight (float newLocalWaterTableHeight);
float getLocalWaterTableShaderSize () const;
void setLocalWaterTableShaderSize (float newLocalWaterTableShaderSize);
const char* getLocalWaterTableShaderTemplateName () const;
void setLocalWaterTableShaderTemplateName (const char* newLocalWaterTableShaderTemplateName);
TerrainGeneratorWaterType getWaterType () const;
void setWaterType (TerrainGeneratorWaterType newWaterType);
};
//-------------------------------------------------------------------
inline float BoundaryPolygon::getLocalWaterTableHeight () const
{
return localWaterTableHeight;
}
//-------------------------------------------------------------------
inline float BoundaryPolygon::getLocalWaterTableShaderSize () const
{
return localWaterTableShaderSize;
}
//-------------------------------------------------------------------
inline const char* BoundaryPolygon::getLocalWaterTableShaderTemplateName () const
{
return localWaterTableShaderTemplateName;
}
//-------------------------------------------------------------------
inline TerrainGeneratorWaterType BoundaryPolygon::getWaterType () const
{
return m_waterType;
}
//===================================================================
class BoundaryPolyline : public BoundaryPoly
{
private:
float m_width;
private:
virtual void recalculate ();
void load_0000 (Iff& iff);
void load_0001 (Iff& iff);
void load_0002 (Iff& iff);
void load_0003 (Iff& iff);
private:
BoundaryPolyline (const BoundaryPolyline& rhs);
BoundaryPolyline& operator= (const BoundaryPolyline& rhs);
public:
BoundaryPolyline ();
virtual ~BoundaryPolyline ();
virtual float isWithin (float worldX, float worldZ) const;
virtual void load (Iff& iff);
virtual void save (Iff& iff) const;
void setWidth (float newWidth);
float getWidth () const;
};
//-------------------------------------------------------------------
inline float BoundaryPolyline::getWidth () const
{
return m_width;
}
//===================================================================
#endif
@@ -0,0 +1,126 @@
//===================================================================
//
// ColorRamp256.cpp
// asommers
//
// copyright 2001, sony online entertainment
//
//===================================================================
#include "sharedTerrain/FirstSharedTerrain.h"
#include "sharedTerrain/ColorRamp256.h"
#include "sharedFile/Iff.h"
//===================================================================
namespace
{
const Tag TAG_RAMP = TAG (R,A,M,P);
}
//===================================================================
ColorRamp256::ColorRamp256 ()
//lint -esym (1926, ColorRamp256::m_ramp) // not in initializer list
//lint -esym (1926, ColorRamp256::m_node) // not in initializer list
{
int i;
for (i = 0; i < 256; ++i)
{
m_ramp [i] = PackedRgb::solidBlack;
m_node [i] = false;
}
m_node [0] = true;
m_node [255] = true;
}
//-------------------------------------------------------------------
ColorRamp256::~ColorRamp256 ()
{
}
//-------------------------------------------------------------------
void ColorRamp256::setColor (int index, const PackedRgb& color)
{
VALIDATE_RANGE_INCLUSIVE_EXCLUSIVE (0, index, 256);
m_ramp [index] = color;
}
//-------------------------------------------------------------------
void ColorRamp256::setNode (int index, bool node)
{
VALIDATE_RANGE_INCLUSIVE_EXCLUSIVE (0, index, 256);
m_node [index] = node;
}
//-------------------------------------------------------------------
void ColorRamp256::setRed (int index, uint8 r)
{
VALIDATE_RANGE_INCLUSIVE_EXCLUSIVE (0, index, 256);
m_ramp [index].r = r;
}
//-------------------------------------------------------------------
void ColorRamp256::setGreen (int index, uint8 g)
{
VALIDATE_RANGE_INCLUSIVE_EXCLUSIVE (0, index, 256);
m_ramp [index].g = g;
}
//-------------------------------------------------------------------
void ColorRamp256::setBlue (int index, uint8 b)
{
VALIDATE_RANGE_INCLUSIVE_EXCLUSIVE (0, index, 256);
m_ramp [index].b = b;
}
//-------------------------------------------------------------------
void ColorRamp256::load (Iff& iff)
{
iff.enterForm (TAG_RAMP);
iff.enterChunk (TAG_0000);
int i;
for (i = 0; i < 256; ++i)
{
m_ramp [i].r = iff.read_uint8 ();
m_ramp [i].g = iff.read_uint8 ();
m_ramp [i].b = iff.read_uint8 ();
m_node [i] = iff.read_uint8 () != 0;
}
iff.exitChunk ();
iff.exitForm ();
}
//-------------------------------------------------------------------
void ColorRamp256::save (Iff& iff) const
{
iff.insertForm (TAG_RAMP);
iff.insertChunk (TAG_0000);
int i;
for (i = 0; i < 256; ++i)
{
iff.insertChunkData (m_ramp [i].r);
iff.insertChunkData (m_ramp [i].g);
iff.insertChunkData (m_ramp [i].b);
iff.insertChunkData (m_node [i] ? static_cast<char> (1) : static_cast<char> (0));
}
iff.exitChunk ();
iff.exitForm ();
}
//===================================================================
@@ -0,0 +1,91 @@
//===================================================================
//
// ColorRamp256.h
// asommers
//
// copyright 2001, sony online entertainment
//
//===================================================================
#ifndef INCLUDED_ColorRamp_H
#define INCLUDED_ColorRamp_H
//===================================================================
#include "sharedMath/PackedRgb.h"
class Iff;
//===================================================================
class ColorRamp256
{
public:
ColorRamp256 ();
~ColorRamp256 ();
void setColor (int index, const PackedRgb& color);
void setRed (int index, uint8 r);
void setGreen (int index, uint8 g);
void setBlue (int index, uint8 b);
void setNode (int index, bool node);
const PackedRgb& getColor (int index) const;
uint8 getRed (int index) const;
uint8 getGreen (int index) const;
uint8 getBlue (int index) const;
bool getNode (int index) const;
void load (Iff& iff);
void save (Iff& iff) const;
private:
PackedRgb m_ramp [256];
bool m_node [256];
};
//-------------------------------------------------------------------
inline const PackedRgb& ColorRamp256::getColor (int index) const
{
VALIDATE_RANGE_INCLUSIVE_EXCLUSIVE (0, index, 256);
return m_ramp [index];
}
//-------------------------------------------------------------------
inline bool ColorRamp256::getNode (int index) const
{
VALIDATE_RANGE_INCLUSIVE_EXCLUSIVE (0, index, 256);
return m_node [index];
}
//-------------------------------------------------------------------
inline uint8 ColorRamp256::getRed (int index) const
{
VALIDATE_RANGE_INCLUSIVE_EXCLUSIVE (0, index, 256);
return m_ramp [index].r;
}
//-------------------------------------------------------------------
inline uint8 ColorRamp256::getGreen (int index) const
{
VALIDATE_RANGE_INCLUSIVE_EXCLUSIVE (0, index, 256);
return m_ramp [index].g;
}
//-------------------------------------------------------------------
inline uint8 ColorRamp256::getBlue (int index) const
{
VALIDATE_RANGE_INCLUSIVE_EXCLUSIVE (0, index, 256);
return m_ramp [index].b;
}
//===================================================================
#endif
@@ -0,0 +1,233 @@
//===================================================================
//
// CoordinateHash.cpp
// bearhart 6-30-2005
//
// copyright 2005, Sony Online Entertainment
//
//===================================================================
#include "sharedTerrain/FirstSharedTerrain.h"
#include "sharedTerrain/CoordinateHash.h"
#include "sharedRandom/FastRandomGenerator.h"
//===================================================================
namespace
{
/*
unsigned int shuffler1[256] = {
0xd987a3ee,0xcc2ab970,0xde1371a6,0xf8fa5333,0x43be3997,0x7b9d4893,0x8bbc3f47,0x1bab3ec6,
0x4e6fd45b,0xb35efe80,0x7e9549eb,0x416276de,0x016eded4,0x31a16f30,0x5be25d3a,0x149f0a1e,
0x0c4f2646,0xe726ccb6,0x7da990d6,0x974250f6,0x2958e3bc,0xf3b220c7,0x320228cf,0xfc37e8bf,
0x0dc2db52,0x375bbd88,0xbea058e1,0xc7784c45,0xa80f930c,0xb9bb45a7,0x3deff0af,0x723bdced,
0x5c80c2f8,0xf04769b4,0x774ebc0a,0x189a1e29,0x7c668dd0,0x0e84fc98,0xa9350bc2,0xd2e89c65,
0xbf3c5156,0xadcc464d,0x19eea891,0x1185793b,0x38d1b60d,0x274ca734,0x92e5c1d1,0x1dd9b1fb,
0xc2d44fa5,0x8f760df2,0x95ae6eb8,0xd494050b,0x479edd2a,0x6138dae4,0x4228e1e0,0x2c7acf41,
0x4b0e7a0f,0x732b425c,0xab11c696,0x6ae6ce7f,0xc3fe2254,0x5ff36c7a,0x8d747443,0xf432f2a1,
0x808aeddd,0x0491a53d,0xb01b568e,0x66c5e758,0x487d3357,0x53e46b07,0x8a6c43da,0xa20a090e,
0x5ef0ebc0,0x75b994cc,0x7fdf13f4,0xdf6df3a8,0x6420c0ff,0xcecb1812,0xaad3812f,0x54b1198f,
0xc471e017,0x3cecb553,0x2677c535,0xb460b089,0x511c3690,0x506a78c1,0x1a721a06,0x78962392,
0x585fa68b,0x2e599f1a,0x94edca49,0x9b5435b7,0x17ff38e7,0xe6b0c4dc,0x10f20777,0xaecdd387,
0xd80c113c,0x09db2d3e,0xe5f1ee5e,0x9d680471,0x2050c86f,0x9adad6b5,0x7a3954ec,0xbdd8a061,
0x575d21ca,0xe30d60b2,0x13c7917e,0x3bb35a66,0xdd0730fd,0x63fb83bd,0xd5ba12cd,0x2b0befac,
0x0b319e69,0xe024662e,0x6fe91086,0x88922c36,0x798c0f24,0x68567531,0x4d9963d5,0xba2d721c,
0xfd491cbe,0x242c7c75,0xcf63159d,0xf1d27b08,0xc01ec3f0,0x3f08f18d,0x307b3210,0x1c14d727,
0xb6d6a994,0xd79cb7d9,0xb18e8a99,0x98f77d83,0xe9e18079,0x2a06ae48,0x55f53450,0xa5e768ba,
0x56ce779a,0x454661fa,0x764bf659,0xcb5c7fa0,0xf56967ce,0x22b785e9,0xe273086b,0xd6d0f5a9,
0x23452e5d,0xed18a4fe,0x4f64bf00,0x46e39895,0xbc17a2ef,0x82d5996a,0xdcc1d864,0xe812e238,
0x059088d7,0x8cb4d501,0x81ac3a05,0xac7fd2d8,0x89c9aadb,0x8e10417d,0x9f7c3b6c,0x49b6954f,
0x87ddcb1d,0x966b31f9,0x0f44cd73,0xdbbf2a44,0x0a330ce6,0x3e70b8a4,0xb28b17f3,0xef61a151,
0xd122c782,0xf9013cea,0x909b40b9,0xc9518481,0xb8f9ab42,0xeb3a2914,0x448fe9e3,0x744a926e,
0x361a8fd2,0xc5dce6e8,0xc8c05b16,0x1e051fb3,0x2882be1b,0x60345f4e,0xd316b27b,0xffa80e6d,
0xd0fce5f1,0x93008923,0x2d045e19,0x07405755,0x3a57d9d3,0xbb1947a3,0xa7a7fbb1,0x063f2f7c,
0x86b8259e,0x2167b411,0x9e5327b0,0x5a3d9a5f,0xe4aa6a5a,0x33c44acb,0x034d1b4c,0xf2b57304,
0x59238609,0x70a46467,0x02a3b325,0xfecfac40,0x65def703,0xcd979be2,0x8509ec26,0x6efd1d28,
0xe19324f5,0xa3552b13,0x99eabb68,0xa03087a2,0xca5aeaad,0xf6ebff3f,0x164102c9,0xeaf41620,
0xc12e37bb,0x69adfde5,0x83484e78,0x35211422,0x6c7eaf1f,0xb7655c2c,0xaf0352ab,0x3486ba4b,
0x52794d9b,0x00af658c,0x1227f9ae,0x4a434439,0x671f709c,0x9ca68b37,0x91520674,0xfb81f49f,
0x40ca8c02,0xda1d9d2b,0x08a2d0aa,0xc6bd9763,0x39e0d132,0xf7887e62,0x6275fafc,0x5dc63dc5,
0x71f8dfc8,0xa6c80018,0x6dd755df,0xec8d9676,0xee298ec4,0x4c158272,0x2f3e4bf7,0xa42f6285,
0xfa36ad60,0x1f98c915,0xa1f6038a,0x25c36d4a,0x1583f8c3,0xb589e421,0x84a50184,0x6b25592d
};
unsigned int shuffler2[256] = {
0x2f2300f3,0xb970f3aa,0xec01de51,0xd8ff6adf,0xb3a7b1ff,0x7ee5829d,0x4f7dbcbe,0x3787f8d7,
0x28b7a03b,0x36f2eb65,0xaa6669c1,0x962293d9,0xc476842e,0xb2418a6e,0xc8032907,0x80e028fd,
0x4c9b5572,0x954e19d4,0xf5b58088,0x570ddd6f,0x7804b091,0xcb5a9bde,0x796c39e1,0x38840a2b,
0x33f1b60a,0x3dd7cd76,0x5851cf8a,0x717550f2,0x2c9f5cca,0xa126105f,0xd9aa1474,0x08c72fc9,
0x29499e4f,0xf4d08886,0xf0a461f6,0x5b7204cc,0x865edb81,0x7b7cd310,0x4734ad28,0x85809cdc,
0xce12ac9e,0x18b3b47b,0xe5e932f7,0x6386b7e3,0x5a11a727,0xea1f6500,0xc2443ddb,0x9bb0bb14,
0x75a1f0e9,0x88cf5a8b,0xd5949d3a,0x17fcc637,0x43d8b938,0xf8e1123e,0x7a3a8b77,0x10c9f92d,
0xbaac7cda,0x68482755,0x0ebcb3ce,0x1e3b0b7d,0x3eeb09c8,0x916a6416,0x341dc30e,0x8f4631a9,
0x2a0a078c,0x273ebab3,0xbd2fc005,0xa642b849,0x8ceaffea,0xa91bfbd1,0x1d7e75c3,0x87b8bda0,
0xb0fe44c6,0x6db926ec,0xeb526f48,0x59165378,0x6e9970b7,0x61b4a647,0xe6dce5c7,0x4e208dd0,
0x8b6bc8e6,0x5ef735ef,0xa41ad1f8,0xed4b9966,0x6085cb35,0x6768d843,0xa7ed5d5e,0xbb71f75c,
0x7f59474e,0x3582950b,0x05790508,0xfd7f5e31,0xc098c71d,0xafefe090,0xf6c5ab5b,0x0aaec518,
0x99f002a4,0xd76e63a2,0xdc402b33,0x56e6bed5,0x0b2b4353,0xcf640db0,0x548321ab,0xe20f7485,
0x131530fb,0xd4456e19,0x448ac4af,0x3ae3eeb6,0xda812d01,0xf36d73d6,0x66271c11,0x1c5794cb,
0xf100f567,0x2017f668,0x23ce4996,0xb4bb5606,0x89a66269,0xfeb6bf71,0x425b7fbf,0x4ad43302,
0xa85666b1,0x7d8b1646,0xbfd9c2b9,0x6f9cc16d,0x726236d8,0xfc89e252,0x16c41d82,0xf93620e2,
0xdde28589,0x7cbf1fa5,0xa5904bac,0x92af5858,0x1a53aebb,0x9ffbd7cf,0x81ee387e,0x9ef91157,
0x30917b8e,0x46ad40bd,0x827adaf9,0xe1f4ceba,0xbcbdb261,0xe9f5d07f,0x9cc113fa,0x49614e63,
0x4b3979c2,0x8a304f70,0x395d4529,0x0d35d404,0x50217ec4,0x6acca921,0xfa633779,0xa210222c,
0xa0180cae,0x9d73b515,0xca08d50d,0xd10e3f98,0xb6243ca6,0x4d50521e,0x94f85484,0x1192816c,
0xf7a246ad,0x55d68fb4,0x22f31ac5,0x45ca9809,0xd3775f3d,0x40a03423,0x24334a44,0xde37cce0,
0xee2c5199,0x5f2991e5,0x2d43f4ee,0x843f7d1a,0x129d0ebc,0xffa50fb8,0x15a3687c,0x981ea464,
0x009ae962,0x6ce46d80,0x253cafe4,0x74197283,0xac314217,0xe4d2f122,0xe32578f5,0x7654609a,
0x7009e43f,0x2ec80854,0x9a7b41f1,0x5260ece8,0xcd06fc9c,0x03b1effc,0x0f5cd94b,0xc1b21efe,
0x26ecea0f,0x0158a345,0x3b28dfed,0x931c2ea3,0x09a959e7,0xfbd5489f,0xb52e3b32,0xad380612,
0xc513edd2,0x19692a2a,0xbe88fe3c,0xc6c6aaeb,0xef6703dd,0xc38c4d30,0x51db1893,0xd22d7625,
0x838da5b5,0xe8de2442,0x64df87b2,0xccc3869b,0xdbd3d673,0xe795e6f4,0xf2556724,0x0cdd1713,
0x69149f95,0xc9cd965a,0xa33dfd1f,0x6bda778f,0x532ad250,0x484a2c5d,0xdff6a2f0,0x779ea81b,
0xe0d16b6b,0x06a85b8d,0x316fcaa8,0x73979a03,0x2b5ffa4a,0xc7c071d3,0x8d4d3aa1,0x3c323e92,
0x3f938c36,0x1bfd1b94,0x14ba7a56,0x62ab0134,0x414789cd,0xb84f972f,0xb707e74c,0x6578f2a7,
0x908ea141,0x07c2927a,0xd065dcc0,0x8e4c8320,0x5c8f4c60,0x21746c6a,0x5d02254d,0x32cbe326,
0x1f0c8e75,0xae0b2340,0x02fae80c,0xabbee197,0xd6965739,0x97e7901c,0x0405c987,0xb1e81559
};
uint32 _hash1(uint32 x)
{
const uint32 h1 = shuffler[((x>> 0)+ 0)&255];
const uint32 h2 = shuffler[((x>> 8)+ 64)&255];
const uint32 h3 = shuffler[((x>>16)+128)&255];
const uint32 h4 = shuffler[((x>>24)+192)&255];
return h1 ^ h2 ^ h3 ^ h4;
}
uint32 _hash2(uint32 x)
{
const uint32 h1 = shuffler[((x>> 0)+ 64)&255];
const uint32 h2 = shuffler[((x>> 8)+128)&255];
const uint32 h3 = shuffler[((x>>16)+192)&255];
const uint32 h4 = shuffler[((x>>24)+ 0)&255];
return (h1 + h2) + (h3 + h4);
}
uint32 _hash3(uint32 x)
{
const uint32 h1 = shuffler[((x>> 0)+128)&255];
const uint32 h2 = shuffler[((x>> 8)+192)&255];
const uint32 h3 = shuffler[((x>>16)+ 0)&255];
const uint32 h4 = shuffler[((x>>24)+ 64)&255];
return (h1 + h2) * (h3 + h4);
}
uint32 _hash4(uint32 x)
{
const int i = (x>>24) ^ ((x>>16)&255) ^ ((x>>8)&255) ^ (x&255);
const uint32 h1 = shuffler[i];
return h1;
}
long _hashSeeds[256] = {
76243,172321,123433,222149,99551,197089,147647,247591,87803,184669,135497,234803,111493,209563,159811,260387,
75527,171583,122651,221401,98849,196271,146917,246773,87149,183917,134777,234083,110731,208787,159119,259531,
74779,170777,121951,220589,98047,195469,146099,245981,86369,183091,133993,233183,109903,208049,158293,258677,
74101,170063,121189,219823,97301,194723,145433,245177,85639,182387,133187,232357,109199,207331,157457,257953,
73369,169321,120551,219071,96497,193861,144593,244411,84919,181669,132499,231481,108499,206483,156727,257141,
72647,168499,119771,218389,95783,193073,143797,243631,84191,180731,131713,230683,107773,205763,155851,256189,
71917,167627,119027,217489,95093,192347,142973,242797,83417,179947,130927,229937,106921,205031,155171,255469,
71261,166909,118213,216757,94397,191599,142159,241981,82633,179269,130183,229223,106273,204163,154373,254773,
67589,162917,114547,212671,90787,187639,138433,238159,79159,175519,126421,225307,102409,200177,150611,250777,
66947,162209,113749,211789,90023,186883,137659,237287,78401,174637,125669,224527,101741,199411,149893,249853,
66179,161377,113017,211051,89387,186107,136897,236503,77647,173867,124907,223747,101081,198593,149159,249059,
65537,160637,112223,210241,88681,185467,136261,235607,76991,173059,124171,222977,100297,197831,148469,248293,
70571,166151,117503,215899,93601,190807,141461,241313,81967,178561,129419,228511,105491,203363,153589,253879,
69877,165343,116747,215063,92893,189977,140689,240509,81233,177811,128669,227651,104723,202591,152837,253103,
69109,164443,115931,214243,92251,189271,139981,239713,80611,176921,127931,226903,104009,201797,152077,252253,
68351,163729,115279,213467,91493,188483,139273,238897,79861,176237,127247,226099,103231,201011,151391,251473
};
inline long _hash(unsigned long x)
{
return
( (_hashSeeds[(x>> 0)&255]<<8) + _hashSeeds[(x>> 8)&255] )
* ( (_hashSeeds[(x>>16)&255]<<8) + _hashSeeds[(x>>24)&255] )
;
}
*/
uint32 inthash(uint32 key)
{
key += (key << 12);
key ^= (key >> 22);
key += (key << 4);
key ^= (key >> 9);
key += (key << 10);
key ^= (key >> 2);
key += (key << 7);
key ^= (key >> 12);
return key;
}
/*
uint32 _rotateRight(uint32 x, const int count)
{
const int modCount = count&31;
const unsigned returnValue = (x>>modCount) | (x<<(32-modCount));
return returnValue;
}
uint32 _rotateLeft(uint32 x, const int count)
{
const int modCount = count&31;
const unsigned returnValue = (x<<modCount) | (x>>(32-modCount));
return returnValue;
}
*/
};
//===================================================================
unsigned long CoordinateHash::hashTuple(float x, float z)
{
const uint32 ix = (*(uint32 *)&x);
const uint32 iz = (*(uint32 *)&z)^0xa5a5a5a5;
const uint32 hx = inthash(ix);
const uint32 hz = inthash(iz);
const uint32 h = inthash(hx^hz);
return h;
}
float CoordinateHash::makeFloat(unsigned long hash)
{
enum { IEEE_FLOAT_BITS=0x3f800000 };
const uint32 mask = ~uint32(0xff800000);
const uint32 maskedHash = (hash + (hash>>9))&mask;
const uint32 iFloat = IEEE_FLOAT_BITS | maskedHash;
const float returnValue = (*(float *)&iFloat) - 1.0f;
return returnValue;
}
#if 0
long CoordinateHash::hashTuple(float x, float z)
{
const unsigned long ix = (*(unsigned long *)&x)^0x5a5a5a5a;
const unsigned long iz = (*(unsigned long *)&z)^0xa5a5a5a5;
const unsigned long hx = _hash1((ix>>8) | (ix<<24));
const unsigned long hz = _hash1((iz>>16) | (iz<<16));
const unsigned long hmix1 = hx^hz;
const unsigned long h = hmix1;
/*
FastRandomGenerator rngx(hx);
FastRandomGenerator rngz(hz);
const long rnx = rngx.random();
const long rnz = rngz.random();
return rnx^rnz;
*/
return h;
}
#endif
//===================================================================
@@ -0,0 +1,29 @@
//===================================================================
//
// CoordinateHash.h
// bearhart 6-30-2005
//
// copyright 2005, Sony Online Entertainment
//
//--
//
// Class to hash terrain coordinate pairs into good random seeds.
//
//===================================================================
#ifndef INCLUDED_CoordinateHash_H
#define INCLUDED_CoordinateHash_H
//===================================================================
class CoordinateHash
{
public:
static unsigned long hashTuple(float x, float z);
static float makeFloat(unsigned long hash);
};
//===================================================================
#endif
@@ -0,0 +1,635 @@
//
// EnvironmentGroup.cpp
// asommers 9-17-2000
//
// copyright 2000, verant interactive
//
//-------------------------------------------------------------------
#include "sharedTerrain/FirstSharedTerrain.h"
#include "sharedTerrain/EnvironmentGroup.h"
#include "sharedFile/Iff.h"
#include "sharedTerrain/ColorRamp256.h"
//-------------------------------------------------------------------
//
// EnvironmentGroup::Info
//
EnvironmentGroup::Info::Info () :
m_familyId(0)
{
}
//-------------------------------------------------------------------
EnvironmentGroup::Info::~Info ()
{
}
//-------------------------------------------------------------------
int EnvironmentGroup::Info::getFamilyId() const
{
return m_familyId;
}
//-------------------------------------------------------------------
void EnvironmentGroup::Info::setFamilyId(int const familyId)
{
DEBUG_WARNING(familyId < 0 || familyId > 255, ("EnvironmentGroup::Info::setFamilyId: familyId %i will be clamped to a uint8", familyId));
m_familyId = static_cast<uint8>(familyId);
}
//-------------------------------------------------------------------
//
// EnvironmentGroup::Family
//
class EnvironmentGroup::Family
{
private:
int familyId;
char* name;
PackedRgb color;
//-- family data
float m_featherClamp;
private:
Family ();
Family (const Family& rhs); //lint -esym (754, Family::Family)
Family& operator= (const Family& rhs); //lint -esym (754, Family::operator=)
public:
explicit Family (int newFamilyId);
~Family ();
int getFamilyId () const;
void setFamilyId (int newId);
const char* getName () const;
void setName (const char* newName);
const PackedRgb& getColor () const;
void setColor (const PackedRgb& newColor);
float getFeatherClamp () const;
void setFeatherClamp (float featherClamp);
};
//-------------------------------------------------------------------
EnvironmentGroup::Family::Family (int newFamilyId) :
familyId (newFamilyId),
name (0),
color (),
m_featherClamp (1.f)
{
}
//-------------------------------------------------------------------
EnvironmentGroup::Family::~Family ()
{
delete [] name;
name = 0;
}
//-------------------------------------------------------------------
void EnvironmentGroup::Family::setFamilyId (int newFamilyId)
{
familyId = newFamilyId;
}
//-------------------------------------------------------------------
const char* EnvironmentGroup::Family::getName () const
{
return name;
}
//-------------------------------------------------------------------
void EnvironmentGroup::Family::setName (const char* newName)
{
if (name)
{
delete [] name;
name = 0;
}
if (newName)
name = DuplicateString (newName);
}
//-------------------------------------------------------------------
const PackedRgb& EnvironmentGroup::Family::getColor () const
{
return color;
}
//-------------------------------------------------------------------
void EnvironmentGroup::Family::setColor (const PackedRgb& newColor)
{
color = newColor;
}
//-------------------------------------------------------------------
int EnvironmentGroup::Family::getFamilyId () const
{
return familyId;
}
//-------------------------------------------------------------------
//
// EnvironmentGroup
//
EnvironmentGroup::EnvironmentGroup () :
familyList (),
errorFamilyColor (255, 0, 255)
{
}
//-------------------------------------------------------------------
EnvironmentGroup::~EnvironmentGroup ()
{
//-- delete family list
removeAllFamilies ();
}
//-------------------------------------------------------------------
void EnvironmentGroup::setFamilyId (int familyIndex, int newFamilyId)
{
familyList [familyIndex]->setFamilyId (newFamilyId);
}
//-------------------------------------------------------------------
const EnvironmentGroup::Info EnvironmentGroup::getDefaultEnvironment () const
{
Info rfgi;
rfgi.setFamilyId(0);
return rfgi;
}
//-------------------------------------------------------------------
int EnvironmentGroup::findFamilyIndex (int familyId) const
{
//-- no, so search list
int i;
for (i = 0; i < familyList.getNumberOfElements (); i++)
if (familyList [i]->getFamilyId () == familyId)
return i;
//-- item still not found in list
return -1;
}
//-------------------------------------------------------------------
int EnvironmentGroup::findFamilyIndex (const PackedRgb& desiredColor) const
{
//-- no, so search list
int i;
for (i = 0; i < familyList.getNumberOfElements (); i++)
if (familyList [i]->getColor () == desiredColor)
return i;
//-- item still not found in list
return -1;
}
//-------------------------------------------------------------------
void EnvironmentGroup::removeAllFamilies ()
{
int i;
for (i = 0; i < familyList.getNumberOfElements (); i++)
{
delete familyList [i];
familyList [i] = 0;
}
familyList.clear ();
}
//-------------------------------------------------------------------
void EnvironmentGroup::addFamily (int familyId, const char* name, const PackedRgb& color)
{
int familyIndex = findFamilyIndex (familyId);
DEBUG_FATAL (familyIndex != -1, ("family with id %i already exists", familyId));
if (familyIndex == -1) //lint !e774 //-- if always true
{
Family* family = new Family (familyId);
family->setColor (color);
family->setName (name);
familyList.add (family);
} //lint !e429 //-- family not freed or returned
}
//-------------------------------------------------------------------
void EnvironmentGroup::removeFamily (int familyId)
{
int familyIndex = findFamilyIndex (familyId);
DEBUG_FATAL (familyIndex == -1, ("family with id %i not found", familyId));
delete familyList [familyIndex];
familyList [familyIndex] = 0;
familyList.removeIndexAndCompactList (familyIndex);
}
//-------------------------------------------------------------------
int EnvironmentGroup::getNumberOfFamilies () const
{
return familyList.getNumberOfElements ();
}
//-------------------------------------------------------------------
const EnvironmentGroup::Info EnvironmentGroup::chooseEnvironment (int familyId) const
{
Info rfgi = getDefaultEnvironment ();
//-- search for the shader in the family list
int familyIndex = findFamilyIndex (familyId);
if (familyIndex != -1)
rfgi.setFamilyId(familyId);
else
//-- family id wasn't found, so log and return default shader
DEBUG_REPORT_LOG_PRINT (true, ("EnvironmentGroup::chooseEnvironment - familyId %i not found, using default shader\n", familyId));
return rfgi;
}
//-------------------------------------------------------------------
const EnvironmentGroup::Info EnvironmentGroup::chooseEnvironment (const PackedRgb& desiredColor) const
{
Info rfgi = getDefaultEnvironment ();
//-- search for the shader in the family list
int familyIndex = findFamilyIndex (desiredColor);
if (familyIndex != -1)
rfgi.setFamilyId(familyList[familyIndex]->getFamilyId());
else
//-- family id wasn't found, so log and return default shader
DEBUG_REPORT_LOG_PRINT (true, ("EnvironmentGroup::chooseEnvironment - family with color %i %i %i not found, using default shader\n", desiredColor.r, desiredColor.g, desiredColor.b));
return rfgi;
}
//-------------------------------------------------------------------
void EnvironmentGroup::load (Iff& iff)
{
//-- delete family list first
removeAllFamilies ();
//-- load data
if (iff.enterForm (TAG (E,G,R,P), true))
{
switch (iff.getCurrentName ())
{
case TAG_0000:
load_0000 (iff);
break;
case TAG_0001:
load_0001 (iff);
break;
case TAG_0002:
load_0002 (iff);
break;
default:
DEBUG_FATAL (true, ("EnvironmentGroup::load unknown tag"));
}
iff.exitForm ();
}
}
//-------------------------------------------------------------------
void EnvironmentGroup::load_0000 (Iff& iff)
{
iff.enterForm (TAG_0000);
int n = iff.getNumberOfBlocksLeft ();
int i;
for (i = 0; i < n; i++)
{
iff.enterForm (TAG (E,F,A,M));
iff.enterChunk (TAG_DATA);
int familyId = iff.read_int32 ();
//-- see if family id is already in use
DEBUG_FATAL (findFamilyIndex (familyId) != -1, ("EnvironmentGroup::load familyId %i is already in use", familyId));
//-- add family
Family* family = new Family (familyId);
char* nameBuffer = iff.read_string ();
family->setName (nameBuffer);
delete [] nameBuffer;
PackedRgb color;
color.r = iff.read_uint8 ();
color.g = iff.read_uint8 ();
color.b = iff.read_uint8 ();
family->setColor (color);
family->setFeatherClamp (iff.read_float ());
iff.exitChunk (true);
familyList.add (family);
iff.exitForm (true);
} //lint !e429 //-- family not freed or returned
iff.exitForm ();
}
//-------------------------------------------------------------------
void EnvironmentGroup::load_0001 (Iff& iff)
{
iff.enterForm (TAG_0001);
int n = iff.getNumberOfBlocksLeft ();
int i;
for (i = 0; i < n; i++)
{
iff.enterForm (TAG (E,F,A,M));
iff.enterChunk (TAG_DATA);
int familyId = iff.read_int32 ();
//-- see if family id is already in use
DEBUG_FATAL (findFamilyIndex (familyId) != -1, ("EnvironmentGroup::load familyId %i is already in use", familyId));
//-- add family
Family* family = new Family (familyId);
char* nameBuffer = iff.read_string ();
family->setName (nameBuffer);
delete [] nameBuffer;
PackedRgb color;
color.r = iff.read_uint8 ();
color.g = iff.read_uint8 ();
color.b = iff.read_uint8 ();
family->setColor (color);
family->setFeatherClamp (iff.read_float ());
iff.exitChunk (true);
familyList.add (family);
iff.exitForm (true);
} //lint !e429 //-- family not freed or returned
iff.exitForm ();
}
//-------------------------------------------------------------------
void EnvironmentGroup::load_0002 (Iff& iff)
{
iff.enterForm (TAG_0002);
int n = iff.getNumberOfBlocksLeft ();
int i;
for (i = 0; i < n; i++)
{
iff.enterForm (TAG (E,F,A,M));
iff.enterChunk (TAG_DATA);
int familyId = iff.read_int32 ();
//-- see if family id is already in use
DEBUG_FATAL (findFamilyIndex (familyId) != -1, ("EnvironmentGroup::load familyId %i is already in use", familyId));
//-- add family
Family* family = new Family (familyId);
char* nameBuffer = iff.read_string ();
family->setName (nameBuffer);
delete [] nameBuffer;
PackedRgb color;
color.r = iff.read_uint8 ();
color.g = iff.read_uint8 ();
color.b = iff.read_uint8 ();
family->setColor (color);
family->setFeatherClamp (iff.read_float ());
iff.exitChunk (true);
familyList.add (family);
iff.exitForm (true);
} //lint !e429 //-- family not freed or returned
iff.exitForm ();
}
//-------------------------------------------------------------------
void EnvironmentGroup::save (Iff& iff) const
{
iff.insertForm (TAG (E,G,R,P));
iff.insertForm (TAG_0002);
int numberOfFamilies = getNumberOfFamilies ();
int i;
for (i = 0; i < numberOfFamilies; i++)
{
const Family* family = familyList [i];
iff.insertForm (TAG (E,F,A,M));
iff.insertChunk (TAG_DATA);
iff.insertChunkData (static_cast<int32> (family->getFamilyId ()));
iff.insertChunkString (family->getName ());
iff.insertChunkData (static_cast<uint8> (family->getColor ().r));
iff.insertChunkData (static_cast<uint8> (family->getColor ().g));
iff.insertChunkData (static_cast<uint8> (family->getColor ().b));
iff.insertChunkData (family->getFeatherClamp ());
iff.exitChunk (TAG_DATA);
iff.exitForm (TAG (E,F,A,M));
}
iff.exitForm (TAG_0002);
iff.exitForm (TAG (E,G,R,P));
}
//-------------------------------------------------------------------
const PackedRgb& EnvironmentGroup::getFamilyColor (int familyId) const
{
//-- search for the appearance in the family list
int familyIndex = findFamilyIndex (familyId);
if (familyIndex != -1)
return familyList [familyIndex]->getColor ();
//-- family id wasn't found, so log and return default shader
DEBUG_REPORT_LOG_PRINT (true, ("EnvironmentGroup::getFamilyColorById - familyId %i not found, using error color.\n", familyId));
return errorFamilyColor;
}
//-------------------------------------------------------------------
int EnvironmentGroup::getFamilyId (const PackedRgb& desiredColor) const
{
//-- search for the appearance in the family list
int familyIndex = findFamilyIndex (desiredColor);
if (familyIndex != -1)
return familyList [familyIndex]->getFamilyId ();
//-- color wasn't found, so log and return default shader
return 0;
}
//-------------------------------------------------------------------
const char* EnvironmentGroup::getFamilyName (int familyId) const
{
int familyIndex = findFamilyIndex (familyId);
DEBUG_FATAL (familyIndex == -1, ("family with id %i not found", familyId));
return familyList [familyIndex]->getName ();
}
//-------------------------------------------------------------------
void EnvironmentGroup::setFamilyName (int familyId, const char* newName)
{
int familyIndex = findFamilyIndex (familyId);
DEBUG_FATAL (familyIndex == -1, ("family with id %i not found", familyId));
familyList [familyIndex]->setName (newName);
}
//-------------------------------------------------------------------
void EnvironmentGroup::setFamilyColor (int familyId, const PackedRgb& newColor)
{
int familyIndex = findFamilyIndex (familyId);
DEBUG_FATAL (familyIndex == -1, ("family with id %i not found", familyId));
familyList [familyIndex]->setColor (newColor);
}
//-------------------------------------------------------------------
int EnvironmentGroup::getFamilyId (int familyIndex) const
{
return familyList [familyIndex]->getFamilyId ();
}
//-------------------------------------------------------------------
bool EnvironmentGroup::hasFamily (int familyId) const
{
return findFamilyIndex (familyId) != -1;
}
//-------------------------------------------------------------------
bool EnvironmentGroup::hasFamily (const char* name) const
{
int i;
for (i = 0; i < familyList.getNumberOfElements (); i++)
if (_stricmp (name, familyList [i]->getName ()) == 0)
return true;
return false;
}
//-------------------------------------------------------------------
int EnvironmentGroup::getFamilyId (const char* name) const
{
int i;
for (i = 0; i < familyList.getNumberOfElements (); i++)
if (_stricmp (name, familyList [i]->getName ()) == 0)
return familyList [i]->getFamilyId ();
DEBUG_FATAL (true, ("family with name %s not found", name));
return -1; //lint !e527 //unreachable
}
//-------------------------------------------------------------------
float EnvironmentGroup::Family::getFeatherClamp () const
{
return m_featherClamp;
}
//-------------------------------------------------------------------
void EnvironmentGroup::Family::setFeatherClamp (float featherClamp)
{
m_featherClamp = featherClamp;
}
//-------------------------------------------------------------------
float EnvironmentGroup::getFamilyFeatherClamp (int familyId) const
{
int familyIndex = findFamilyIndex (familyId);
DEBUG_FATAL (familyIndex == -1, ("family with id %i not found", familyId));
return familyList [familyIndex]->getFeatherClamp ();
}
//-------------------------------------------------------------------
void EnvironmentGroup::setFamilyFeatherClamp (int familyId, float featherClamp)
{
int familyIndex = findFamilyIndex (familyId);
DEBUG_FATAL (familyIndex == -1, ("family with id %i not found", familyId));
familyList [familyIndex]->setFeatherClamp (featherClamp);
}
//-------------------------------------------------------------------
void EnvironmentGroup::copyFamily (const int destinationFamilyId, const int sourceFamilyId)
{
setFamilyFeatherClamp (destinationFamilyId, getFamilyFeatherClamp (sourceFamilyId));
}
//===================================================================
@@ -0,0 +1,115 @@
//===================================================================
//
// EnvironmentGroup.h
// asommers 9-17-2000
//
// copyright 2000, verant interactive
//
//===================================================================
#ifndef INCLUDED_EnvironmentGroup_H
#define INCLUDED_EnvironmentGroup_H
//===================================================================
#include "sharedFoundation/ArrayList.h"
#include "sharedMath/PackedRgb.h"
class ColorRamp256;
class Iff;
//===================================================================
class EnvironmentGroup
{
public:
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//
// Info holds info about an environment
//
struct Info
{
public:
Info();
~Info();
int getFamilyId() const;
void setFamilyId(int familyId);
private:
uint8 m_familyId;
};
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
private:
class Family;
private:
//-- list of families
ArrayList<Family*> familyList;
//--
PackedRgb errorFamilyColor;
private:
int findFamilyIndex (int familyId) const;
int findFamilyIndex (const PackedRgb& desiredColor) const;
private:
void load_0000 (Iff& iff);
void load_0001 (Iff& iff);
void load_0002 (Iff& iff);
private:
EnvironmentGroup (const EnvironmentGroup& rhs);
EnvironmentGroup& operator= (const EnvironmentGroup& rhs);
public:
EnvironmentGroup ();
~EnvironmentGroup ();
const Info getDefaultEnvironment () const;
const Info chooseEnvironment (int familyId) const;
const Info chooseEnvironment (const PackedRgb& desiredColor) const;
//-- creation routines (for editor)
void load (Iff& iff);
void save (Iff& iff) const;
void removeAllFamilies ();
//-- family id routines
void addFamily (int familyId, const char* name, const PackedRgb& color);
void removeFamily (int familyId);
bool hasFamily (int familyId) const;
bool hasFamily (const char* name) const;
int getFamilyId (const PackedRgb& desiredColor) const;
int getFamilyId (const char* name) const;
const char* getFamilyName (int familyId) const;
void setFamilyName (int familyId, const char* name);
const PackedRgb& getFamilyColor (int familyId) const;
void setFamilyColor (int familyId, const PackedRgb& prgb);
float getFamilyFeatherClamp (int familyId) const;
void setFamilyFeatherClamp (int familyId, float featherClamp);
void copyFamily (int destinationFamilyId, int sourceFamilyId);
//-- family index routines
int getNumberOfFamilies () const;
int getFamilyId (int familyIndex) const;
void setFamilyId (int familyIndex, int newId);
};
//===================================================================
#endif
@@ -0,0 +1,133 @@
//===================================================================
//
// FastKeyList.h
// asommers
//
// copyright 2001, sony online entertainment
//
//--
//
// FastKeyList is a sorted automatic memory based list completely avoiding memory allocation
// T must have a .key parameter which is of type KEY
//===================================================================
#ifndef INCLUDED_FastKeyList_H
#define INCLUDED_FastKeyList_H
//===================================================================
template<class T, class KEY, int MAXSIZE>
class FastKeyList
{
public:
FastKeyList ();
~FastKeyList ();
int getNumberOfElements ();
const T& operator[] (int index) const;
void insertIfNotExists (const T& element);
private:
void add (const T& element);
private:
//-- disable heap'ed FastKeyList
void* operator new (size_t size);
FastKeyList (const FastKeyList<T, KEY, MAXSIZE>& rhs);
FastKeyList& operator= (const FastKeyList<T, KEY, MAXSIZE>& rhs);
private:
int numberOfElements;
T data [MAXSIZE];
};
//===================================================================
template<class T, class KEY, int MAXSIZE>
inline FastKeyList<T, KEY, MAXSIZE>::FastKeyList () :
numberOfElements (0)
{
}
//-------------------------------------------------------------------
template<class T, class KEY, int MAXSIZE>
inline FastKeyList<T, KEY, MAXSIZE>::~FastKeyList ()
{
}
//-------------------------------------------------------------------
template<class T, class KEY, int MAXSIZE>
inline int FastKeyList<T, KEY, MAXSIZE>::getNumberOfElements ()
{
return numberOfElements;
}
//-------------------------------------------------------------------
template<class T, class KEY, int MAXSIZE>
inline const T& FastKeyList<T, KEY, MAXSIZE>::operator[] (int index) const
{
DEBUG_FATAL (index < 0 || index >= numberOfElements, ("index out of range"));
return data [index];
}
//-------------------------------------------------------------------
template<class T, class KEY, int MAXSIZE>
inline void FastKeyList<T, KEY, MAXSIZE>::add (const T& element)
{
DEBUG_FATAL (numberOfElements == MAXSIZE, ("can't add to a full list"));
data [numberOfElements++] = element;
}
//-------------------------------------------------------------------
template<class T, class KEY, int MAXSIZE>
inline void FastKeyList<T, KEY, MAXSIZE>::insertIfNotExists(const T& element)
{
//-- search for where to insert
int i = 0;
for (; i < numberOfElements; ++i)
{
if (data[i].key == element.key)
{
return;
}
else if (data[i].key > element.key)
{
break;
}
}
//-- is element to add at end?
if (i == numberOfElements)
{
add (element);
}
else
{
DEBUG_FATAL (numberOfElements == MAXSIZE, ("can't add to a full list"));
//-- make room
int j;
for (j = numberOfElements; j >= i; --j)
data [j] = data [j - 1];
data [i] = element;
numberOfElements++;
}
}
//===================================================================
#endif
@@ -0,0 +1,125 @@
//===================================================================
//
// FastList.h
// asommers
//
// copyright 2001, sony online entertainment
//
//--
//
// FastList is an unsorted automatic memory based list completely avoiding memory allocation
//
//===================================================================
#ifndef INCLUDED_FastList_H
#define INCLUDED_FastList_H
//===================================================================
template<class T, int n>
class FastList
{
public:
FastList ();
~FastList ();
int getNumberOfElements ();
const T& operator[] (int index) const;
T& operator[] (int index);
bool exists (const T& element) const;
void add (const T& element);
void addIfNotExists (const T& element);
private:
//-- disable heap'ed fastlist
void* operator new (size_t size);
FastList (const FastList<T, n>& rhs);
FastList& operator= (const FastList<T, n>& rhs);
private:
int numberOfElements;
T data [n];
};
//===================================================================
template<class T, int n>
inline FastList<T, n>::FastList () :
numberOfElements (0)
{
}
//-------------------------------------------------------------------
template<class T, int n>
inline FastList<T, n>::~FastList ()
{
}
//-------------------------------------------------------------------
template<class T, int n>
inline int FastList<T, n>::getNumberOfElements ()
{
return numberOfElements;
}
//-------------------------------------------------------------------
template<class T, int n>
inline const T& FastList<T, n>::operator[] (int index) const
{
DEBUG_FATAL (index < 0 || index >= numberOfElements, ("index out of range"));
return data [index];
}
//-------------------------------------------------------------------
template<class T, int n>
inline T& FastList<T, n>::operator[] (int index)
{
DEBUG_FATAL (index < 0 || index >= numberOfElements, ("index out of range"));
return data [index];
}
//-------------------------------------------------------------------
template<class T, int n>
inline bool FastList<T, n>::exists (const T& element) const
{
int i;
for (i = 0; i < numberOfElements; ++i)
if (data [i] == element)
return true;
return false;
}
//-------------------------------------------------------------------
template<class T, int n>
inline void FastList<T, n>::add (const T& element)
{
DEBUG_FATAL (numberOfElements == n, ("can't add to a full list"));
data [numberOfElements++] = element;
}
//-------------------------------------------------------------------
template<class T, int n>
inline void FastList<T, n>::addIfNotExists (const T& element)
{
if (!exists (element))
add (element);
}
//===================================================================
#endif
@@ -0,0 +1,112 @@
//===================================================================
//
// Feather.h
// asommers 2001-01-28
//
// copyright 2001, sony online entertainment
//
//===================================================================
#ifndef INCLUDED_Feather_H
#define INCLUDED_Feather_H
//===================================================================
class Feather
{
public:
explicit Feather (TerrainGeneratorFeatherFunction newFeatherFunction);
~Feather ();
float feather (float start, float end, float t) const;
private:
float linear (float start, float end, float t) const;
float easeIn (float start, float end, float t) const;
float easeOut (float start, float end, float t) const;
float easeInOut (float start, float end, float t) const;
private:
Feather ();
Feather (const Feather&);
Feather& operator= (const Feather&);
private:
const TerrainGeneratorFeatherFunction featherFunction;
};
//===================================================================
inline Feather::Feather (TerrainGeneratorFeatherFunction newFeatherFunction) :
featherFunction (newFeatherFunction)
{
}
//-------------------------------------------------------------------
inline Feather::~Feather ()
{
}
//-------------------------------------------------------------------
inline float Feather::linear (const float start, const float end, const float t) const
{
return linearInterpolate (start, end, t);
}
//-------------------------------------------------------------------
inline float Feather::easeIn (const float start, const float end, const float t) const
{
return linearInterpolate (start, end, sqr (t));
}
//-------------------------------------------------------------------
inline float Feather::easeOut (const float start, const float end, const float t) const
{
return linearInterpolate (start, end, sqrt (t));
}
//-------------------------------------------------------------------
inline float Feather::easeInOut (const float start, const float end, const float t) const
{
const float a = ((3.0f - (2.0f * t)) * t * t);
return linearInterpolate (start, end, a);
}
//-------------------------------------------------------------------
inline float Feather::feather (const float start, const float end, const float t) const
{
switch (featherFunction)
{
case TGFF_linear:
return linear (start, end, t);
case TGFF_easeIn:
return easeIn (start, end, t);
case TGFF_easeOut:
return easeOut (start, end, t);
case TGFF_easeInOut:
return easeInOut (start, end, t);
case TGFF_COUNT:
default:
DEBUG_FATAL (true, ("invalid feather function"));
return 0.0f; //lint !e527 //unreachable
}
}
//===================================================================
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,392 @@
//===================================================================
//
// Filter.h
// asommers 9-30-2000
//
// copyright 2000, verant interactive
//
//===================================================================
#ifndef INCLUDED_Filter_H
#define INCLUDED_Filter_H
//===================================================================
#include "sharedTerrain/TerrainGenerator.h"
//===================================================================
//
// FilterHeight
//
class FilterHeight : public TerrainGenerator::Filter
{
private:
float lowHeight;
float highHeight;
private:
void load_0000 (Iff& iff);
void load_0001 (Iff& iff);
void load_0002 (Iff& iff);
private:
FilterHeight (const FilterHeight& rhs);
FilterHeight& operator= (const FilterHeight& rhs);
public:
FilterHeight ();
virtual ~FilterHeight ();
virtual float isWithin (float worldX, float worldZ, int x, int z, const TerrainGenerator::GeneratorChunkData& generatorChunkData) const;
virtual void load (Iff& iff);
virtual void save (Iff& iff) const;
float getLowHeight () const;
void setLowHeight (float newLowHeight);
float getHighHeight () const;
void setHighHeight (float newHighHeight);
};
//-------------------------------------------------------------------
inline float FilterHeight::getLowHeight () const
{
return lowHeight;
}
//-------------------------------------------------------------------
inline float FilterHeight::getHighHeight () const
{
return highHeight;
}
//-------------------------------------------------------------------
//
// FilterFractal
//
class FilterFractal : public TerrainGenerator::Filter
{
private:
//-- not accessible
mutable const MultiFractal* m_multiFractal;
mutable int m_cachedFamilyId;
//-- accessible
int m_familyId;
float m_scaleY;
float m_lowFractalLimit;
float m_highFractalLimit;
private:
void load_0000 (Iff& iff, FractalGroup& fractalGroup);
void load_0001 (Iff& iff, FractalGroup& fractalGroup);
void load_0002 (Iff& iff, FractalGroup& fractalGroup);
void load_0003 (Iff& iff, FractalGroup& fractalGroup);
void load_0004 (Iff& iff, FractalGroup& fractalGroup);
void load_0005 (Iff& iff);
private:
FilterFractal (const FilterFractal& rhs);
FilterFractal& operator= (const FilterFractal& rhs);
public:
FilterFractal ();
virtual ~FilterFractal ();
virtual float isWithin (float worldX, float worldZ, int x, int z, const TerrainGenerator::GeneratorChunkData& generatorChunkData) const;
virtual void load (Iff& iff, FractalGroup& fractalGroup);
virtual void save (Iff& iff) const;
int getFamilyId () const;
void setFamilyId (int id);
float getScaleY () const;
void setScaleY (float newScaleY);
float getLowFractalLimit () const;
void setLowFractalLimit (float newLowFractalLimit);
float getHighFractalLimit () const;
void setHighFractalLimit (float newHighFractalLimit);
};
//-------------------------------------------------------------------
inline int FilterFractal::getFamilyId () const
{
return m_familyId;
}
//-------------------------------------------------------------------
inline float FilterFractal::getScaleY () const
{
return m_scaleY;
}
//-------------------------------------------------------------------
inline float FilterFractal::getLowFractalLimit () const
{
return m_lowFractalLimit;
}
//-------------------------------------------------------------------
inline float FilterFractal::getHighFractalLimit () const
{
return m_highFractalLimit;
}
//-------------------------------------------------------------------
//
// FilterSlope
//
class FilterSlope : public TerrainGenerator::Filter
{
private:
//-- accessible
float maximumAngle;
float minimumAngle;
//-- not accessible
float sinMaxAngle;
float sinMinAngle;
private:
void load_0000 (Iff& iff);
void load_0001 (Iff& iff);
void load_0002 (Iff& iff);
private:
FilterSlope (const FilterSlope& rhs);
FilterSlope& operator= (const FilterSlope& rhs);
public:
FilterSlope ();
virtual ~FilterSlope ();
virtual float isWithin (float worldX, float worldZ, int x, int z, const TerrainGenerator::GeneratorChunkData& generatorChunkData) const;
virtual void load (Iff& iff);
virtual void save (Iff& iff) const;
virtual bool needsNormals () const;
float getMinimumAngle () const;
void setMinimumAngle (float newMinimumAngle);
float getMaximumAngle () const;
void setMaximumAngle (float newMaximumAngle);
};
//-------------------------------------------------------------------
inline float FilterSlope::getMinimumAngle () const
{
return minimumAngle;
}
//-------------------------------------------------------------------
inline float FilterSlope::getMaximumAngle () const
{
return maximumAngle;
}
//-------------------------------------------------------------------
//
// FilterDirection
//
class FilterDirection : public TerrainGenerator::Filter
{
private:
//-- accessible
float maximumAngle;
float minimumAngle;
//-- inaccessible
float maximumFeatherAngle;
float minimumFeatherAngle;
private:
void load_0000 (Iff& iff);
private:
FilterDirection (const FilterDirection& rhs);
FilterDirection& operator= (const FilterDirection& rhs);
public:
FilterDirection ();
virtual ~FilterDirection ();
virtual float isWithin (float worldX, float worldZ, int x, int z, const TerrainGenerator::GeneratorChunkData& generatorChunkData) const;
virtual void load (Iff& iff);
virtual void save (Iff& iff) const;
virtual bool needsNormals () const;
float getMinimumAngle () const;
void setMinimumAngle (float newMinimumAngle);
float getMaximumAngle () const;
void setMaximumAngle (float newMaximumAngle);
};
//-------------------------------------------------------------------
inline float FilterDirection::getMinimumAngle () const
{
return minimumAngle;
}
//-------------------------------------------------------------------
inline float FilterDirection::getMaximumAngle () const
{
return maximumAngle;
}
//-------------------------------------------------------------------
//
// FilterShader
//
class FilterShader : public TerrainGenerator::Filter
{
private:
int familyId;
private:
void load_0000 (Iff& iff);
private:
FilterShader (const FilterShader& rhs);
FilterShader& operator= (const FilterShader& rhs);
public:
FilterShader ();
virtual ~FilterShader ();
virtual float isWithin (float worldX, float worldZ, int x, int z, const TerrainGenerator::GeneratorChunkData& generatorChunkData) const;
virtual void load (Iff& iff);
virtual void save (Iff& iff) const;
virtual bool needsShaders () const;
int getFamilyId () const;
void setFamilyId (int id);
};
//-------------------------------------------------------------------
inline int FilterShader::getFamilyId () const
{
return familyId;
}
//-------------------------------------------------------------------
//
// FilterBitmap
//
class BitmapGroup;
class FilterBitmap : public TerrainGenerator::Filter
{
private:
int m_familyId;
float m_lowBitmapLimit;
float m_highBitmapLimit;
Rectangle2d m_extent;
float m_gain;
private:
void load_0000 (Iff& iff);
void load_0001 (Iff& iff);
private:
FilterBitmap (const FilterBitmap& rhs);
FilterBitmap& operator= (const FilterBitmap& rhs);
public:
FilterBitmap ();
virtual ~FilterBitmap ();
virtual float isWithin (float worldX, float worldZ, int x, int z, const TerrainGenerator::GeneratorChunkData& generatorChunkData) const;
virtual void load (Iff& iff/*, BitmapGroup& bitmapGroup*/);
virtual void save (Iff& iff) const;
int getFamilyId () const;
void setFamilyId (int id);
float getLowBitmapLimit () const;
void setLowBitmapLimit (float newLowBitmapLimit);
float getHighBitmapLimit () const;
void setHighBitmapLimit (float newHighBitmapLimit);
float getGain () const;
void setGain (float newValue);
void setExtent(const Rectangle2d& rect);
};
//-------------------------------------------------------------------
inline int FilterBitmap::getFamilyId () const
{
return m_familyId;
}
//-------------------------------------------------------------------
inline float FilterBitmap::getLowBitmapLimit () const
{
return m_lowBitmapLimit;
}
//-------------------------------------------------------------------
inline float FilterBitmap::getHighBitmapLimit () const
{
return m_highBitmapLimit;
}
//-------------------------------------------------------------------
inline float FilterBitmap::getGain () const
{
return m_gain;
}
//===================================================================
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,167 @@
//===================================================================
//
// FloraGroup.h
// asommers 9-17-2000
//
// copyright 2000, verant interactive
//
//--
//
// A FloraGroup contains lists of families of meshes organized by id.
// A flora family is a list of valid appearances for a specified id. The flora
// family also stores the name of the flora, and its appearanceTemplate.
// The flora group will return created appearances for use with the terrain
// system. In the event that requested flora family id does not
// exist, the flora group will return a [clearly visible] default flora.
// Families will only create flora when they are chosen.
//
//===================================================================
#ifndef FLORAGROUP_H
#define FLORAGROUP_H
//===================================================================
#include "sharedFoundation/ArrayList.h"
#include "sharedMath/PackedRgb.h"
class Iff;
class AppearanceTemplate;
//===================================================================
class FloraGroup
{
public:
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//
// Info holds info about flora for the flora map
//
struct Info
{
public:
Info ();
~Info ();
int getFamilyId () const;
void setFamilyId (int familyId);
float getChildChoice () const;
void setChildChoice (float childChoice);
private:
uint8 m_familyId;
uint8 m_childChoice;
};
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//
// FamilyChildData allows creation of FloraGroups
//
struct FamilyChildData
{
public:
int familyId;
float weight;
const char* appearanceTemplateName;
bool shouldSway;
float period;
float displacement;
bool alignToTerrain;
bool shouldScale;
float minimumScale;
float maximumScale;
public:
FamilyChildData ();
~FamilyChildData ();
};
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
private:
class Family;
private:
//-- list of families
ArrayList<Family*> familyList;
//--
PackedRgb errorFamilyColor;
private:
int findFamilyIndex (int familyId) const;
int findFamilyIndex (const PackedRgb& desiredColor) const;
void load_0001 (Iff& iff);
void load_0002 (Iff& iff);
void load_0003 (Iff& iff);
void load_0004 (Iff& iff);
void load_0005 (Iff& iff);
void load_0006 (Iff& iff);
void load_0007 (Iff& iff);
void load_0008 (Iff& iff);
private:
FloraGroup (const FloraGroup& rhs);
FloraGroup& operator= (const FloraGroup& rhs);
public:
FloraGroup ();
~FloraGroup ();
const Info getDefaultFlora () const;
const Info chooseFlora (int familyId) const;
const Info chooseFlora (const PackedRgb& desiredColor) const;
FamilyChildData const & createFlora(FloraGroup::Info const & rfgi) const;
//-- creation routines (for editor)
void load (Iff& iff);
void save (Iff& iff) const;
void removeAllFamilies ();
//-- family id routines
void addFamily (int familyId, const char* name, const PackedRgb& color);
void removeFamily (int familyId);
void addChild (const FamilyChildData& familyChildData);
void removeChild (const FamilyChildData& familyChildData);
bool hasFamily (int familyId) const;
bool hasFamily (const char* name) const;
int getFamilyId (const PackedRgb& desiredColor) const;
int getFamilyId (const char* name) const;
const char* getFamilyName (int familyId) const;
void setFamilyName (int familyId, const char* name);
const PackedRgb& getFamilyColor (int familyId) const;
void setFamilyColor (int familyId, const PackedRgb& prgb);
int getFamilyNumberOfChildren (int familyId) const;
void renameChild (int familyId, const char* oldName, const char* newName);
FamilyChildData const & getFamilyChild(int familyId, char const * childName) const;
FamilyChildData const & getFamilyChild(int familyId, int childIndex) const;
void setFamilyChild (int familyId, const FamilyChildData& familyChildData);
float getFamilyDensity (int familyId) const;
void setFamilyDensity (int familyId, float density);
bool getFamilyFloats (int familyId) const;
void setFamilyFloats (int familyId, bool floats);
//-- family index routines
int getNumberOfFamilies () const;
int getNumberOfChildren (int familyIndex) const;
FamilyChildData const & getChild(int familyIndex, int childIndex) const;
int getFamilyId (int familyIndex) const;
void setFamilyId (int familyIndex, int newId);
};
//===================================================================
#endif
@@ -0,0 +1,478 @@
//===================================================================
//
// FractalGroup.cpp
// asommers 9-17-2000
//
// copyright 2000, verant interactive
//
//===================================================================
#include "sharedTerrain/FirstSharedTerrain.h"
#include "sharedTerrain/FractalGroup.h"
#include "sharedFile/Iff.h"
#include "sharedFractal/MultiFractal.h"
#include "sharedFractal/MultiFractalReaderWriter.h"
#include <map>
#include <string>
#include <cstdio>
//===================================================================
namespace
{
const Tag TAG_MGRP = TAG (M,G,R,P);
const Tag TAG_MFAM = TAG (M,F,A,M);
}
//===================================================================
//
// FractalGroup::Family
//
class FractalGroup::Family
{
public:
explicit Family (int familyId);
~Family ();
const char* getName () const;
void setName (const char* name);
int getFamilyId () const;
void setFamilyId (int familyId);
const MultiFractal& getMultiFractal () const;
MultiFractal& getMultiFractal ();
private:
Family ();
Family (const Family& rhs); //lint -esym (754, Family::Family)
Family& operator= (const Family& rhs); //lint -esym (754, Family::operator=)
private:
char* m_name;
int m_familyId;
MultiFractal m_multiFractal;
};
//-------------------------------------------------------------------
FractalGroup::Family::Family (int familyId) :
m_name (0),
m_familyId (familyId),
m_multiFractal ()
{
}
//-------------------------------------------------------------------
FractalGroup::Family::~Family ()
{
delete [] m_name;
m_name = 0;
}
//-------------------------------------------------------------------
const char* FractalGroup::Family::getName () const
{
return m_name;
}
//-------------------------------------------------------------------
void FractalGroup::Family::setName (const char* name)
{
if (m_name)
{
delete [] m_name;
m_name = 0;
}
if (name)
m_name = DuplicateString (name);
}
//-------------------------------------------------------------------
int FractalGroup::Family::getFamilyId () const
{
return m_familyId;
}
//-------------------------------------------------------------------
void FractalGroup::Family::setFamilyId (int familyId)
{
m_familyId = familyId;
}
//-------------------------------------------------------------------
const MultiFractal& FractalGroup::Family::getMultiFractal () const
{
return m_multiFractal;
}
//-------------------------------------------------------------------
MultiFractal& FractalGroup::Family::getMultiFractal ()
{
return m_multiFractal; //lint !e1536 //-- exposing low access member
}
//===================================================================
//
// FractalGroup
//
FractalGroup::FractalGroup () :
m_familyMap (new FamilyMap)
{
}
//-------------------------------------------------------------------
FractalGroup::~FractalGroup ()
{
//-- delete family list
reset ();
delete m_familyMap;
m_familyMap = 0;
}
//-------------------------------------------------------------------
void FractalGroup::load (Iff& iff)
{
//-- delete family list first
reset ();
//-- load data
if (iff.enterForm (TAG_MGRP, true))
{
DEBUG_WARNING (iff.getCurrentName () != TAG_0000, ("FractalGroup::load - loading old version"));
switch (iff.getCurrentName ())
{
case TAG_0000:
load_0000 (iff);
break;
default:
DEBUG_FATAL (true, ("FractalGroup::load unknown tag"));
}
iff.exitForm ();
}
}
//-------------------------------------------------------------------
void FractalGroup::save (Iff& iff) const
{
iff.insertForm (TAG_MGRP);
iff.insertForm (TAG_0000);
for (FamilyMap::iterator iter = m_familyMap->begin (); iter != m_familyMap->end (); ++iter)
{
const Family* family = iter->second;
iff.insertForm (TAG_MFAM);
iff.insertChunk (TAG_DATA);
iff.insertChunkData (static_cast<int32> (family->getFamilyId ()));
iff.insertChunkString (family->getName ());
iff.exitChunk ();
MultiFractalReaderWriter::save (iff, family->getMultiFractal ());
iff.exitForm ();
}
iff.exitForm ();
iff.exitForm ();
}
//-------------------------------------------------------------------
void FractalGroup::reset ()
{
for (FamilyMap::iterator iter = m_familyMap->begin (); iter != m_familyMap->end (); ++iter)
delete iter->second;
m_familyMap->clear ();
}
//-------------------------------------------------------------------
void FractalGroup::prepare (int cacheX, int cacheY)
{
for (FamilyMap::iterator iter = m_familyMap->begin (); iter != m_familyMap->end (); ++iter)
iter->second->getMultiFractal ().allocateCache (cacheX, cacheY);
}
//-------------------------------------------------------------------
const char* FractalGroup::getFamilyName (int familyId) const
{
const Family* const family = getFamily (familyId);
return family->getName ();
}
//-------------------------------------------------------------------
void FractalGroup::setFamilyName (int familyId, const char* name)
{
Family* const family = getFamily (familyId);
family->setName (name);
}
//-------------------------------------------------------------------
const MultiFractal* FractalGroup::getFamilyMultiFractal (int familyId) const
{
const Family* const family = getFamily (familyId);
return &family->getMultiFractal ();
}
//-------------------------------------------------------------------
MultiFractal* FractalGroup::getFamilyMultiFractal (int familyId)
{
Family* const family = getFamily (familyId);
return &family->getMultiFractal ();
}
//-------------------------------------------------------------------
void FractalGroup::addFamily (int familyId, const char* name)
{
DEBUG_FATAL (getFamily (familyId) != 0, ("family with id %i already exists", familyId));
Family* family = new Family (familyId);
family->setName (name);
IGNORE_RETURN (m_familyMap->insert (FamilyMap::value_type (familyId, family)));
}
//-------------------------------------------------------------------
void FractalGroup::removeFamily (int familyId)
{
FamilyMap::iterator iter = m_familyMap->find (familyId);
DEBUG_FATAL (iter == m_familyMap->end (), ("family with id %i not found", familyId));
m_familyMap->erase (iter);
}
//-------------------------------------------------------------------
bool FractalGroup::hasFamily (int familyId) const
{
return getFamily (familyId) != 0;
}
//-------------------------------------------------------------------
bool FractalGroup::findFamily (const char* name, int& familyId) const
{
const Family* const family = getFamily (name);
if (family)
familyId = family->getFamilyId ();
return family != 0;
}
//-------------------------------------------------------------------
int FractalGroup::getNumberOfFamilies () const
{
return static_cast<int> (m_familyMap->size ());
}
//-------------------------------------------------------------------
const FractalGroup::Family* FractalGroup::getFamily (int familyId) const
{
FamilyMap::const_iterator iter = m_familyMap->find (familyId);
if (iter != m_familyMap->end ())
return iter->second;
return 0;
}
//-------------------------------------------------------------------
FractalGroup::Family* FractalGroup::getFamily (int familyId)
{
FamilyMap::iterator iter = m_familyMap->find (familyId);
if (iter != m_familyMap->end ())
return iter->second;
return 0;
}
//-------------------------------------------------------------------
const FractalGroup::Family* FractalGroup::getFamily (const char* familyName) const
{
FamilyMap::iterator iter = m_familyMap->begin ();
for (; iter != m_familyMap->end (); ++iter)
{
const Family* const family = iter->second;
if (_stricmp (familyName, family->getName ()) == 0)
return family;
}
return 0;
}
//-------------------------------------------------------------------
FractalGroup::Family* FractalGroup::getFamily (const char* familyName)
{
FamilyMap::iterator iter = m_familyMap->begin ();
for (; iter != m_familyMap->end (); ++iter)
{
Family* const family = iter->second;
if (_stricmp (familyName, family->getName ()) == 0)
return family;
}
return 0;
}
//-------------------------------------------------------------------
void FractalGroup::setFamilyId (int familyIndex, int familyId)
{
VALIDATE_RANGE_INCLUSIVE_EXCLUSIVE (0, familyIndex, getNumberOfFamilies ());
Family* const family = getFamily (familyIndex);
NOT_NULL (family);
family->setFamilyId (familyId);
}
//-------------------------------------------------------------------
void FractalGroup::load_0000 (Iff& iff)
{
iff.enterForm (TAG_0000);
int n = iff.getNumberOfBlocksLeft ();
int i;
for (i = 0; i < n; i++)
{
iff.enterForm (TAG_MFAM);
iff.enterChunk (TAG_DATA);
int familyId = iff.read_int32 ();
//-- see if family id is already in use
DEBUG_FATAL (getFamily (familyId) != 0, ("EnvironmentGroup::load familyId %i is already in use", familyId));
char* nameBuffer = iff.read_string ();
//-- add family
addFamily (familyId, nameBuffer);
delete [] nameBuffer;
iff.exitChunk ();
Family* const family = getFamily (familyId);
NOT_NULL (family);
MultiFractalReaderWriter::load (iff, family->getMultiFractal ());
iff.exitForm ();
} //lint !e429 //-- family not freed or returned
iff.exitForm ();
}
//-------------------------------------------------------------------
int FractalGroup::getFamilyId (int familyIndex) const
{
VALIDATE_RANGE_INCLUSIVE_EXCLUSIVE (0, familyIndex, static_cast<int> (m_familyMap->size ()));
FamilyMap::iterator iter = m_familyMap->begin ();
int i = 0;
for (; i < familyIndex || iter == m_familyMap->end (); ++i, ++iter)
;
DEBUG_FATAL (iter == m_familyMap->end (), (""));
return iter->second->getFamilyId ();
}
//-------------------------------------------------------------------
int FractalGroup::createFamily (const MultiFractal* multiFractal, const char* baseName)
{
NOT_NULL (multiFractal);
FamilyMap::iterator iter = m_familyMap->begin ();
for (; iter != m_familyMap->end (); ++iter)
{
const Family* const family = iter->second;
if (family->getMultiFractal () == *multiFractal)
return family->getFamilyId ();
}
const int familyId = createUniqueFamilyId ();
std::string familyName = createUniqueFamilyName (baseName);
addFamily (familyId, familyName.c_str ());
Family* const family = getFamily (familyId);
NOT_NULL (family);
family->getMultiFractal () = *multiFractal;
return familyId;
}
//-------------------------------------------------------------------
int FractalGroup::createUniqueFamilyId () const
{
int familyId = 1;
while (getFamily (familyId) != 0)
++familyId;
return familyId;
}
//-------------------------------------------------------------------
std::string FractalGroup::createUniqueFamilyName (const char* baseName) const
{
char familyName [1000];
int i = 0;
do
{
++i;
sprintf (familyName, "%s_%i", baseName, i);
}
while (getFamily (familyName) != 0);
return std::string (familyName);
}
//===================================================================
@@ -0,0 +1,81 @@
//===================================================================
//
// FractalGroup.h
// asommers 9-17-2000
//
// copyright 2000, verant interactive
//
//===================================================================
#ifndef INCLUDED_FractalGroup_H
#define INCLUDED_FractalGroup_H
//===================================================================
class Iff;
class MultiFractal;
//===================================================================
class FractalGroup
{
public:
FractalGroup ();
~FractalGroup ();
//-- creation routines (for editor)
void load (Iff& iff);
void save (Iff& iff) const;
void reset ();
void prepare (int cacheX, int cacheY);
//--
const char* getFamilyName (int familyId) const;
void setFamilyName (int familyId, const char* name);
const MultiFractal* getFamilyMultiFractal (int familyId) const;
MultiFractal* getFamilyMultiFractal (int familyId);
//-- family id routines
void addFamily (int familyId, const char* name);
void removeFamily (int familyId);
bool hasFamily (int familyId) const;
bool findFamily (const char* name, int& familyId) const;
//-- family index routines
int getNumberOfFamilies () const;
int getFamilyId (int familyIndex) const;
void setFamilyId (int familyIndex, int newId);
//-- used to convert from the old terrain format to the new terrain format
int createFamily (const MultiFractal* multiFractal, const char* baseName);
private:
//-- list of families
class Family;
typedef stdmap<int, Family*>::fwd FamilyMap;
FamilyMap* m_familyMap;
private:
const Family* getFamily (int familyId) const;
Family* getFamily (int familyId);
const Family* getFamily (const char* familyName) const;
Family* getFamily (const char* familyName);
int createUniqueFamilyId () const;
std::string createUniqueFamilyName (const char* baseName) const;
void load_0000 (Iff& iff);
private:
FractalGroup (const FractalGroup& rhs);
FractalGroup& operator= (const FractalGroup& rhs);
};
//===================================================================
#endif
@@ -0,0 +1,488 @@
//===================================================================
//
// HeightData.cpp
// asommers 2001-08-02
//
// copyright 2001, sony online entertainment
//
//===================================================================
#include "sharedTerrain/FirstSharedTerrain.h"
#include "sharedTerrain/HeightData.h"
#include "sharedFile/Iff.h"
#include "sharedFoundation/PointerDeleter.h"
#include "sharedFoundation/VoidMemberFunction.h"
#include "sharedMath/Vector.h"
#include "sharedMath/Vector2d.h"
#include <algorithm>
#include <vector>
//===================================================================
static const Tag TAG_ROAD = TAG (R,O,A,D);
static const Tag TAG_SGMT = TAG (S,G,M,T);
static const Tag TAG_HDTA = TAG (H,D,T,A);
//===================================================================
class HeightData::Segment
{
public:
Segment ();
~Segment ();
int getNumberOfPoints () const;
const Vector& getPoint (int index) const;
void setPoint (int index, const Vector& point);
bool find (const Vector2d& point, float& result) const;
void addPoint (const Vector& point);
void clear ();
void load (Iff& iff);
void save (Iff& iff);
void createRoadData ();
private:
Segment (const Segment&); //lint -esym (754, Segment::Segment)
Segment& operator= (const Segment&); //lint -esym (754, Segment::operator=)
private:
typedef std::vector<Vector> PointList;
PointList m_pointList;
};
//-------------------------------------------------------------------
HeightData::Segment::Segment () :
m_pointList ()
{
}
//-------------------------------------------------------------------
HeightData::Segment::~Segment ()
{
}
//-------------------------------------------------------------------
int HeightData::Segment::getNumberOfPoints () const
{
return static_cast<int> (m_pointList.size ());
}
//-------------------------------------------------------------------
const Vector& HeightData::Segment::getPoint (int index) const
{
DEBUG_FATAL (index < 0 || index >= static_cast<int> (m_pointList.size ()), ("index out of range %i <= %i < %i", 0, index, m_pointList.size ()));
return m_pointList [static_cast<uint> (index)];
}
//-------------------------------------------------------------------
void HeightData::Segment::setPoint (int index, const Vector& point)
{
DEBUG_FATAL (index < 0 || index >= static_cast<int> (m_pointList.size ()), ("index out of range %i <= %i < %i", 0, index, m_pointList.size ()));
m_pointList [static_cast<uint> (index)] = point;
}
//-------------------------------------------------------------------
bool HeightData::Segment::find (const Vector2d& oposition, float& result) const
{
Vector2d position = oposition;
#if 1
{
const float x0 = std::min (m_pointList.begin ()->x, m_pointList.back ().x);
const float z0 = std::min (m_pointList.begin ()->z, m_pointList.back ().z);
const float x1 = std::max (m_pointList.begin ()->x, m_pointList.back ().x);
const float z1 = std::max (m_pointList.begin ()->z, m_pointList.back ().z);
// DEBUG_FATAL (position.x < x0 || position.x > x1 || position.y < z0 || position.y > z1, ("position out of range"));
position.x = clamp (x0, position.x, x1);
position.y = clamp (z0, position.y, z1);
}
#endif
const float width = m_pointList.back ().x - m_pointList.begin ()->x;
const float height = m_pointList.back ().z - m_pointList.begin ()->z;
if (fabsf (width) >= fabsf (height))
{
if (width >= 0)
{
DEBUG_FATAL (width == 0, ("this can't happen"));
//-- go from -x to +x
PointList::const_iterator current = m_pointList.begin ();
PointList::const_iterator previous = current;
for (; current != m_pointList.end () && current->x < position.x; previous = current, ++current)
;
DEBUG_FATAL (current == m_pointList.begin (), ("couldn't straddle begin"));
DEBUG_FATAL (current == m_pointList.end (), ("couldn't straddle end"));
const float t = (position.x - previous->x) / (current->x - previous->x);
result = linearInterpolate (previous->y, current->y, t);
}
else
{
//-- go from +x to -x
PointList::const_reverse_iterator current = m_pointList.rbegin ();
PointList::const_reverse_iterator previous = current;
for (; current != m_pointList.rend () && current->x < position.x; previous = current, ++current)
;
DEBUG_FATAL (current == m_pointList.rbegin (), ("couldn't straddle rbegin"));
DEBUG_FATAL (current == m_pointList.rend (), ("couldn't straddle rend"));
const float t = (position.x - previous->x) / (current->x - previous->x);
result = linearInterpolate (previous->y, current->y, t);
}
}
else
{
if (height >= 0)
{
DEBUG_FATAL (height == 0, ("this can't happen"));
//-- go from -z to +z
PointList::const_iterator current = m_pointList.begin ();
PointList::const_iterator previous = current;
for (; current != m_pointList.end () && current->z < position.y; previous = current, ++current)
;
DEBUG_FATAL (current == m_pointList.begin (), ("couldn't straddle begin"));
DEBUG_FATAL (current == m_pointList.end (), ("couldn't straddle end"));
const float t = (position.y - previous->z) / (current->z - previous->z);
result = linearInterpolate (previous->y, current->y, t);
}
else
{
//-- go from +z to -z
PointList::const_reverse_iterator current = m_pointList.rbegin ();
PointList::const_reverse_iterator previous = current;
for (; current != m_pointList.rend () && current->z < position.y; previous = current, ++current)
;
DEBUG_FATAL (current == m_pointList.rbegin (), ("couldn't straddle rbegin"));
DEBUG_FATAL (current == m_pointList.rend (), ("couldn't straddle rend"));
const float t = (position.y - previous->z) / (current->z - previous->z);
result = linearInterpolate (previous->y, current->y, t);
}
}
return true;
}
//-------------------------------------------------------------------
void HeightData::Segment::addPoint (const Vector& point)
{
m_pointList.push_back (point);
}
//-------------------------------------------------------------------
void HeightData::Segment::clear ()
{
m_pointList.clear ();
}
//-------------------------------------------------------------------
void HeightData::Segment::load (Iff& iff)
{
iff.enterChunk (TAG_SGMT);
const int n = iff.getChunkLengthLeft (static_cast<int> (sizeof (Vector)));
int i;
for (i = 0; i < n; ++i)
m_pointList.push_back (iff.read_floatVector ());
iff.exitChunk (TAG_SGMT);
}
//-------------------------------------------------------------------
void HeightData::Segment::save (Iff& iff)
{
iff.insertChunk (TAG_SGMT);
uint i;
for (i = 0; i < m_pointList.size (); ++i)
iff.insertChunkFloatVector (m_pointList [i]);
iff.exitChunk (TAG_SGMT);
}
//-------------------------------------------------------------------
void HeightData::Segment::createRoadData ()
{
//-- road data is an averaged original data
if (m_pointList.size () > 3)
{
std::vector<Vector> newPointList;
newPointList.push_back (m_pointList [0]);
unsigned int i;
for (i = 1; i < m_pointList.size () - 1; ++i)
{
const float y = (m_pointList [i - 1].y + m_pointList [i].y + m_pointList [i + 1].y) / 3.f;
newPointList.push_back (Vector (m_pointList [i].x, y, m_pointList [i].z));
}
newPointList.push_back (m_pointList [i]);
m_pointList.swap (newPointList);
}
}
//===================================================================
HeightData::HeightData () :
m_segmentList (NON_NULL (new SegmentList)),
m_needsRecalculateExtents (true)
{
}
//-------------------------------------------------------------------
HeightData::~HeightData ()
{
clear ();
delete m_segmentList;
m_segmentList = 0;
}
//-------------------------------------------------------------------
void HeightData::load (Iff& iff)
{
if (! (iff.enterForm (TAG_ROAD, true) || iff.enterForm (TAG_HDTA, true)))
return;
clear ();
switch (iff.getCurrentName ())
{
case TAG_0000:
load_0000 (iff);
break;
case TAG_0001:
load_0001 (iff);
break;
default:
FATAL (true, ("invalid form"));
}
iff.exitForm ();
recalculateExtents ();
}
//-------------------------------------------------------------------
void HeightData::load_0000 (Iff& iff)
{
addSegment ();
iff.enterChunk (TAG_0000);
const int n = iff.getChunkLengthLeft (static_cast<int> (sizeof (Vector)));
int i;
for (i = 0; i < n; ++i)
addPoint (iff.read_floatVector ());
iff.exitChunk (TAG_0000);
}
//-------------------------------------------------------------------
void HeightData::load_0001 (Iff& iff)
{
iff.enterForm (TAG_0001);
int numberOfSegments = iff.getNumberOfBlocksLeft ();
while (numberOfSegments-- > 0)
{
addSegment ();
m_segmentList->back ()->load (iff);
}
iff.exitForm (TAG_0001);
}
//-------------------------------------------------------------------
void HeightData::save (Iff& iff) const
{
iff.insertForm (TAG_HDTA);
iff.insertForm (TAG_0001);
uint i;
for (i = 0; i < m_segmentList->size (); ++i)
(*m_segmentList) [i]->save (iff);
iff.exitForm (TAG_0001);
iff.exitForm (TAG_HDTA);
}
//-------------------------------------------------------------------
void HeightData::clear ()
{
std::for_each (m_segmentList->begin (), m_segmentList->end (), PointerDeleter ());
m_segmentList->clear ();
}
//-------------------------------------------------------------------
void HeightData::addSegment ()
{
m_segmentList->push_back (new Segment ());
}
//-------------------------------------------------------------------
void HeightData::addPoint (const Vector& point)
{
m_segmentList->back ()->addPoint (point);
m_needsRecalculateExtents = true;
}
//-------------------------------------------------------------------
int HeightData::getNumberOfSegments () const
{
return static_cast<int> (m_segmentList->size ());
}
//-------------------------------------------------------------------
int HeightData::getNumberOfPoints (int segmentIndex) const
{
if (m_segmentList->size ())
{
DEBUG_FATAL (segmentIndex < 0 || segmentIndex >= static_cast<int> (m_segmentList->size ()), ("index out of range %i <= %i < %i", 0, segmentIndex, m_segmentList->size ()));
return (*m_segmentList) [static_cast<uint> (segmentIndex)]->getNumberOfPoints ();
}
return 0;
}
//-------------------------------------------------------------------
const Vector& HeightData::getPoint (int segmentIndex, int pointIndex) const
{
if (m_segmentList->size ())
{
DEBUG_FATAL (segmentIndex < 0 || segmentIndex >= static_cast<int> (m_segmentList->size ()), ("index out of range %i <= %i < %i", 0, segmentIndex, m_segmentList->size ()));
return (*m_segmentList) [static_cast<uint> (segmentIndex)]->getPoint (pointIndex);
}
return Vector::zero;
}
//-------------------------------------------------------------------
bool HeightData::find (int segmentIndex, const Vector2d& position, float& result) const
{
if (m_segmentList->size ())
{
DEBUG_FATAL (segmentIndex < 0 || segmentIndex >= static_cast<int> (m_segmentList->size ()), ("index out of range %i <= %i < %i", 0, segmentIndex, m_segmentList->size ()));
return (*m_segmentList) [static_cast<uint> (segmentIndex)]->find (position, result);
}
return false;
}
//-------------------------------------------------------------------
void HeightData::recalculateExtents ()
{
m_needsRecalculateExtents = false;
}
//-------------------------------------------------------------------
void HeightData::createRoadData ()
{
uint i;
for (i = 1; i < m_segmentList->size (); ++i)
(*m_segmentList) [i]->setPoint (0, (*m_segmentList) [i - 1]->getPoint ((*m_segmentList) [i - 1]->getNumberOfPoints () - 1));
std::for_each (m_segmentList->begin (), m_segmentList->end (), VoidMemberFunction (&Segment::createRoadData));
}
//-------------------------------------------------------------------
void HeightData::createRiverData ()
{
//-- river data is a downward-terraced original data
const float epsilon = sin (convertDegreesToRadians (5.f)) * 4.f;
float minimum = FLT_MAX - epsilon;
uint i;
for (i = 0; i < m_segmentList->size (); ++i)
{
Segment* const segment = (*m_segmentList) [i];
int j;
for (j = 0; j < segment->getNumberOfPoints (); ++j)
{
Vector point = segment->getPoint (j);
if (j == 0)
{
if (i == 0)
minimum = point.y;
else
{
point.y = minimum;
segment->setPoint (j, point);
}
}
else
if (point.y >= minimum + epsilon)
{
minimum += epsilon;
point.y = minimum;
segment->setPoint (j, point);
}
else
if (point.y < minimum)
minimum = point.y;
else
{
point.y = minimum;
segment->setPoint (j, point);
}
}
}
}
//===================================================================
@@ -0,0 +1,71 @@
//===================================================================
//
// HeightData.h
// asommers 2001-08-02
//
// copyright 2001, sony online entertainment
//
//===================================================================
#ifndef INCLUDED_HeightData_H
#define INCLUDED_HeightData_H
//===================================================================
class Iff;
class Vector;
class Vector2d;
//===================================================================
class HeightData
{
public:
HeightData ();
~HeightData ();
void load (Iff& iff);
void save (Iff& iff) const;
//-- creation
void clear ();
void addSegment ();
void addPoint (const Vector& point);
//-- query
int getNumberOfSegments () const;
int getNumberOfPoints (int segmentIndex) const;
const Vector& getPoint (int segmentIndex, int pointIndex) const;
bool find (int segmentIndex, const Vector2d& position, float& result) const;
//-- call one of these once all the points have been added
void createRoadData ();
void createRiverData ();
private:
void recalculateExtents ();
private:
void load_0000 (Iff& iff);
void load_0001 (Iff& iff);
private:
HeightData (const HeightData&);
HeightData& operator= (const HeightData&);
private:
class Segment;
typedef stdvector<Segment*>::fwd SegmentList;
SegmentList* m_segmentList;
bool m_needsRecalculateExtents;
};
//===================================================================
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,154 @@
//===================================================================
//
// RadialGroup.h
// asommers 9-17-2000
//
// copyright 2000, verant interactive
//
//===================================================================
#ifndef INCLUDED_RadialGroup_H
#define INCLUDED_RadialGroup_H
//===================================================================
#include "sharedFoundation/ArrayList.h"
#include "sharedMath/PackedRgb.h"
class Iff;
//===================================================================
class RadialGroup
{
public:
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//
// Info holds info about a radial group and its child choice
//
struct Info
{
public:
Info();
~Info();
int getFamilyId() const;
void setFamilyId(int familyId);
float getChildChoice() const;
void setChildChoice(float childChoice);
private:
uint8 m_familyId;
uint8 m_childChoice;
};
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//
// FamilyChildData allows creation of RadialGroups
//
struct FamilyChildData
{
public:
int familyId;
float weight;
const char* shaderTemplateName;
float distance;
float minWidth;
float maxWidth;
float minHeight;
float maxHeight;
bool maintainAspectRatio;
float period;
float displacement;
bool shouldSway;
bool alignToTerrain;
bool createPlus;
public:
FamilyChildData ();
~FamilyChildData ();
};
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
private:
class Family;
private:
ArrayList<Family *> familyList;
PackedRgb errorFamilyColor;
private:
int findFamilyIndex (int familyId) const;
int findFamilyIndex (const PackedRgb& desiredColor) const;
private:
void load_0000 (Iff& iff);
void load_0001 (Iff& iff);
void load_0002 (Iff& iff);
void load_0003 (Iff& iff);
void load_0004 (Iff& iff);
private:
RadialGroup (const RadialGroup& rhs);
RadialGroup& operator= (const RadialGroup& rhs);
public:
RadialGroup ();
~RadialGroup ();
const Info getDefaultRadial () const;
const Info chooseRadial (int familyId) const;
const Info chooseRadial (const PackedRgb& desiredColor) const;
FamilyChildData const & createRadial(RadialGroup::Info const & rfgi) const;
//-- creation routines (for editor)
void load (Iff& iff);
void save (Iff& iff) const;
void removeAllFamilies ();
//-- family id routines
void addFamily (int familyId, const char* name, const PackedRgb& color);
void removeFamily (int familyId);
void addChild (const FamilyChildData& familyChildData);
void removeChild (const FamilyChildData& familyChildData);
bool hasFamily (int familyId) const;
bool hasFamily (const char* name) const;
int getFamilyId (const PackedRgb& desiredColor) const;
int getFamilyId (const char* name) const;
const char* getFamilyName (int familyId) const;
void setFamilyName (int familyId, const char* name);
const PackedRgb& getFamilyColor (int familyId) const;
void setFamilyColor (int familyId, const PackedRgb& prgb);
int getFamilyNumberOfChildren (int familyId) const;
void renameChild (int familyId, const char* oldName, const char* newName);
FamilyChildData const & getFamilyChild(int familyId, char const * childName) const;
FamilyChildData const & getFamilyChild(int familyId, int childIndex) const;
void setFamilyChild (int familyId, const FamilyChildData& familyChildData);
float getFamilyDensity (int familyId) const;
void setFamilyDensity (int familyId, float density);
//-- family index routines
int getNumberOfFamilies () const;
int getNumberOfChildren (int familyIndex) const;
FamilyChildData const & getChild(int familyIndex, int childIndex) const;
int getFamilyId (int familyIndex) const;
void setFamilyId (int familyIndex, int newId);
};
//===================================================================
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,172 @@
//===================================================================
//
// ShaderGroup.h
// asommers 9-17-2000
//
// copyright 2000, verant interactive
//
//--
//
// A ShaderGroup contains lists of families of textures organized by id.
// A shader family is a list of valid shaders for a specified id. The shader
// family also stores the name of the shader, its shaderTemplate, and
// the actual shader. The shader group will return const shaders for use
// with the terrain system. In the event that requested shader does not
// exist, the shader group will return a [clearly visible] default shader.
// Families will only create shaders when they are chosen.
//
//===================================================================
#ifndef SHADERGROUP_H
#define SHADERGROUP_H
//===================================================================
#include "sharedFoundation/ArrayList.h"
#include "sharedMath/PackedRgb.h"
class Iff;
class ObjectTemplate;
//===================================================================
class ShaderGroup
{
public:
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//
// Info holds info about a shader and its priority
//
struct Info
{
public:
Info ();
~Info ();
int getPriority () const;
void setPriority (int priority);
int getFamilyId () const;
void setFamilyId (int familyId);
float getChildChoice () const;
void setChildChoice (float childChoice);
private:
uint8 m_priority;
uint8 m_familyId;
uint8 m_childChoice;
};
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//
// FamilyChildData allows creation of ShaderGroups
//
struct FamilyChildData
{
public:
int familyId;
const char* shaderTemplateName;
float weight;
public:
FamilyChildData ();
~FamilyChildData ();
};
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
private:
class Family;
private:
//-- list of families
ArrayList<Family*> familyList;
//--
PackedRgb errorFamilyColor;
private:
int findFamilyIndex (int familyId) const;
int findFamilyIndex (const PackedRgb& desiredColor) const;
private:
void load_0000 (Iff& iff);
void load_0001 (Iff& iff);
void load_0002 (Iff& iff);
void load_0003 (Iff& iff);
void load_0004 (Iff& iff);
void load_0005 (Iff& iff);
void load_0006 (Iff& iff);
private:
ShaderGroup (const ShaderGroup& rhs);
ShaderGroup& operator= (const ShaderGroup& rhs);
public:
ShaderGroup ();
~ShaderGroup ();
const Info getDefaultShader () const;
const Info chooseShader (int familyId) const;
const Info chooseShader (const PackedRgb& desiredColor) const;
int createShader (const ShaderGroup::Info& sgi) const;
//-- creation routines (for editor)
void load (Iff& iff);
void save (Iff& iff) const;
void removeAllFamilies ();
void loadSurfaceProperties ();
//-- family id routines
void addFamily (int familyId, const char* name, const PackedRgb& color);
void removeFamily (int familyId);
void addChild (const FamilyChildData& familyChildData);
void removeChild (const FamilyChildData& familyChildData);
bool hasFamily (int familyId) const;
bool hasFamily (const char* name) const;
int getFamilyId (const PackedRgb& desiredColor) const;
int getFamilyId (const char* name) const;
const char* getFamilyName (int familyId) const;
void setFamilyName (int familyId, const char* name);
const PackedRgb& getFamilyColor (int familyId) const;
void setFamilyColor (int familyId, const PackedRgb& prgb);
float getFamilyShaderSize (int familyId) const;
void setFamilyShaderSize (int familyId, float meters);
int getFamilyNumberOfChildren (int familyId) const;
void renameChild (int familyId, const char* oldName, const char* newName);
void promoteFamily (int familyId);
void demoteFamily (int familyId);
void promoteChild (int familyId, const char* childName);
void demoteChild (int familyId, const char* childName);
const FamilyChildData getFamilyChild (int familyId, const char* childName) const;
const FamilyChildData getFamilyChild (int familyId, int childIndex) const;
void setFamilyChild (int familyId, const FamilyChildData& familyChildData);
float getFamilyFeatherClamp (int familyId) const;
void setFamilyFeatherClamp (int familyId, float featherClamp);
const char* getFamilySurfacePropertiesName (int familyId) const;
void setFamilySurfacePropertiesName (int familyId, const char* familySurfacePropertiesName);
const ObjectTemplate* getFamilySurfaceProperties (int familyId) const;
//-- family index routines
int getNumberOfFamilies () const;
int getNumberOfChildren (int familyIndex) const;
const FamilyChildData getChild (int familyIndex, int childIndex) const;
int getFamilyId (int familyIndex) const;
void setFamilyId (int familyIndex, int newId);
};
//===================================================================
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,886 @@
//===================================================================
//
// TerrainGenerator.h
// asommers 9-11-2000
//
// copyright 2000, verant interactive
//
//--
//
// figure out:
// 1) if a layer is inactive, it shouldn't be loaded instead of tested
// before use
//
//===================================================================
#ifndef INCLUDED_TerrainGenerator_H
#define INCLUDED_TerrainGenerator_H
//===================================================================
#include "sharedFoundation/ArrayList.h"
#include "sharedFoundation/Tag.h"
#include "sharedMath/Rectangle2d.h"
#include "sharedMath/Vector.h"
#include "sharedRandom/RandomGenerator.h"
#include "sharedTerrain/Array2d.h"
#include "sharedTerrain/BitmapGroup.h"
#include "sharedTerrain/EnvironmentGroup.h"
#include "sharedTerrain/FloraGroup.h"
#include "sharedTerrain/FractalGroup.h"
#include "sharedTerrain/RadialGroup.h"
#include "sharedTerrain/ShaderGroup.h"
#include "sharedTerrain/TerrainGeneratorType.h"
class Shader;
//===================================================================
class TerrainGenerator
{
public:
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//
// GeneratorChunkData is used to request a chunk from the generator
//
struct GeneratorChunkData
{
public:
//-- number of poles also represents the number of valid indices in the chunk maps
int originOffset;
int numberOfPoles;
int upperPad;
float distanceBetweenPoles;
//-- offset into world space for left-rear corner of chunk to build (including the buffer zone)
Vector start;
//-- numberOfPoles x numberOfPoles
Array2d<float>* heightMap;
//-- numberOfPoles x numberOfPoles
Array2d<PackedRgb>* colorMap;
//-- since a tile is two poles, every other entry is skipped
Array2d<ShaderGroup::Info>* shaderMap;
//-- map of flora per tile
Array2d<FloraGroup::Info>* floraStaticCollidableMap;
//-- map of flora per tile
Array2d<FloraGroup::Info>* floraStaticNonCollidableMap;
//-- map of radial flora per tile
Array2d<RadialGroup::Info>* floraDynamicNearMap;
//-- map of radial flora per tile
Array2d<RadialGroup::Info>* floraDynamicFarMap;
//-- map of environment block data per tile
Array2d<EnvironmentGroup::Info>* environmentMap;
//-- used to calculate the plane data and vertex normals
Array2d<Vector>* vertexPositionMap;
//-- the normal at the vertex
Array2d<Vector>* vertexNormalMap;
//-- allows tiles to be excluded
Array2d<bool>* excludeMap;
//-- allows tiles to be passable/not passable
Array2d<bool>* passableMap;
//-- groups
const ShaderGroup* shaderGroup;
const FloraGroup* floraGroup;
const RadialGroup* radialGroup;
const EnvironmentGroup* environmentGroup;
const FractalGroup* fractalGroup;
const BitmapGroup* bitmapGroup;
//-- provides random numbers for choosers and affectors
RandomGenerator *m_legacyRandomGenerator;
//-- internal use only
mutable bool normalsDirtyIUO;
mutable bool shadersDirtyIUO;
mutable Rectangle2d chunkExtentIUO;
private:
GeneratorChunkData (const GeneratorChunkData& rhs);
GeneratorChunkData& operator= (const GeneratorChunkData& rhs);
public:
GeneratorChunkData(bool legacyMode);
~GeneratorChunkData ();
void validate () const;
bool isLegacyMode() const { return m_legacyRandomGenerator!=0; }
};
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//
// CreateChunkBuffer is a scratchpad for generating terrain chunks
//
struct CreateChunkBuffer
{
public:
//-- actual maps
Array2d<float> heightMap;
Array2d<PackedRgb> colorMap;
Array2d<ShaderGroup::Info> shaderMap;
Array2d<FloraGroup::Info> floraStaticCollidableMap;
Array2d<FloraGroup::Info> floraStaticNonCollidableMap;
Array2d<RadialGroup::Info> floraDynamicNearMap;
Array2d<RadialGroup::Info> floraDynamicFarMap;
Array2d<EnvironmentGroup::Info> environmentMap;
Array2d<Vector> vertexPositionMap;
Array2d<Vector> vertexNormalMap;
Array2d<bool> excludeMap;
Array2d<bool> passableMap;
private:
CreateChunkBuffer (const CreateChunkBuffer& rhs);
CreateChunkBuffer& operator= (const CreateChunkBuffer& rhs);
public:
CreateChunkBuffer ();
~CreateChunkBuffer ();
void allocate (int poleCount);
void validate () const;
};
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//
// LayerItem holds tool specific data for all Boundaries, Filters, Affectors, and Layers
//
class LayerItem
{
private:
const Tag m_tag;
bool m_active;
bool m_pruned;
char* m_name;
private:
void load_0000 (Iff& iff);
void load_0001 (Iff& iff);
private:
LayerItem ();
LayerItem (const LayerItem& rhs);
LayerItem& operator= (const LayerItem& rhs);
public:
explicit LayerItem (Tag tag);
virtual ~LayerItem ()=0;
Tag getTag () const;
void setActive (bool active);
bool isActive () const;
void setPruned(bool pruned) { m_pruned=pruned; }
bool isPruned() const { return m_pruned; }
void setName (const char* name);
const char* getName () const;
virtual void prepare ();
virtual void load (Iff& iff);
virtual void save (Iff& iff) const=0;
};
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//
// Boundary is the interface for all boundary types. This could potentially
// be optimized by having the circle as the base type, and only checking
// isWithin for derived types if isWithin for the circle test passes first
// since the circle would be the fastest check.
//
class Boundary : public LayerItem
{
private:
const TerrainGeneratorBoundaryType m_type;
TerrainGeneratorFeatherFunction m_featherFunction;
float m_featherDistance;
private:
Boundary ();
Boundary (const Boundary& rhs);
Boundary& operator= (const Boundary& rhs);
public:
Boundary (Tag tag, TerrainGeneratorBoundaryType type);
virtual ~Boundary ()=0;
TerrainGeneratorBoundaryType getType () const;
TerrainGeneratorFeatherFunction getFeatherFunction () const;
void setFeatherFunction (TerrainGeneratorFeatherFunction featherFunction);
float getFeatherDistance () const;
virtual void setFeatherDistance (float featherDistance);
virtual void rotate (float angle);
virtual void rotate (float angle, const Vector2d& center);
virtual void translate (const Vector2d& translation);
virtual void scale (float scalar);
virtual float isWithin (float worldX, float worldZ) const=0;
virtual void expand (Rectangle2d& extent) const=0;
virtual const Vector2d getCenter () const=0;
virtual bool intersects(const Rectangle2d& other) const=0;
virtual void scanConvertGT(float *o_data, const Rectangle2d &scanArea, int numberOfPoles) const;
//-- run-time rule interface
virtual void setCenter (const Vector2d& center);
virtual void setRotation (float angle);
};
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
class Filter : public LayerItem
{
private:
const TerrainGeneratorFilterType m_type;
TerrainGeneratorFeatherFunction m_featherFunction;
float m_featherDistance;
private:
Filter ();
Filter (const Filter& rhs);
Filter& operator= (const Filter& rhs);
public:
Filter (Tag tag, TerrainGeneratorFilterType type);
virtual ~Filter ()=0;
TerrainGeneratorFilterType getType () const;
TerrainGeneratorFeatherFunction getFeatherFunction () const;
void setFeatherFunction (TerrainGeneratorFeatherFunction featherFunction);
float getFeatherDistance () const;
virtual void setFeatherDistance (float featherDistance);
virtual float isWithin (float worldX, float worldZ, int x, int z, const GeneratorChunkData& generatorChunkData) const=0;
virtual bool needsNormals () const;
virtual bool needsShaders () const;
};
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
class Affector : public LayerItem
{
private:
const TerrainGeneratorAffectorType m_type;
private:
Affector ();
Affector (const Affector& rhs);
Affector& operator= (const Affector& rhs);
public:
Affector (Tag tag, TerrainGeneratorAffectorType type);
virtual ~Affector ()=0;
TerrainGeneratorAffectorType getType () const;
virtual void affect (float worldX, float worldZ, int x, int z, float amount, const GeneratorChunkData& generatorChunkData) const=0;
virtual bool affectsHeight () const;
virtual bool affectsShader () const;
virtual unsigned getAffectedMaps() const=0;
virtual float isWithin (float worldX, float worldZ) const;
};
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
class Layer : public LayerItem
{
public:
struct ProfileData
{
public:
float timeInOverhead;
float timeInBoundaries;
float timeInFilters;
float timeInAffectors;
float timeInSubLayers;
public:
ProfileData ();
~ProfileData ();
bool isWorthCounting () const;
float getLayerTime () const;
float getTotalTime () const;
void reset ();
};
private:
ArrayList<Boundary*> m_boundaryList;
ArrayList<Filter*> m_filterList;
ArrayList<Affector*> m_affectorList;
ArrayList<Layer*> m_subLayerList;
bool m_hasActiveBoundaries;
bool m_hasActiveFilters;
bool m_hasActiveAffectors;
bool m_hasUnprunedAffectors;
bool m_hasActiveLayers;
bool m_hasUnprunedLayers;
bool m_invertBoundaries;
bool m_invertFilters;
bool m_useExtent;
Rectangle2d m_extent;
float m_modificationHeight;
bool m_expanded;
char* m_notes;
private:
mutable ProfileData m_profileData;
private:
void load_0000 (Iff& iff, TerrainGenerator* terrainGenerator); //lint !e1511 // member hides non-virt
void load_0001 (Iff& iff, TerrainGenerator* terrainGenerator); //lint !e1511 // member hides non-virt
void load_0002 (Iff& iff, TerrainGenerator* terrainGenerator); //lint !e1511 // member hides non-virt
void load_0003 (Iff& iff, TerrainGenerator* terrainGenerator); //lint !e1511 // member hides non-virt
void load_0004 (Iff& iff, TerrainGenerator* terrainGenerator); //lint !e1511 // member hides non-virt
void load_ACTN (Iff& iff, TerrainGenerator* terrainGenerator);
void load_ACTN_0000 (Iff& iff, TerrainGenerator* terrainGenerator);
void load_ACTN_0001 (Iff& iff, TerrainGenerator* terrainGenerator);
void load_ACTN_0002 (Iff& iff, TerrainGenerator* terrainGenerator);
private:
Layer (const Layer& rhs);
Layer& operator= (const Layer& rhs);
public:
Layer ();
~Layer ();
void _oldBoundaryTest(float &fuzzyTest, float worldX, float worldZ) const;
void affect (const float *previousAmountMap, const GeneratorChunkData& generatorChunkData) const;
virtual void prepare ();
virtual void load (Iff& iff, TerrainGenerator* terrainGenerator);
virtual void save (Iff& iff) const;
virtual bool prune(unsigned &mapMask, const Rectangle2d &chunkExtentIUO);
bool getInvertBoundaries () const;
void setInvertBoundaries (bool invertBoundaries);
bool getInvertFilters () const;
void setInvertFilters (bool invertFilters);
int getNumberOfBoundaries () const;
const Boundary* getBoundary (int index) const;
Boundary* getBoundary (int index);
void addBoundary (Boundary* boundary);
void removeBoundary (int index);
void removeBoundary (const Boundary* boundary, bool doDelete);
void promoteBoundary (const Boundary* boundary);
void demoteBoundary (const Boundary* boundary);
int getNumberOfFilters () const;
const Filter* getFilter (int index) const;
Filter* getFilter (int index);
void addFilter (Filter* filter);
void removeFilter (int index);
void removeFilter (const Filter* filter, bool doDelete);
void promoteFilter (const Filter* filter);
void demoteFilter (const Filter* filter);
int getNumberOfAffectors () const;
const Affector* getAffector (int index) const;
Affector* getAffector (int index);
void addAffector (Affector* affector);
void removeAffector (int index);
void removeAffector (const Affector* affector, bool doDelete);
int getNumberOfLayers () const;
const Layer* getLayer (int index) const;
Layer* getLayer (int index);
void addLayer (Layer* layer);
void removeLayer (int index);
void removeLayer (const Layer* layer, bool doDelete);
void promoteLayer (const Layer* layer);
void demoteLayer (const Layer* layer);
void calculateExtent ();
bool getUseExtent () const;
const Rectangle2d& getExtent () const;
float getModificationHeight () const;
void setModificationHeight (float modificationHeight);
//-- tool use only
void setExpanded (bool expanded);
bool getExpanded () const;
void resetProfileData ();
const ProfileData& getProfileData () const;
void setNotes (const char* notes);
const char* getNotes () const;
bool computeHasPassableAffectors() const;
};
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
private:
ShaderGroup m_shaderGroup;
FloraGroup m_floraGroup;
RadialGroup m_radialGroup;
EnvironmentGroup m_environmentGroup;
FractalGroup m_fractalGroup;
BitmapGroup m_bitmapGroup;
ArrayList<Layer*> m_layerList;
unsigned m_sampleMaps;
bool m_hasPassableAffectors;
private:
mutable bool m_groupsPrepared;
private:
void _generateVertexPositions(const GeneratorChunkData& generatorChunkData) const;
void affect (const GeneratorChunkData& generatorChunkData) const;
void load_0000 (Iff& iff);
void saveLayerList (Iff& iff, const ArrayList<Layer*>& layerList) const;
void saveLayers (Iff& iff) const;
void calculateExtent ();
private:
TerrainGenerator (const TerrainGenerator& rhs);
TerrainGenerator& operator= (const TerrainGenerator& rhs);
public:
TerrainGenerator ();
~TerrainGenerator ();
// set which maps you are interested in.
// see the TerrainGeneratorMap bit flags
void setMapsToSample(unsigned TGM_flags);
const ShaderGroup& getShaderGroup () const;
ShaderGroup& getShaderGroup ();
const FloraGroup& getFloraGroup () const;
FloraGroup& getFloraGroup ();
const RadialGroup& getRadialGroup () const;
RadialGroup& getRadialGroup ();
const EnvironmentGroup& getEnvironmentGroup () const;
EnvironmentGroup& getEnvironmentGroup ();
const FractalGroup& getFractalGroup () const;
FractalGroup& getFractalGroup ();
const BitmapGroup& getBitmapGroup() const;
BitmapGroup& getBitmapGroup();
//-- layer interface
int getNumberOfLayers () const;
const Layer* getLayer (int index) const;
Layer* getLayer (int index);
void addLayer (Layer* layer);
void removeLayer (int index);
void removeLayer (Layer* layer, bool doDelete);
void promoteLayer (const Layer* layer);
void demoteLayer (const Layer* layer);
void resetProfileData ();
//-- reset the generator (clears shader groups and flora groups and removes all layers)
void reset ();
//-- load the generator
void load (Iff& iff);
//-- save the generator
void save (Iff& iff) const;
//-- prepare should only be called from the tool and is used to validate the data before generation
void prepare ();
//-- fills out data specific to a chunk
void generateChunk (const GeneratorChunkData& generatorChunkData) const;
bool hasPassableAffectors() const;
public:
//-- used internally
static void generatePlaneAndVertexNormals (const GeneratorChunkData& generatorChunkData);
static void synchronizeShaders (const GeneratorChunkData& generatorChunkData);
};
//===================================================================
inline Tag TerrainGenerator::LayerItem::getTag () const
{
return m_tag;
}
//-------------------------------------------------------------------
inline const char* TerrainGenerator::LayerItem::getName () const
{
return m_name;
}
//===================================================================
inline TerrainGeneratorBoundaryType TerrainGenerator::Boundary::getType () const
{
return m_type;
}
//-------------------------------------------------------------------
inline TerrainGeneratorFeatherFunction TerrainGenerator::Boundary::getFeatherFunction () const
{
return m_featherFunction;
}
//-------------------------------------------------------------------
inline float TerrainGenerator::Boundary::getFeatherDistance () const
{
return m_featherDistance;
}
//===================================================================
inline TerrainGeneratorFilterType TerrainGenerator::Filter::getType () const
{
return m_type;
}
//-------------------------------------------------------------------
inline TerrainGeneratorFeatherFunction TerrainGenerator::Filter::getFeatherFunction () const
{
return m_featherFunction;
}
//-------------------------------------------------------------------
inline float TerrainGenerator::Filter::getFeatherDistance () const
{
return m_featherDistance;
}
//===================================================================
inline TerrainGeneratorAffectorType TerrainGenerator::Affector::getType () const
{
return m_type;
}
//===================================================================
inline bool TerrainGenerator::Layer::getInvertBoundaries () const
{
return m_invertBoundaries;
}
//-------------------------------------------------------------------
inline bool TerrainGenerator::Layer::getInvertFilters () const
{
return m_invertFilters;
}
//-------------------------------------------------------------------
inline bool TerrainGenerator::Layer::getExpanded () const
{
return m_expanded;
}
//-------------------------------------------------------------------
inline const char* TerrainGenerator::Layer::getNotes () const
{
return m_notes;
}
//-------------------------------------------------------------------
inline bool TerrainGenerator::Layer::getUseExtent () const
{
return m_useExtent;
}
//-------------------------------------------------------------------
inline const Rectangle2d& TerrainGenerator::Layer::getExtent () const
{
return m_extent;
}
//-------------------------------------------------------------------
inline float TerrainGenerator::Layer::getModificationHeight () const
{
return m_modificationHeight;
}
//-------------------------------------------------------------------
inline int TerrainGenerator::Layer::getNumberOfBoundaries () const
{
return m_boundaryList.getNumberOfElements ();
}
//-------------------------------------------------------------------
inline const TerrainGenerator::Boundary* TerrainGenerator::Layer::getBoundary (int index) const
{
return m_boundaryList [index];
}
//-------------------------------------------------------------------
inline TerrainGenerator::Boundary* TerrainGenerator::Layer::getBoundary (int index)
{
return m_boundaryList [index];
}
//-------------------------------------------------------------------
inline int TerrainGenerator::Layer::getNumberOfFilters () const
{
return m_filterList.getNumberOfElements ();
}
//-------------------------------------------------------------------
inline const TerrainGenerator::Filter* TerrainGenerator::Layer::getFilter (int index) const
{
return m_filterList [index];
}
//-------------------------------------------------------------------
inline TerrainGenerator::Filter* TerrainGenerator::Layer::getFilter (int index)
{
return m_filterList [index];
}
//-------------------------------------------------------------------
inline int TerrainGenerator::Layer::getNumberOfAffectors () const
{
return m_affectorList.getNumberOfElements ();
}
//-------------------------------------------------------------------
inline const TerrainGenerator::Affector* TerrainGenerator::Layer::getAffector (int index) const
{
return m_affectorList [index];
}
//-------------------------------------------------------------------
inline TerrainGenerator::Affector* TerrainGenerator::Layer::getAffector (int index)
{
return m_affectorList [index];
}
//-------------------------------------------------------------------
inline int TerrainGenerator::Layer::getNumberOfLayers () const
{
return m_subLayerList.getNumberOfElements ();
}
//-------------------------------------------------------------------
inline const TerrainGenerator::Layer* TerrainGenerator::Layer::getLayer (int index) const
{
return m_subLayerList[index];
}
//-------------------------------------------------------------------
inline TerrainGenerator::Layer* TerrainGenerator::Layer::getLayer (int index)
{
return m_subLayerList[index];
}
//===================================================================
inline int TerrainGenerator::getNumberOfLayers () const
{
return m_layerList.getNumberOfElements ();
}
//-------------------------------------------------------------------
inline const TerrainGenerator::Layer* TerrainGenerator::getLayer (int index) const
{
return m_layerList [index];
}
//-------------------------------------------------------------------
inline TerrainGenerator::Layer* TerrainGenerator::getLayer (int index)
{
return m_layerList [index];
}
//-------------------------------------------------------------------
inline const ShaderGroup& TerrainGenerator::getShaderGroup () const
{
return m_shaderGroup;
}
//-------------------------------------------------------------------
inline ShaderGroup& TerrainGenerator::getShaderGroup ()
{
return m_shaderGroup; //lint !e1536 // exposing low access member
}
//-------------------------------------------------------------------
inline const FloraGroup& TerrainGenerator::getFloraGroup () const
{
return m_floraGroup;
}
//-------------------------------------------------------------------
inline FloraGroup& TerrainGenerator::getFloraGroup ()
{
return m_floraGroup; //lint !e1536 // exposing low access member
}
//-------------------------------------------------------------------
inline const RadialGroup& TerrainGenerator::getRadialGroup () const
{
return m_radialGroup;
}
//-------------------------------------------------------------------
inline RadialGroup& TerrainGenerator::getRadialGroup ()
{
return m_radialGroup; //lint !e1536 // exposing low access member
}
//-------------------------------------------------------------------
inline const EnvironmentGroup& TerrainGenerator::getEnvironmentGroup () const
{
return m_environmentGroup;
}
//-------------------------------------------------------------------
inline EnvironmentGroup& TerrainGenerator::getEnvironmentGroup ()
{
return m_environmentGroup; //lint !e1536 // exposing low access member
}
//-------------------------------------------------------------------
inline const FractalGroup& TerrainGenerator::getFractalGroup () const
{
return m_fractalGroup;
}
//-------------------------------------------------------------------
inline FractalGroup& TerrainGenerator::getFractalGroup ()
{
return m_fractalGroup; //lint !e1536 // exposing low access member
}
//-------------------------------------------------------------------
inline const BitmapGroup& TerrainGenerator::getBitmapGroup () const
{
return m_bitmapGroup;
}
//-------------------------------------------------------------------
inline BitmapGroup& TerrainGenerator::getBitmapGroup ()
{
return m_bitmapGroup; //lint !e1536 // exposing low access member
}
//-------------------------------------------------------------------
inline bool TerrainGenerator::LayerItem::isActive () const
{
return m_active;
}
//===================================================================
#endif
@@ -0,0 +1,496 @@
//
// TerrainGeneratorLoader.cpp
// asommers 9-11-2000
//
// copyright 2000, verant interactive
//
//-------------------------------------------------------------------
#include "sharedTerrain/FirstSharedTerrain.h"
#include "sharedTerrain/TerrainGeneratorLoader.h"
#include "sharedFile/Iff.h"
#include "sharedTerrain/Affector.h"
#include "sharedTerrain/AffectorColor.h"
#include "sharedTerrain/AffectorEnvironment.h"
#include "sharedTerrain/AffectorFloraDynamic.h"
#include "sharedTerrain/AffectorFloraStatic.h"
#include "sharedTerrain/AffectorRibbon.h"
#include "sharedTerrain/AffectorHeight.h"
#include "sharedTerrain/AffectorPassable.h"
#include "sharedTerrain/AffectorRiver.h"
#include "sharedTerrain/AffectorRoad.h"
#include "sharedTerrain/AffectorShader.h"
#include "sharedTerrain/Boundary.h"
#include "sharedTerrain/Filter.h"
//-------------------------------------------------------------------
void TerrainGeneratorLoader::loadLayerItem (Iff& iff, TerrainGenerator* terrainGenerator, TerrainGenerator::Layer* layer)
{
TerrainGenerator::Boundary* boundary = createBoundary (iff);
if (boundary)
layer->addBoundary (boundary);
else
{
TerrainGenerator::Filter* filter = createFilter (iff, terrainGenerator);
if (filter)
layer->addFilter (filter);
else
{
TerrainGenerator::Affector* affector = createAffector (iff, terrainGenerator);
if (affector)
layer->addAffector (affector);
else
{
DEBUG_FATAL (iff.getCurrentName () != TAG_LAYR, ("not at layer in terrain file"));
TerrainGenerator::Layer* sublayer = new TerrainGenerator::Layer ();
sublayer->load (iff, terrainGenerator);
layer->addLayer (sublayer);
} //lint !e429 //-- sublayer has not been freed or returned
}
}
}
//-------------------------------------------------------------------
TerrainGenerator::Boundary* TerrainGeneratorLoader::createBoundary (Iff& iff)
{
TerrainGenerator::Boundary* boundary = 0;
switch (iff.getCurrentName ())
{
case TAG_BALL:
{
//-- this boundary is no longer used
iff.enterForm (TAG_BALL);
iff.exitForm (TAG_BALL, true);
}
break;
case TAG_BCIR:
{
iff.enterForm (TAG_BCIR);
boundary = new BoundaryCircle ();
boundary->load (iff);
iff.exitForm (TAG_BCIR);
}
break;
case TAG_BREC:
{
iff.enterForm (TAG_BREC);
boundary = new BoundaryRectangle ();
boundary->load (iff);
iff.exitForm (TAG_BREC);
}
break;
case TAG_BPOL:
{
iff.enterForm (TAG_BPOL);
boundary = new BoundaryPolygon ();
boundary->load (iff);
iff.exitForm (TAG_BPOL);
}
break;
case TAG_BSPL:
{
//-- this boundary is no longer used
iff.enterForm (TAG_BSPL);
iff.exitForm (TAG_BSPL, true);
}
break;
case TAG_BPLN:
{
iff.enterForm (TAG_BPLN);
boundary = new BoundaryPolyline ();
boundary->load (iff);
iff.exitForm (TAG_BPLN);
}
break;
default:
break;
}
return boundary;
}
//-------------------------------------------------------------------
TerrainGenerator::Filter* TerrainGeneratorLoader::createFilter (Iff& iff, TerrainGenerator* terrainGenerator)
{
TerrainGenerator::Filter* filter = 0;
switch (iff.getCurrentName ())
{
case TAG_FHGT:
{
iff.enterForm (TAG_FHGT);
filter = new FilterHeight ();
filter->load (iff);
iff.exitForm (TAG_FHGT);
}
break;
case TAG_FFRA:
{
iff.enterForm (TAG_FFRA);
FilterFractal* filterFractal = new FilterFractal ();
filterFractal->load (iff, terrainGenerator->getFractalGroup ());
filter = filterFractal;
iff.exitForm (TAG_FFRA);
}
break;
case TAG_FBIT:
{
iff.enterForm (TAG_FBIT);
FilterBitmap* filterBitmap = new FilterBitmap ();
filterBitmap->load (iff /*, terrainGenerator->getBitmapGroup ()*/);
filter = filterBitmap;
iff.exitForm (TAG_FBIT);
}
break;
case TAG_FSLP:
{
iff.enterForm (TAG_FSLP);
filter = new FilterSlope ();
filter->load (iff);
iff.exitForm (TAG_FSLP);
}
break;
case TAG_FDIR:
{
iff.enterForm (TAG_FDIR);
filter = new FilterDirection ();
filter->load (iff);
iff.exitForm (TAG_FDIR);
}
break;
case TAG_FSHD:
{
iff.enterForm (TAG_FSHD);
filter = new FilterShader ();
filter->load (iff);
iff.exitForm (TAG_FSHD);
}
break;
default:
break;
}
return filter;
}
//-------------------------------------------------------------------
TerrainGenerator::Affector* TerrainGeneratorLoader::createAffector (Iff& iff, TerrainGenerator* terrainGenerator)
{
TerrainGenerator::Affector* affector = 0;
switch (iff.getCurrentName ())
{
case TAG_AHSM:
{
//-- AffectorHeightSmoother no longer exists
iff.enterForm (TAG_AHSM);
iff.exitForm (TAG_AHSM, true);
}
break;
case TAG_AHBM:
{
//-- AffectorHeightBitmap no longer exists
iff.enterForm (TAG_AHBM);
iff.exitForm (TAG_AHBM, true);
}
break;
case TAG_ACBM:
{
//-- AffectorColorBitmap no longer exists
iff.enterForm (TAG_ACBM);
iff.exitForm (TAG_ACBM, true);
}
break;
case TAG_ASBM:
{
//-- AffectorShaderBitmap no longer exists
iff.enterForm (TAG_ASBM);
iff.exitForm (TAG_ASBM, true);
}
break;
case TAG_AFBM:
{
//-- AffectorFloraBitmap no longer exists
iff.enterForm (TAG_AFBM);
iff.exitForm (TAG_AFBM, true);
}
break;
case TAG_AENV:
{
iff.enterForm (TAG_AENV);
affector = new AffectorEnvironment ();
affector->load (iff);
iff.exitForm (TAG_AENV);
}
break;
case TAG_AHTR:
{
iff.enterForm (TAG_AHTR);
affector = new AffectorHeightTerrace ();
affector->load (iff);
iff.exitForm (TAG_AHTR);
}
break;
case TAG_AHCN:
{
iff.enterForm (TAG_AHCN);
affector = new AffectorHeightConstant ();
affector->load (iff);
iff.exitForm (TAG_AHCN);
}
break;
case TAG_AHFR:
{
iff.enterForm (TAG_AHFR);
AffectorHeightFractal* affectorHeightFractal = new AffectorHeightFractal ();
affectorHeightFractal->load (iff, terrainGenerator->getFractalGroup ());
affector = affectorHeightFractal;
iff.exitForm (TAG_AHFR);
}
break;
case TAG_ACCN:
{
iff.enterForm (TAG_ACCN);
affector = new AffectorColorConstant ();
affector->load (iff);
iff.exitForm (TAG_ACCN);
}
break;
case TAG_ACRH:
{
iff.enterForm (TAG_ACRH);
affector = new AffectorColorRampHeight ();
affector->load (iff);
iff.exitForm (TAG_ACRH);
}
break;
case TAG_ACRF:
{
iff.enterForm (TAG_ACRF);
AffectorColorRampFractal* affectorColorRampFractal = new AffectorColorRampFractal ();
affectorColorRampFractal->load (iff, terrainGenerator->getFractalGroup ());
affector = affectorColorRampFractal;
iff.exitForm (TAG_ACRF);
}
break;
case TAG_ASCN:
{
iff.enterForm (TAG_ASCN);
affector = new AffectorShaderConstant ();
affector->load (iff);
iff.exitForm (TAG_ASCN);
}
break;
case TAG_ASRP:
{
iff.enterForm (TAG_ASRP);
affector = new AffectorShaderReplace ();
affector->load (iff);
iff.exitForm (TAG_ASRP);
}
break;
case TAG_AFCN:
{
iff.enterForm (TAG_AFCN);
affector = new AffectorFloraStaticCollidableConstant ();
affector->load (iff);
iff.exitForm (TAG_AFCN);
}
break;
case TAG_AFSC:
{
iff.enterForm (TAG_AFSC);
affector = new AffectorFloraStaticCollidableConstant ();
affector->load (iff);
iff.exitForm (TAG_AFSC);
}
break;
case TAG_AFSN:
{
iff.enterForm (TAG_AFSN);
affector = new AffectorFloraStaticNonCollidableConstant ();
affector->load (iff);
iff.exitForm (TAG_AFSN);
}
break;
case TAG_ARCN:
{
iff.enterForm (TAG_ARCN);
affector = new AffectorFloraDynamicNearConstant ();
affector->load (iff);
iff.exitForm (TAG_ARCN);
}
break;
case TAG_AFDN:
{
iff.enterForm (TAG_AFDN);
affector = new AffectorFloraDynamicNearConstant ();
affector->load (iff);
iff.exitForm (TAG_AFDN);
}
break;
case TAG_AFDF:
{
iff.enterForm (TAG_AFDF);
affector = new AffectorFloraDynamicFarConstant ();
affector->load (iff);
iff.exitForm (TAG_AFDF);
}
break;
case TAG_ARIB:
{
iff.enterForm (TAG_ARIB);
affector = new AffectorRibbon ();
affector->load (iff);
iff.exitForm (TAG_ARIB);
}
break;
case TAG_AEXC:
{
iff.enterForm (TAG_AEXC);
affector = new AffectorExclude ();
affector->load (iff);
iff.exitForm (TAG_AEXC);
}
break;
case TAG_APAS:
{
iff.enterForm (TAG_APAS);
affector = new AffectorPassable();
affector->load (iff);
iff.exitForm (TAG_APAS);
}
break;
case TAG_AROA:
{
iff.enterForm (TAG_AROA);
affector = new AffectorRoad ();
affector->load (iff);
iff.exitForm (TAG_AROA);
}
break;
case TAG_ARIV:
{
iff.enterForm (TAG_ARIV);
affector = new AffectorRiver ();
affector->load (iff);
iff.exitForm (TAG_ARIV);
}
break;
default:
break;
}
return affector;
}
//-------------------------------------------------------------------
@@ -0,0 +1,50 @@
//===================================================================
//
// TerrainGeneratorLoader.h
// asommers 9-11-2000
//
// copyright 2000, verant interactive
//
//--
//
// this class knows about all of the available terrain generator Layers,
// Actions, Boundaries, Filters and Affectors and how to initialize them
//
//===================================================================
#ifndef INCLUDED_TerrainGeneratorLoader_H
#define INCLUDED_TerrainGeneratorLoader_H
//===================================================================
#include "sharedTerrain/TerrainGenerator.h"
//===================================================================
class TerrainGeneratorLoader
{
private:
TerrainGeneratorLoader ();
~TerrainGeneratorLoader ();
TerrainGeneratorLoader (const TerrainGeneratorLoader& rhs);
TerrainGeneratorLoader& operator= (const TerrainGeneratorLoader& rhs);
public:
//-- createLayer instantiates a layer
static void loadLayerItem (Iff& iff, TerrainGenerator* terrainGenerator, TerrainGenerator::Layer* layer);
//-- createBoundary instantiates a boundary
static TerrainGenerator::Boundary* createBoundary (Iff& iff);
//-- createFilter instantiates a filter
static TerrainGenerator::Filter* createFilter (Iff& iff, TerrainGenerator* terrainGenerator);
//-- createAffector instantiates a affector
static TerrainGenerator::Affector* createAffector (Iff& iff, TerrainGenerator* terrainGenerator);
};
//===================================================================
#endif
@@ -0,0 +1,118 @@
//
// TerrainGeneratorType.def
// asommers 9-11-2000
//
// copyright 2000, verant interactive
//
//-------------------------------------------------------------------
#ifndef TERRAINGENERATORTYPE_DEF
#define TERRAINGENERATORTYPE_DEF
//-------------------------------------------------------------------
enum TerrainGeneratorMap
{
TGM_height = (1<< 0),
TGM_color = (1<< 1),
TGM_shader = (1<< 2),
TGM_floraStaticCollidable = (1<< 3),
TGM_floraStaticNonCollidable = (1<< 4),
TGM_floraDynamicNear = (1<< 5),
TGM_floraDynamicFar = (1<< 6),
TGM_environment = (1<< 7),
TGM_vertexPosition = (1<< 8),
TGM_vertexNormal = (1<< 9),
TGM_exclude = (1<<10),
TGM_passable = (1<<11),
TGM_ALL = 0xffffffff
};
//-------------------------------------------------------------------
enum TerrainGeneratorBoundaryType
{
TGBT_circle,
TGBT_rectangle,
TGBT_polygon,
TGBT_polyline
};
//-------------------------------------------------------------------
enum TerrainGeneratorFilterType
{
TGFT_height,
TGFT_fractal,
TGFT_slope,
TGFT_direction,
TGFT_shader,
TGFT_bitmap
};
//-------------------------------------------------------------------
enum TerrainGeneratorAffectorType
{
TGAT_heightTerrace,
TGAT_heightConstant,
TGAT_heightFractal,
TGAT_colorConstant,
TGAT_colorRampHeight,
TGAT_colorRampFractal,
TGAT_shaderConstant,
TGAT_shaderReplace,
TGAT_floraStaticCollidableConstant,
TGAT_floraStaticNonCollidableConstant,
TGAT_floraDynamicNearConstant,
TGAT_floraDynamicFarConstant,
TGAT_exclude,
TGAT_passable,
TGAT_road,
TGAT_river,
TGAT_environment,
TGAT_ribbon,
TGAT_COUNT
};
//-------------------------------------------------------------------
enum TerrainGeneratorOperation
{
TGO_replace,
TGO_add,
TGO_subtract,
TGO_multiply,
TGO_COUNT
};
//-------------------------------------------------------------------
enum TerrainGeneratorFeatherFunction
{
TGFF_linear,
TGFF_easeIn,
TGFF_easeOut,
TGFF_easeInOut,
TGFF_COUNT
};
//-------------------------------------------------------------------
enum TerrainGeneratorWaterType
{
TGWT_invalid = -1,
TGWT_water,
TGWT_lava,
TGWT_COUNT
};
//-------------------------------------------------------------------
#endif
@@ -0,0 +1,72 @@
//===================================================================
//
// TerrainGeneratorType.h
// asommers 9-11-2000
//
// copyright 2000, verant interactive
//
//===================================================================
#ifndef INCLUDED_TerrainGeneratorType_H
#define INCLUDED_TerrainGeneratorType_H
//===================================================================
#include "sharedTerrain/TerrainGeneratorType.def"
//===================================================================
//-- boundaries
const Tag TAG_BALL = TAG (B,A,L,L);
const Tag TAG_BCIR = TAG (B,C,I,R);
const Tag TAG_BPLN = TAG (B,P,L,N);
const Tag TAG_BPOL = TAG (B,P,O,L);
const Tag TAG_BREC = TAG (B,R,E,C);
const Tag TAG_BSPL = TAG (B,S,P,L);
//-- filters
const Tag TAG_FBIT = TAG (F,B,I,T); // bitmap
const Tag TAG_FDIR = TAG (F,D,I,R); // direction
const Tag TAG_FFRA = TAG (F,F,R,A); // fractal
const Tag TAG_FHGT = TAG (F,H,G,T); // height
const Tag TAG_FSHD = TAG (F,S,H,D); // shader
const Tag TAG_FSLP = TAG (F,S,L,P); // slope
//-- affectors
const Tag TAG_ACBM = TAG (A,C,B,M);
const Tag TAG_ACCN = TAG (A,C,C,N);
const Tag TAG_ACRF = TAG (A,C,R,F);
const Tag TAG_ACRH = TAG (A,C,R,H);
const Tag TAG_AEXC = TAG (A,E,X,C);
const Tag TAG_APAS = TAG (A,P,A,S);
const Tag TAG_AENV = TAG (A,E,N,V);
const Tag TAG_AFBM = TAG (A,F,B,M);
const Tag TAG_AFCN = TAG (A,F,C,N);
const Tag TAG_AFDF = TAG (A,F,D,F);
const Tag TAG_AFDN = TAG (A,F,D,N);
const Tag TAG_AFSC = TAG (A,F,S,C);
const Tag TAG_AFSN = TAG (A,F,S,N);
const Tag TAG_AHBM = TAG (A,H,B,M);
const Tag TAG_AHCN = TAG (A,H,C,N);
const Tag TAG_AHFR = TAG (A,H,F,R);
const Tag TAG_AHSM = TAG (A,H,S,M);
const Tag TAG_AHTR = TAG (A,H,T,R);
const Tag TAG_ARCN = TAG (A,R,C,N);
const Tag TAG_ARIB = TAG (A,R,I,B);
const Tag TAG_ARIV = TAG (A,R,I,V);
const Tag TAG_AROA = TAG (A,R,O,A);
const Tag TAG_ASBM = TAG (A,S,B,M);
const Tag TAG_ASCN = TAG (A,S,C,N);
const Tag TAG_ASRP = TAG (A,S,R,P);
//-- misc
const Tag TAG_TGEN = TAG (T,G,E,N);
const Tag TAG_LYRS = TAG (L,Y,R,S);
const Tag TAG_IHDR = TAG (I,H,D,R);
const Tag TAG_LAYR = TAG (L,A,Y,R);
const Tag TAG_ACTN = TAG (A,C,T,N);
const Tag TAG_ADTA = TAG (A,D,T,A);
//===================================================================
#endif
@@ -0,0 +1,110 @@
//===================================================================
//
// TerrainModificationHelper.cpp
// copyright 2001, sony online entertainment
//
//
//===================================================================
#include "sharedTerrain/FirstSharedTerrain.h"
#include "sharedTerrain/TerrainModificationHelper.h"
#include "sharedTerrain/AffectorHeight.h"
#include "sharedFile/Iff.h"
//===================================================================
void TerrainModificationHelper::setHeight (TerrainGenerator::Layer* layer, float height)
{
layer->setModificationHeight (height);
{
int i;
for (i = 0; i < layer->getNumberOfAffectors (); ++i)
if (layer->getAffector (i)->isActive () && layer->getAffector (i)->getType () == TGAT_heightConstant)
safe_cast<AffectorHeightConstant*> (layer->getAffector (i))->setHeight (height);
}
{
int i;
for (i = 0; i < layer->getNumberOfLayers (); ++i)
if (layer->getLayer (i)->isActive ())
setHeight (layer->getLayer (i), height);
}
}
//-------------------------------------------------------------------
void TerrainModificationHelper::setPosition (TerrainGenerator::Layer* layer, const Vector2d& position)
{
{
int i;
for (i = 0; i < layer->getNumberOfBoundaries (); ++i)
if (layer->getBoundary (i)->isActive ())
layer->getBoundary (i)->setCenter (position);
}
{
int i;
for (i = 0; i < layer->getNumberOfLayers (); i++)
if (layer->getLayer (i)->isActive ())
setPosition (layer->getLayer (i), position);
}
}
//-------------------------------------------------------------------
void TerrainModificationHelper::setRotation (TerrainGenerator::Layer* layer, float angle)
{
{
int i;
for (i = 0; i < layer->getNumberOfBoundaries (); ++i)
if (layer->getBoundary (i)->isActive ())
layer->getBoundary (i)->setRotation (angle);
}
{
int i;
for (i = 0; i < layer->getNumberOfLayers (); i++)
if (layer->getLayer (i)->isActive ())
setRotation (layer->getLayer (i), angle);
}
}
//-------------------------------------------------------------------
TerrainGenerator::Layer* TerrainModificationHelper::importLayer (const char* filename)
{
Iff iff;
if (iff.open (filename, true))
{
ShaderGroup* shaderGroup = new ShaderGroup;
shaderGroup->load (iff);
delete shaderGroup;
FloraGroup* floraGroup = new FloraGroup;
floraGroup->load (iff);
delete floraGroup;
RadialGroup* radialGroup = new RadialGroup;
radialGroup->load (iff);
delete radialGroup;
EnvironmentGroup* environmentGroup = new EnvironmentGroup;
environmentGroup->load (iff);
delete environmentGroup;
FractalGroup* fractalGroup = new FractalGroup;
fractalGroup->load (iff);
delete fractalGroup;
TerrainGenerator::Layer* const newLayer = new TerrainGenerator::Layer;
newLayer->load (iff, 0);
return newLayer;
}
return 0;
}
//===================================================================
@@ -0,0 +1,37 @@
//===================================================================
//
// TerrainModificationHelper.h
// copyright 2001, sony online entertainment
//
//
//===================================================================
#ifndef INCLUDED_TerrainModificationHelper_H
#define INCLUDED_TerrainModificationHelper_H
//===================================================================
#include "TerrainGenerator.h"
//===================================================================
class TerrainModificationHelper
{
public:
static void setPosition (TerrainGenerator::Layer* layer, const Vector2d& position);
static void setRotation (TerrainGenerator::Layer* layer, float angle);
static void setHeight (TerrainGenerator::Layer* layer, float height);
static TerrainGenerator::Layer* importLayer (const char* filename);
private:
TerrainModificationHelper ();
~TerrainModificationHelper ();
TerrainModificationHelper (const TerrainModificationHelper& rhs);
TerrainModificationHelper& operator= (const TerrainModificationHelper& rhs);
};
//===================================================================
#endif
@@ -0,0 +1,795 @@
//===================================================================
//
// TerrainObject.cpp
// asommers 3-1-99
//
// copyright 1999, bootprint entertainment
// copyright 2001, sony online entertainment
//
//===================================================================
#include "sharedTerrain/FirstSharedTerrain.h"
#include "sharedTerrain/TerrainObject.h"
#include "sharedCollision/CollideParameters.h"
#include "sharedCollision/CollisionInfo.h"
#include "sharedDebug/DebugFlags.h"
#include "sharedFoundation/ExitChain.h"
#include "sharedMath/Sphere.h"
#include "sharedTerrain/ConfigSharedTerrain.h"
#include "sharedTerrain/TerrainAppearance.h"
#include <string>
#include <vector>
//===================================================================
namespace
{
inline const TerrainAppearance* getCastedAppearance (const Object* const object)
{
NOT_NULL (object);
return safe_cast<const TerrainAppearance*> (object->getAppearance ());
}
inline TerrainAppearance* getCastedAppearance (Object* const object)
{
NOT_NULL (object);
return safe_cast<TerrainAppearance*> (object->getAppearance ());
}
const Vector2d ms_invalidPosition_w (FLT_MAX, FLT_MAX);
bool ms_debugReport;
typedef std::vector<TerrainObject::TerrainChangedFunction> TerrainChangedFunctionList;
TerrainChangedFunctionList ms_terrainChangedFunctionList;
}
//===================================================================
// STATIC PUBLIC TerrainObject
//===================================================================
TerrainObject* TerrainObject::ms_instance;
bool TerrainObject::ms_useCache = true;
//===================================================================
void TerrainObject::install ()
{
DebugFlags::registerFlag (ms_debugReport, "SharedTerrain", "debugReport", debugDump);
ExitChain::add (remove, "TerrainObject::remove");
}
//-------------------------------------------------------------------
void TerrainObject::remove ()
{
DebugFlags::unregisterFlag (ms_debugReport);
}
//-------------------------------------------------------------------
TerrainObject* TerrainObject::getInstance ()
{
return ms_instance;
}
//-------------------------------------------------------------------
const TerrainObject* TerrainObject::getConstInstance ()
{
return ms_instance;
}
//-------------------------------------------------------------------
void TerrainObject::setUseCache (bool useCache)
{
ms_useCache = useCache;
}
//-------------------------------------------------------------------
void TerrainObject::addTerrainChangedFunction (TerrainObject::TerrainChangedFunction terrainChangedFunction)
{
ms_terrainChangedFunctionList.push_back (terrainChangedFunction);
}
//-------------------------------------------------------------------
void TerrainObject::terrainChanged (Rectangle2d const & extent2d)
{
TerrainChangedFunctionList::iterator end = ms_terrainChangedFunctionList.end ();
for (TerrainChangedFunctionList::iterator iter = ms_terrainChangedFunctionList.begin (); iter != end; ++iter)
(*iter) (extent2d);
}
//-------------------------------------------------------------------
void TerrainObject::debugDump ()
{
if (ms_instance)
getCastedAppearance (ms_instance)->debugDump ();
}
//===================================================================
// PUBLIC TerrainObject
//===================================================================
TerrainObject::TerrainObject () :
Object (),
m_cachedPosition_w (ms_invalidPosition_w),
m_cachedPositionHeight (0.f),
m_cachedPositionNormal_w (ms_invalidPosition_w),
m_cachedPositionNormalHeight (0.f),
m_cachedPositionNormalNormal_w (Vector::unitY),
m_cachedPositionWater_w (ms_invalidPosition_w),
m_cachedPositionWaterHeight (0.f),
m_cachedPositionWaterType(TGWT_invalid)
{
DEBUG_FATAL (ms_instance, ("TerrainObject instance already exists"));
ms_instance = this;
}
//-------------------------------------------------------------------
TerrainObject::TerrainObject (const ObjectNotification &notification) :
Object (),
m_cachedPosition_w (ms_invalidPosition_w),
m_cachedPositionHeight (0.f),
m_cachedPositionNormal_w (ms_invalidPosition_w),
m_cachedPositionNormalHeight (0.f),
m_cachedPositionNormalNormal_w (Vector::unitY),
m_cachedPositionWater_w (ms_invalidPosition_w),
m_cachedPositionWaterHeight (0.f),
m_cachedPositionWaterType(TGWT_invalid)
{
DEBUG_FATAL (ms_instance, ("TerrainObject instance already exists"));
ms_instance = this;
addNotification (notification);
}
//-------------------------------------------------------------------
TerrainObject::~TerrainObject ()
{
//remove from world
if (isInWorld ())
TerrainObject::removeFromWorld ();
DEBUG_FATAL (ms_instance != this, ("TerrainObject instance is not this object"));
ms_instance = NULL;
}
//-------------------------------------------------------------------
bool TerrainObject::placeObject (Object& object, bool alignToTerrain, bool forceChunkCreation) const
{
// @todo ALS handle align to terrain
UNREF (alignToTerrain);
//-- make sure the object is both in the world and in the world cell
if (!object.isInWorld () || !object.isInWorldCell ())
{
DEBUG_WARNING (true, ("TerrainObject::placeObject - object is not in world or not in world cell (id=%s, template=%s)", object.getNetworkId ().getValueString ().c_str (), object.getObjectTemplateName ()));
return false;
}
const Vector& position_w = object.getPosition_w ();
float height;
if (forceChunkCreation)
{
if (getHeightForceChunkCreation (position_w, height))
{
object.setPosition_w (Vector (position_w.x, height, position_w.z));
return true;
}
}
else
{
if (getHeight (position_w, height))
{
object.setPosition_w (Vector (position_w.x, height, position_w.z));
return true;
}
}
DEBUG_WARNING (true, ("TerrainObject::placeObject (id=%s, template=%s) failed for %s location <%1.2f, %1.2f>", object.getNetworkId ().getValueString ().c_str (), object.getObjectTemplateName (), forceChunkCreation ? "forced" : "non-forced", position_w.x, position_w.z));
return false;
}
//-------------------------------------------------------------------
bool TerrainObject::getLogicalHeight (const Vector& position_w, const float swimHeight, float& logicalHeight, float& realHeight) const
{
if (getHeight (position_w, realHeight))
{
float waterHeight;
if (getWaterHeight (position_w, waterHeight) && (waterHeight - swimHeight > realHeight))
logicalHeight = waterHeight - swimHeight;
else
logicalHeight = realHeight;
return true;
}
return false;
}
//-------------------------------------------------------------------
bool TerrainObject::getLogicalHeight (const Vector& position_w, const float swimHeight, float& logicalHeight, float& realHeight, Vector& normal) const
{
if (getHeight (position_w, realHeight, normal))
{
float waterHeight;
if (getWaterHeight (position_w, waterHeight) && (waterHeight - swimHeight > realHeight))
logicalHeight = waterHeight - swimHeight;
else
logicalHeight = realHeight;
return true;
}
return false;
}
//-------------------------------------------------------------------
bool TerrainObject::getHeight (const Vector& position_w, float& height) const
{
const Vector2d position (position_w.x, position_w.z);
if (ms_useCache && position == m_cachedPosition_w)
{
height = m_cachedPositionHeight;
return true;
}
const bool result = getCastedAppearance (this)->getHeight (rotateTranslate_w2o (position_w), height);
if (result)
{
m_cachedPosition_w = position;
m_cachedPositionHeight = height;
}
else
m_cachedPosition_w = ms_invalidPosition_w;
return result;
}
//-------------------------------------------------------------------
bool TerrainObject::getHeight (const Vector& position_w, float& height, Vector& normal) const
{
const Vector2d position (position_w.x, position_w.z);
if (ms_useCache && position == m_cachedPositionNormal_w)
{
height = m_cachedPositionNormalHeight;
normal = m_cachedPositionNormalNormal_w;
return true;
}
const bool result = getCastedAppearance (this)->getHeight (rotateTranslate_w2o (position_w), height, normal);
if (result)
{
normal = rotate_o2w (normal);
m_cachedPositionNormal_w = position;
m_cachedPositionNormalHeight = height;
m_cachedPositionNormalNormal_w = normal;
}
else
m_cachedPositionNormal_w = ms_invalidPosition_w;
return result;
}
//-------------------------------------------------------------------
bool TerrainObject::getHeightForceChunkCreation (const Vector& position_w, float& height) const
{
return getCastedAppearance (this)->getHeightForceChunkCreation (rotateTranslate_w2o (position_w), height);
}
//-------------------------------------------------------------------
const ObjectTemplate* TerrainObject::getSurfaceProperties (const Vector& position_w) const
{
return getCastedAppearance (this)->getSurfaceProperties (rotateTranslate_w2o (position_w));
}
//-------------------------------------------------------------------
int TerrainObject::getTerrainType (const Vector &position_w) const
{
return getCastedAppearance (this)->getTerrainType (rotateTranslate_w2o (position_w));
}
//-------------------------------------------------------------------
bool TerrainObject::getWaterHeight (const Vector& position_w, float& height) const
{
TerrainGeneratorWaterType waterType;
return getWaterHeight(position_w,height,waterType);
}
//-------------------------------------------------------------------
bool TerrainObject::getWaterHeight (const Vector& position_w, float& height, TerrainGeneratorWaterType& waterType, bool ignoreNonTransparentWater) const
{
const Vector2d position (position_w.x, position_w.z);
if (ms_useCache && position == m_cachedPositionWater_w)
{
height = m_cachedPositionWaterHeight;
waterType = m_cachedPositionWaterType;
return true;
}
const bool result = getCastedAppearance (this)->getWaterHeight (rotateTranslate_w2o (position_w), height, waterType, ignoreNonTransparentWater);
if (result)
{
m_cachedPositionWater_w = position;
m_cachedPositionWaterHeight = height;
m_cachedPositionWaterType = waterType;
}
else
m_cachedPositionWater_w = ms_invalidPosition_w;
return result;
}
//-------------------------------------------------------------------
TerrainGeneratorWaterType TerrainObject::getWaterType (const Vector& position_w) const
{
const TerrainGeneratorWaterType ret = getCastedAppearance (this)->getWaterType (rotateTranslate_w2o (position_w));
return ret;
}
//-------------------------------------------------------------------
bool TerrainObject::isBelowWater (const Vector& position_w) const
{
float waterHeight;
return getWaterHeight (position_w, waterHeight) && (position_w.y < waterHeight);
}
//-------------------------------------------------------------------
bool TerrainObject::isBelowWater (const Vector& position_w, TerrainGeneratorWaterType& waterType, bool ignoreNonTransparentWater) const
{
float waterHeight;
return getWaterHeight (position_w, waterHeight, waterType, ignoreNonTransparentWater) && (position_w.y < waterHeight);
}
//-------------------------------------------------------------------
bool TerrainObject::getWater (const Rectangle2d& rectangle) const
{
return getCastedAppearance (this)->getWater (rectangle);
}
//-------------------------------------------------------------------
bool TerrainObject::getSlope (const Rectangle2d& rectangle) const
{
return getCastedAppearance (this)->getSlope (rectangle);
}
//-------------------------------------------------------------------
bool TerrainObject::getWater (const int chunkX, const int chunkZ) const
{
return getCastedAppearance (this)->getWater (chunkX, chunkZ);
}
//-------------------------------------------------------------------
bool TerrainObject::getSlope (const int chunkX, const int chunkZ) const
{
return getCastedAppearance (this)->getSlope (chunkX, chunkZ);
}
//-------------------------------------------------------------------
float TerrainObject::getChunkWidthInMeters () const
{
return getCastedAppearance (this)->getChunkWidthInMeters ();
}
//-------------------------------------------------------------------
float TerrainObject::getMapWidthInMeters () const
{
return getCastedAppearance (this)->getMapWidthInMeters ();
}
//-------------------------------------------------------------------
float TerrainObject::getMaximumValidHeightInMeters () const
{
return ConfigSharedTerrain::getMaximumValidHeightInMeters ();
}
//-------------------------------------------------------------------
int TerrainObject::getNumberOfChunks () const
{
return getCastedAppearance (this)->getNumberOfChunks ();
}
//-------------------------------------------------------------------
bool TerrainObject::hasHighLevelOfDetailTerrain (const Vector& position_w) const
{
return getCastedAppearance (this)->hasHighLevelOfDetailTerrain (rotateTranslate_w2o (position_w));
}
//-------------------------------------------------------------------
int TerrainObject::calculateChunkX (const Vector& position_w) const
{
return getCastedAppearance (this)->calculateChunkX (rotateTranslate_w2o (position_w).x);
}
//-------------------------------------------------------------------
int TerrainObject::calculateChunkZ (const Vector& position_w) const
{
return getCastedAppearance (this)->calculateChunkZ (rotateTranslate_w2o (position_w).z);
}
//-------------------------------------------------------------------
float TerrainObject::getChunkHeight (const int chunkX, const int chunkZ) const
{
return getCastedAppearance (this)->getChunkHeight (chunkX, chunkZ);
}
//-------------------------------------------------------------------
const BoxExtent* TerrainObject::getChunkExtent (const Vector& position_w) const
{
return getCastedAppearance (this)->getChunkExtent (rotateTranslate_w2o (position_w));
}
//-------------------------------------------------------------------
const BoxExtent* TerrainObject::getChunkExtentForceChunkCreation (const Vector& position_w) const
{
return getCastedAppearance (this)->getChunkExtentForceChunkCreation (rotateTranslate_w2o (position_w));
}
//-------------------------------------------------------------------
bool TerrainObject::collide (const Vector& start_w, const Vector& end_w, CollisionInfo& result) const
{
if (getCastedAppearance(this)->collide(rotateTranslate_w2o(start_w), rotateTranslate_w2o(end_w), CollideParameters::cms_default, result))
{
result.setObject (this);
result.setPoint (rotateTranslate_o2w (result.getPoint ()));
result.setNormal (rotate_o2w (result.getNormal ()));
return true;
}
return false;
}
//-------------------------------------------------------------------
bool TerrainObject::collideForceChunkCreation (Vector const & start_w, Vector const & end_w, CollisionInfo & result)
{
return getCastedAppearance(this)->collideForceChunkCreation(rotateTranslate_w2o(start_w), rotateTranslate_w2o(end_w), result);
}
//-------------------------------------------------------------------
bool TerrainObject::collideObjects (const Vector& start_w, const Vector& end_w, CollisionInfo& result) const
{
if (getCastedAppearance (this)->collideObjects (rotateTranslate_w2o (start_w), rotateTranslate_w2o (end_w), result))
{
result.setPoint (rotateTranslate_o2w (result.getPoint ()));
result.setNormal (rotate_o2w (result.getNormal ()));
return true;
}
return false;
}
//-------------------------------------------------------------------
bool TerrainObject::approximateCollideObjects (const Vector& start_w, const Vector& end_w, CollisionInfo& result) const
{
if (getCastedAppearance (this)->approximateCollideObjects (rotateTranslate_w2o (start_w), rotateTranslate_w2o (end_w), result))
{
result.setPoint (rotateTranslate_o2w (result.getPoint ()));
result.setNormal (rotate_o2w (result.getNormal ()));
return true;
}
return false;
}
//-------------------------------------------------------------------
void TerrainObject::preRender (const Camera* const camera) const
{
getCastedAppearance (this)->preRender (camera);
}
//-------------------------------------------------------------------
void TerrainObject::postRender () const
{
getCastedAppearance (this)->postRender ();
}
//-------------------------------------------------------------------
void TerrainObject::addReferenceObject (const Object* const referenceObject)
{
getCastedAppearance (this)->addReferenceObject (referenceObject);
}
//-------------------------------------------------------------------
int TerrainObject::getNumberOfReferenceObjects() const
{
return getCastedAppearance (this)->getNumberOfReferenceObjects();
}
//-------------------------------------------------------------------
void TerrainObject::removeReferenceObject (const Object* const referenceObject)
{
getCastedAppearance (this)->removeReferenceObject (referenceObject);
}
//-------------------------------------------------------------------
void TerrainObject::removeAllReferenceObjects ()
{
getCastedAppearance (this)->removeAllReferenceObjects ();
}
//-------------------------------------------------------------------
bool TerrainObject::isReferenceObject (const Object* const referenceObject) const
{
return getCastedAppearance (this)->isReferenceObject (referenceObject);
}
//-------------------------------------------------------------------
bool TerrainObject::getPauseEnvironment () const
{
return getCastedAppearance (this)->getPauseEnvironment ();
}
//-------------------------------------------------------------------
void TerrainObject::setPauseEnvironment (bool const pauseEnvironment)
{
getCastedAppearance (this)->setPauseEnvironment (pauseEnvironment);
}
//-------------------------------------------------------------------
float TerrainObject::getEnvironmentCycleTime () const
{
return getCastedAppearance (this)->getEnvironmentCycleTime ();
}
//-------------------------------------------------------------------
const PackedRgb TerrainObject::getClearColor () const
{
return getCastedAppearance (this)->getClearColor ();
}
//-------------------------------------------------------------------
const PackedRgb TerrainObject::getFogColor () const
{
return getCastedAppearance (this)->getFogColor ();
}
//-------------------------------------------------------------------
float TerrainObject::getFogDensity () const
{
return getCastedAppearance (this)->getFogDensity ();
}
//-------------------------------------------------------------------
void TerrainObject::getTime (int& hour, int& minute) const
{
getCastedAppearance (this)->getTime (hour, minute);
}
//-------------------------------------------------------------------
float TerrainObject::getTime () const
{
return getCastedAppearance (this)->getTime ();
}
//-------------------------------------------------------------------
void TerrainObject::setTime (const float time, const bool force)
{
getCastedAppearance (this)->setTime (time, force);
}
//-------------------------------------------------------------------
bool TerrainObject::isDay () const
{
return getCastedAppearance (this)->isDay ();
}
//----------------------------------------------------------------------
bool TerrainObject::isTimeLocked() const
{
return getCastedAppearance(this)->isTimeLocked();
}
//-------------------------------------------------------------------
void TerrainObject::addClearCollidableFloraObject (const Object* const object, const Vector& position_w, const float radius)
{
getCastedAppearance (this)->addClearCollidableFloraObject (object, position_w, radius);
}
//-------------------------------------------------------------------
void TerrainObject::removeClearCollidableFloraObject (const Object* const object)
{
getCastedAppearance (this)->removeClearCollidableFloraObject (object);
}
//-------------------------------------------------------------------
void TerrainObject::addClearNonCollidableFloraObject (const Object* const object, const ClearFloraEntryList& clearFloraEntryList)
{
getCastedAppearance (this)->addClearNonCollidableFloraObject (object, clearFloraEntryList);
}
//-------------------------------------------------------------------
void TerrainObject::removeClearNonCollidableFloraObject (const Object* const object)
{
getCastedAppearance (this)->removeClearNonCollidableFloraObject (object);
}
//-------------------------------------------------------------------
float TerrainObject::getHighLevelOfDetailThreshold ()
{
TerrainObject * const to = getInstance ();
if (to)
return getCastedAppearance (to)->getHighLevelOfDetailThreshold ();
return 0.0f;
}
//-------------------------------------------------------------------
void TerrainObject::setHighLevelOfDetailThreshold (const float highLevelOfDetailThreshold)
{
TerrainObject * const to = getInstance ();
if (to)
getCastedAppearance (to)->setHighLevelOfDetailThreshold (highLevelOfDetailThreshold);
}
//-------------------------------------------------------------------
float TerrainObject::getLevelOfDetailThreshold ()
{
TerrainObject * const to = getInstance ();
if (to)
return getCastedAppearance (to)->getLevelOfDetailThreshold ();
return 1.0f;
}
//-------------------------------------------------------------------
void TerrainObject::setLevelOfDetailThreshold (const float levelOfDetailThreshold)
{
TerrainObject * const to = getInstance ();
if (to)
getCastedAppearance (to)->setLevelOfDetailThreshold (levelOfDetailThreshold);
}
//-------------------------------------------------------------------
void TerrainObject::drawExtents (const Vector& position_w) const
{
getCastedAppearance (this)->drawExtents (rotateTranslate_w2o (position_w));
}
// ----------------------------------------------------------------------
/**
* Test whether a world x,z position falls within the boundaries of
* the terrain map.
*
* @param position_w a world-space position to test.
*
* @return true if the given position falls within the boundaries
* of the terrain map; false otherwise.
*/
bool TerrainObject::isWithinTerrainBoundaries (Vector const &position_w) const
{
//-- check x and z
float const maxCoordinate = getMapWidthInMeters () * 0.5f;
if ((abs (position_w.x) > maxCoordinate) || (abs (position_w.z) > maxCoordinate))
return false;
//-- check y
if (abs (position_w.y) > getMaximumValidHeightInMeters ())
return false;
return true;
}
//----------------------------------------------------------------------
bool TerrainObject::isPassable(Vector const & position_w) const
{
return getCastedAppearance(this)->isPassable(position_w);
}
//----------------------------------------------------------------------
bool TerrainObject::isPassableForceChunkCreation(Vector const & position_w) const
{
return getCastedAppearance(this)->isPassableForceChunkCreation(position_w);
}
//-------------------------------------------------------------------
void TerrainObject::getPolygonSoup (const Rectangle2d& extent2d_w, IndexedTriangleList& indexedTriangleList) const
{
getCastedAppearance (this)->getPolygonSoup (extent2d_w, indexedTriangleList);
}
//-------------------------------------------------------------------
void TerrainObject::invalidateRegion (const Rectangle2d& extent2d)
{
getCastedAppearance (this)->invalidateRegion (extent2d);
}
//-------------------------------------------------------------------
void TerrainObject::purgeChunks()
{
getCastedAppearance(this)->purgeChunks();
}
//----------------------------------------------------------------------
bool TerrainObject::hasPassableAffectors() const
{
return getCastedAppearance(this)->hasPassableAffectors();
}
//===================================================================
@@ -0,0 +1,165 @@
//===================================================================
//
// TerrainObject.h
// asommers 3-1-99
//
// copyright 1999, bootprint entertainment
// copyright 2001, sony online entertainment
//
//===================================================================
#ifndef INCLUDED_TerrainObject_H
#define INCLUDED_TerrainObject_H
//===================================================================
#include "sharedMath/PackedRgb.h"
#include "sharedMath/Vector2d.h"
#include "sharedObject/Object.h"
#include "sharedTerrain/TerrainGeneratorType.h"
class BoxExtent;
class CollisionInfo;
class IndexedTriangleList;
class Rectangle2d;
class TerrainAppearance;
//===================================================================
class TerrainObject : public Object
{
public:
static void install ();
static TerrainObject* getInstance ();
static const TerrainObject* getConstInstance ();
static void setUseCache (bool useCache);
typedef void (*TerrainChangedFunction) (Rectangle2d const & extent2d);
static void addTerrainChangedFunction (TerrainChangedFunction terrainChangedFunction);
static void terrainChanged (Rectangle2d const & extent2d);
public:
TerrainObject ();
TerrainObject (const ObjectNotification &notification);
virtual ~TerrainObject ();
bool placeObject (Object& object, bool alignToTerrain=false, bool forceChunkCreation=false) const;
bool getLogicalHeight (const Vector& position_w, float waterHeight, float& logicalHeight, float& realHeight) const;
bool getLogicalHeight (const Vector& position_w, float waterHeight, float& logicalHeight, float& realHeight, Vector& normal) const;
bool getHeight (const Vector& position_w, float& height) const;
bool getHeight (const Vector& position_w, float& height, Vector& normal) const;
bool getHeightForceChunkCreation (const Vector& position_w, float& height) const;
const ObjectTemplate* getSurfaceProperties (const Vector& position_w) const;
int getTerrainType (const Vector& position_w) const;
bool getWaterHeight (const Vector& position_w, float& height) const;
TerrainGeneratorWaterType getWaterType (const Vector& position_w) const;
bool isBelowWater (const Vector& position_w) const;
bool isBelowWater (const Vector& position_w, TerrainGeneratorWaterType& waterType, bool ignoreNonTransparentWater=false) const;
bool getWaterHeight (const Vector& position_w, float& height, TerrainGeneratorWaterType& waterType, bool ignoreNonTransparenetWater=false) const;
bool getWater (const Rectangle2d& rectangle) const;
bool getSlope (const Rectangle2d& rectangle) const;
bool getWater (int chunkX, int chunkZ) const;
bool getSlope (int chunkX, int chunkZ) const;
float getMapWidthInMeters () const;
float getMaximumValidHeightInMeters () const;
float getChunkWidthInMeters () const;
int getNumberOfChunks () const;
bool hasHighLevelOfDetailTerrain (const Vector& position_w) const;
int calculateChunkX (const Vector& position_w) const;
int calculateChunkZ (const Vector& position_w) const;
float getChunkHeight (int chunkX, int chunkZ) const;
const BoxExtent* getChunkExtent (const Vector& position_w) const;
const BoxExtent* getChunkExtentForceChunkCreation (const Vector& position_w) const;
bool collide (const Vector& start_w, const Vector& end_w, CollisionInfo& result) const;
bool collideForceChunkCreation (const Vector& start_w, const Vector& end_w, CollisionInfo& result);
bool collideObjects (const Vector& start_w, const Vector& end_w, CollisionInfo& result) const;
bool approximateCollideObjects (const Vector& start_w, const Vector& end_w, CollisionInfo& result) const;
void preRender (const Camera* camera) const;
void postRender () const;
void addReferenceObject (const Object* object);
int getNumberOfReferenceObjects() const;
void removeReferenceObject (const Object* object);
void removeAllReferenceObjects ();
bool isReferenceObject (const Object* object) const;
bool getPauseEnvironment () const;
void setPauseEnvironment (bool pauseEnvironment);
float getEnvironmentCycleTime () const;
const PackedRgb getClearColor () const;
const PackedRgb getFogColor () const;
float getFogDensity () const;
void getTime (int& hour, int& minute) const;
float getTime () const;
void setTime (float time, bool force=false);
bool isDay () const;
bool isTimeLocked() const;
typedef stdvector<std::pair<Vector, float> >::fwd ClearFloraEntryList;
void addClearCollidableFloraObject (const Object* object, const Vector& position_w, float radius);
void removeClearCollidableFloraObject (const Object* object);
void addClearNonCollidableFloraObject (const Object* object, const ClearFloraEntryList& clearFloraEntryList);
void removeClearNonCollidableFloraObject (const Object* object);
static float getHighLevelOfDetailThreshold ();
static void setHighLevelOfDetailThreshold (float highLevelOfDetailThreshold);
static float getLevelOfDetailThreshold ();
static void setLevelOfDetailThreshold (float levelOfDetailThreshold);
void getPolygonSoup (const Rectangle2d& extent2d_w, IndexedTriangleList& indexedTriangleList) const;
void invalidateRegion (const Rectangle2d& extent2d);
//-- debugging
void drawExtents (const Vector& position_w) const;
void purgeChunks();
// void writeChunkData (const Vector& position_w) const;
// bool placeObject (Object& object, const Vector& position_w, bool alignToTerrain=false) const;
// bool placeObject (Object& object, const Vector& position_w, const Vector& up_w) const;
bool isWithinTerrainBoundaries (Vector const &position_w) const;
bool isPassable(Vector const & position_w) const;
bool isPassableForceChunkCreation(Vector const & position_w) const;
bool hasPassableAffectors() const;
private:
static void remove ();
static void debugDump ();
private:
TerrainObject (const TerrainObject&);
TerrainObject& operator= (const TerrainObject&);
private:
static TerrainObject* ms_instance;
static bool ms_useCache;
private:
mutable Vector2d m_cachedPosition_w;
mutable float m_cachedPositionHeight;
mutable Vector2d m_cachedPositionNormal_w;
mutable float m_cachedPositionNormalHeight;
mutable Vector m_cachedPositionNormalNormal_w;
mutable Vector2d m_cachedPositionWater_w;
mutable float m_cachedPositionWaterHeight;
mutable TerrainGeneratorWaterType m_cachedPositionWaterType;
};
//===================================================================
#endif

Some files were not shown because too many files have changed in this diff Show More