From 6d5afc10ffdc0986ebac84f4084f23463e82fa93 Mon Sep 17 00:00:00 2001 From: MarkT Date: Fri, 21 May 2004 23:46:16 +0000 Subject: [PATCH] Added PASAP entity systems This was SVN commit r246. --- source/main.cpp | 24 +- source/premake/premake.lua | 24 +- source/ps/BaseEntity.h | 211 --- source/ps/CStr.cpp | 14 + source/ps/CStr.h | 19 + source/ps/Entity.cpp | 292 ---- source/ps/Entity.h | 138 -- source/ps/Event.cpp | 0 source/ps/Event.h | 46 - source/ps/EventTypes.h | 59 - source/ps/NPFont.cpp | 204 +-- source/ps/NPFont.h | 160 +-- source/ps/NPFontManager.cpp | 204 +-- source/ps/NPFontManager.h | 78 +- source/ps/Overlay.cpp | 44 +- source/ps/Overlay.h | 282 ++-- source/ps/OverlayText.cpp | 64 +- source/ps/OverlayText.h | 216 +-- source/simulation/BaseEntity.cpp | 91 ++ source/simulation/BaseEntity.h | 27 + source/simulation/BaseEntityCollection.cpp | 67 + source/simulation/BaseEntityCollection.h | 24 + source/simulation/Entity.cpp | 242 ++++ source/simulation/Entity.h | 54 + source/simulation/EntityHandles.cpp | 71 + source/simulation/EntityHandles.h | 35 + source/simulation/EntityManager.cpp | 56 + source/simulation/EntityManager.h | 35 + source/simulation/EntityMessage.h | 19 + source/simulation/EntityOrders.h | 36 + source/simulation/EntityProperties.cpp | 160 +++ source/simulation/EntityProperties.h | 65 + source/terrain/AlphaMapCalculator.cpp | 606 ++++---- source/terrain/AlphaMapCalculator.h | 62 +- source/terrain/BlendShapes.h | 284 ++-- source/terrain/Bound.cpp | 324 ++--- source/terrain/Bound.h | 100 +- source/terrain/Camera.cpp | 216 +-- source/terrain/Camera.h | 144 +- source/terrain/Color.h | 60 +- source/terrain/FilePacker.cpp | 152 +- source/terrain/FilePacker.h | 84 +- source/terrain/FileUnpacker.cpp | 202 +-- source/terrain/FileUnpacker.h | 110 +- source/terrain/LightEnv.h | 94 +- source/terrain/MapIO.h | 70 +- source/terrain/MapReader.cpp | 359 ++--- source/terrain/MapReader.h | 94 +- source/terrain/MapWriter.cpp | 452 +++--- source/terrain/MapWriter.h | 70 +- source/terrain/MathUtil.h | 58 +- source/terrain/Matrix3D.cpp | 1080 +++++++------- source/terrain/Matrix3D.h | 240 ++-- source/terrain/MiniPatch.cpp | 68 +- source/terrain/MiniPatch.h | 78 +- source/terrain/Model.cpp | 336 ++--- source/terrain/Model.h | 148 +- source/terrain/ModelDef.cpp | 180 +-- source/terrain/ModelDef.h | 218 +-- source/terrain/ModelRData.cpp | 514 +++---- source/terrain/ModelRData.h | 108 +- source/terrain/ObjectEntry.cpp | 456 +++--- source/terrain/ObjectEntry.h | 93 +- source/terrain/ObjectManager.cpp | 260 ++-- source/terrain/ObjectManager.h | 92 +- source/terrain/Patch.cpp | 120 +- source/terrain/Patch.h | 84 +- source/terrain/PatchRData.cpp | 1106 +++++++------- source/terrain/PatchRData.h | 182 +-- source/terrain/Quaternion.cpp | 378 ++--- source/terrain/Quaternion.h | 86 +- source/terrain/RenderableObject.h | 188 +-- source/terrain/Renderer.cpp | 1510 ++++++++++---------- source/terrain/Renderer.h | 534 +++---- source/terrain/SHCoeffs.cpp | 154 +- source/terrain/SkeletonAnim.cpp | 210 +-- source/terrain/SkeletonAnim.h | 163 ++- source/terrain/Terrain.cpp | 584 ++++---- source/terrain/Terrain.h | 164 +-- source/terrain/TextureEntry.h | 48 +- source/terrain/TextureManager.cpp | 4 +- source/terrain/TransparencyRenderer.cpp | 270 ++-- source/terrain/TransparencyRenderer.h | 62 +- source/terrain/Unit.h | 32 +- source/terrain/UnitManager.cpp | 56 +- source/terrain/UnitManager.h | 48 +- source/terrain/Vector3D.cpp | 306 ++-- source/terrain/Vector3D.h | 134 +- source/terrain/Vector4D.h | 220 +-- source/terrain/terrainMain.cpp | 130 +- 90 files changed, 8823 insertions(+), 8423 deletions(-) delete mode 100755 source/ps/BaseEntity.h delete mode 100755 source/ps/Entity.cpp delete mode 100755 source/ps/Entity.h delete mode 100755 source/ps/Event.cpp delete mode 100755 source/ps/Event.h delete mode 100755 source/ps/EventTypes.h create mode 100755 source/simulation/BaseEntity.cpp create mode 100755 source/simulation/BaseEntity.h create mode 100755 source/simulation/BaseEntityCollection.cpp create mode 100755 source/simulation/BaseEntityCollection.h create mode 100755 source/simulation/Entity.cpp create mode 100755 source/simulation/Entity.h create mode 100755 source/simulation/EntityHandles.cpp create mode 100755 source/simulation/EntityHandles.h create mode 100755 source/simulation/EntityManager.cpp create mode 100755 source/simulation/EntityManager.h create mode 100755 source/simulation/EntityMessage.h create mode 100755 source/simulation/EntityOrders.h create mode 100755 source/simulation/EntityProperties.cpp create mode 100755 source/simulation/EntityProperties.h diff --git a/source/main.cpp b/source/main.cpp index 806a083c49..ad7808e7e6 100755 --- a/source/main.cpp +++ b/source/main.cpp @@ -19,6 +19,10 @@ #include "Renderer.h" #include "Model.h" #include "UnitManager.h" +#include "BaseEntityCollection.h" +#include "Entity.h" +#include "EntityHandles.h" +#include "EntityManager.h" #ifndef NO_GUI #include "gui/GUI.h" @@ -240,7 +244,7 @@ static void Render() g_Renderer.SetCamera(g_Camera); // switch on wireframe for terrain if we want it - g_Renderer.SetTerrainRenderMode(SOLID); + g_Renderer.SetTerrainRenderMode( SOLID ); RenderTerrain(); RenderModels(); @@ -310,6 +314,8 @@ void UpdateWorld(float time) for (uint i=0;im_Model->Update(time); } + g_EntityManager.updateAll( time ); + } @@ -441,6 +447,12 @@ if(argc < 2) // the terrain terr_init(); + // This needs to be done after the renderer has loaded all its actors... + new CBaseEntityCollection; + new CEntityManager; + + g_EntityTemplateCollection.loadTemplates(); + // load a map if we were given one if (g_MapFile) { CStr mapfilename("mods/official/maps/scenarios/"); @@ -455,6 +467,12 @@ if(argc < 2) } } + // Initialize entities + + g_EntityManager.dispatchAll( &CMessage( CMessage::EMSG_INIT ) ); + + PASAPScenario(); + #ifndef NO_GUI in_add_handler(gui_handler); #endif @@ -472,7 +490,7 @@ in_add_handler(terr_handler); g_Config.Update(); while(!quit) { - g_Config.Update(); + //g_Config.Update(); allow_reload(); @@ -515,6 +533,8 @@ in_add_handler(terr_handler); #endif delete &g_Config; + delete &g_EntityManager; + delete &g_EntityTemplateCollection; return 0; } diff --git a/source/premake/premake.lua b/source/premake/premake.lua index 79164bbc76..06e467edb2 100755 --- a/source/premake/premake.lua +++ b/source/premake/premake.lua @@ -2,8 +2,8 @@ dofile("functions.lua") -- Set up the Project project.name = "prometheus" -project.bindir = "../../../binaries/system" -project.libdir = "../../../binaries/system" +project.bindir = "../../binaries/system" +project.libdir = "../../binaries/system" -- Start the package part package = newpackage() @@ -20,22 +20,24 @@ package.config["Release"].target = "ps" -- Files package.files = { -- ps/ - { sourcesfromdirs("../../ps") }, + { sourcesfromdirs("../ps") }, + -- simulation/ + { sourcesfromdirs("../simulation") }, -- lib/ { sourcesfromdirs( - "../../lib", - "../../lib/sysdep", - "../../lib/res") }, + "../lib", + "../lib/sysdep", + "../lib/res") }, -- terrain/ { sourcesfromdirs( - "../../terrain") }, + "../terrain") }, -- gui/ { sourcesfromdirs( - "../../gui") }, + "../gui") }, -- main - { "../../main.cpp" } + { "../main.cpp" } } -package.includepaths = { "../../ps", "../../lib", "../../terrain", "../.." } +package.includepaths = { "../ps", "../simulation", "../lib", "../terrain", ".." } -- Platform Specifics if (OS == "windows") then @@ -44,7 +46,7 @@ if (OS == "windows") then "opengl32", "glu32" } - tinsert(package.files, sourcesfromdirs("../../lib/sysdep/win")) + tinsert(package.files, sourcesfromdirs("../lib/sysdep/win")) package.linkoptions = { "/ENTRY:entry" } package.linkflags = { "static-runtime" } package.buildflags = { "no-main" } diff --git a/source/ps/BaseEntity.h b/source/ps/BaseEntity.h deleted file mode 100755 index 18ca59523c..0000000000 --- a/source/ps/BaseEntity.h +++ /dev/null @@ -1,211 +0,0 @@ -// base entity for all the Units and Buildings in the game 0AD - -// written by Jacob Ricketts - -#if !defined( __0AD_BASE_ENTITY_H_ ) -#define __0AD_BASE_ENTITY_H_ - -#include "ai_common.h" -#include -#include - -class DLLExport CBaseEntity -{ -public: - CBaseEntity( void ) { Clear(); }; - virtual ~CBaseEntity( void ) { }; - - virtual void Clear( void ) { ClearBaseEntity(); }; - //virtual bool Update( void ) = 0; - //virtual bool HandleMessage( const Message &msg ) = 0; - - // === ID FUNCTIONS === - inline - USHORT GetID( void ) { return( m_nID ); }; - - inline - USHORT GetTeamID( void ) { return( m_byteTeamID ); }; - - inline - BYTE AddAllies( BYTE bitflagTeams ) { return( m_bitflagAllies |= bitflagTeams ); }; - - inline - BYTE RemoveAllies( BYTE bitflagTeams ) { return( m_bitflagAllies &= ~bitflagTeams ); }; - - - // === HIT POINT FUNCTIONS === - inline - virtual USHORT GetHitPoints( void ) { std::cout << "CBaseEntity.GetHitPoints() called..." << endl; return( m_nHitPoints ); }; - - inline - virtual USHORT GetBaseHitPoints( void ) { return( m_nBaseHitPoints ); }; - - inline - virtual USHORT GetMaxHitPoints( void ) { return( m_nMaxHitPoints ); }; - - inline - virtual short GetRegenRate( void ) { return( m_nBaseRegenRate ); }; - - - // === ATTACK STAT FUNCTIONS === - inline - virtual USHORT GetAttackStrength( void ) { return( m_nBaseAttackStrength ); }; - - inline - virtual USHORT GetAttackRate( void ) { return( m_nBaseAttackRate ); }; - - inline - virtual USHORT GetAreaOfEffect( void ) { return( m_nBaseAreaOfEffect ); }; - - inline - virtual USHORT GetMaxRange( void ) { return( m_nBaseMaxRange ); }; - - inline - virtual USHORT GetMinRange( void ) { return( m_nBaseMinRange ); }; - - inline - virtual USHORT GetMeleeArmor( void ) { return( m_nBaseMeleeArmor ); } ; - - inline - virtual USHORT GetPierceArmor( void ) { return( m_nBasePierceArmor ); }; - - - // === MISC ATTRIBUTES === - inline - virtual const std::vector& AvailableToCivs( void ) { return( m_vAvailableToCivs ); }; - - inline - virtual const Vector3D& GetPosition( void ) { return( m_vPos ); }; - - inline - virtual bool BoostsMorale( void ) { return( m_bBoostsMorale ); }; - - inline - virtual bool DemoralizesEnemies( void ) { return( m_bDemoralizesEnemies ); }; - - inline - virtual USHORT GetActionRate( void ) { return( m_nBaseActionRate ); }; - - inline - virtual USHORT GetAreaOfInfluence( void ) { return( m_nBaseAreaOfInfluence ); }; - - inline - virtual USHORT GetLOS( void ) { return( m_nBaseLOS ); }; - - - // === BUILD STATS === - inline - virtual USHORT GetBuildTime( void ) { return( m_nBuildTime ); }; - - inline - virtual USHORT GetReqFoodToBuild( void ) { return( m_nFoodReqToBuild ); }; - - inline - virtual USHORT GetReqGoldToBuild( void ) { return( m_nGoldReqToBuild ); }; - - inline - virtual USHORT GetReqMetalToBuild( void ) { return( m_nMetalReqToBuild ); }; - - inline - virtual USHORT GetReqStoneToBuild( void ) { return( m_nStoneReqToBuild ); }; - - inline - virtual USHORT GetReqWoodToBuild( void ) { return( m_nWoodReqToBuild ); }; - - inline - virtual const std::vector& GetBuildingsReqToBuild( void ) { return( m_vBuildingsReqToBuild ); }; - - inline - virtual const std::vector& GetTechsReqToBuild( void ) { return( m_vTechsReqToBuild ); }; - - - // === UPGRADE STATS === - inline - virtual USHORT UpgradesTo( void ) { return( m_nUpgradesTo ); }; - - inline - virtual USHORT GetUpgradeTime( void ) { return( m_nUpgradeTime ); }; - - inline - virtual USHORT GetReqFoodToUpgrade( void ) { return( m_nFoodReqToUpgrade ); }; - - inline - virtual USHORT GetReqGoldToUpgrade( void ) { return( m_nGoldReqToUpgrade ); }; - - inline - virtual USHORT GetReqMetalToUpgrade( void ) { return( m_nMetalReqToUpgrade ); }; - - inline - virtual USHORT GetReqStoneToUpgrade( void ) { return( m_nStoneReqToUpgrade ); }; - - inline - virtual USHORT GetReqWoodToUpgrade( void ) { return( m_nWoodReqToUpgrade ); }; - - inline - virtual const std::vector& GetBuildingsReqToUpgrade( void ) { return( m_vBuildingsReqToUpgrade ); }; - - inline - virtual const std::vector& GetTechsReqToUpgrade( void ) { return( m_vTechsReqToUpgrade ); }; - - BYTE m_nCurrentFrame; - -protected: - void ClearBaseEntity( void ); - - USHORT m_nID; // ID for this entity - BYTE m_byteTeamID; // ID of the team this entity is on - BYTE m_bitflagAllies; // bitflag to contain the list of allies - - - std::vector m_vAvailableToCivs; // a list of Civs that can create this entity - - // === ATTRIBUTES === - USHORT m_nHitPoints; // current amount of hit points - USHORT m_nBaseHitPoints; // initial hit points - USHORT m_nMaxHitPoints; // maximum hit points - short m_nBaseRegenRate; // rate of health regeneation - - USHORT m_nBaseAttackStrength; // base strength - USHORT m_nBaseAttackRate; // rate of attack - USHORT m_nBaseMinRange; // minimum range of attack - USHORT m_nBaseMaxRange; // maximum range of attack - USHORT m_nBaseActionRate; // rate of actions - USHORT m_nBaseAreaOfEffect; // area of effect - - USHORT m_nBaseAreaOfInfluence; // area of influence - - USHORT m_nBaseMeleeArmor; // armor rating against melee attacks - USHORT m_nBasePierceArmor; // armor rating against projectile attacks - - USHORT m_nBaseLOS; // line of sight distance - - USHORT m_nBuildTime; // time required to build - USHORT m_nUpgradeTime; // time required to upgrade - - USHORT m_nFoodReqToBuild; // amount of food required to build - USHORT m_nGoldReqToBuild; // amount of gold required to build - USHORT m_nMetalReqToBuild; // amount of metal required to build - USHORT m_nStoneReqToBuild; // amount of stone required to build - USHORT m_nWoodReqToBuild; // amount of wood required to build - std::vector m_vBuildingsReqToBuild; // buildings required to build this entity - std::vector m_vTechsReqToBuild; // techs required to build this entity - - USHORT m_nFoodReqToUpgrade; // cost to upgrade (food) - USHORT m_nGoldReqToUpgrade; // cost to upgrade (gold) - USHORT m_nMetalReqToUpgrade; // cost to upgrade (metal) - USHORT m_nStoneReqToUpgrade; // cost to upgrade (stone) - USHORT m_nWoodReqToUpgrade; // cost to upgrade (wood) - std::vector m_vBuildingsReqToUpgrade; // buildings required to upgrade this entity - std::vector m_vTechsReqToUpgrade; // techs required to upgrade this entity - - USHORT m_nUpgradesTo; // ID of entity this unit will upgrade to if possible - - bool m_bBoostsMorale; // does this entity boost Morale? - bool m_bDemoralizesEnemies; // does this entity demoralize enemy units? - - Vector3D m_vPos; // position on the map - -private: -}; - -#endif \ No newline at end of file diff --git a/source/ps/CStr.cpp b/source/ps/CStr.cpp index b0c78947cb..8d33d4936e 100755 --- a/source/ps/CStr.cpp +++ b/source/ps/CStr.cpp @@ -398,6 +398,20 @@ ostream &operator<<(ostream &os, CStr &Str) return os; } +size_t CStr::GetHashCode() const +{ + // FNV-1 hash for 64 bit integers. + size_t hash = 14695981039346656037; + const char* data = m_String.data(); + for( int t = 0; t < m_String.length(); t++ ) + { + hash *= 1099511628211; + hash ^= *(data++); + } + return( hash ); + +} + uint CStr::GetSerializedLength() const { return uint(m_String.length()+1); diff --git a/source/ps/CStr.h b/source/ps/CStr.h index 830141b04e..8d7bedcb9f 100755 --- a/source/ps/CStr.h +++ b/source/ps/CStr.h @@ -30,6 +30,8 @@ More Info: */ +// Last modified: 19 May 04, Mark Thompson (mot20@cam.ac.uk / mark@wildfiregames.com) + #ifndef CSTR_H #define CSTR_H @@ -177,6 +179,8 @@ public: inline const char *c_str() { return m_String.c_str(); } + + size_t GetHashCode() const; // Serialization functions virtual uint GetSerializedLength() const; @@ -188,6 +192,21 @@ private: TCHAR m_ConversionBuffer[CONVERSION_BUFFER_SIZE]; }; +class CStr_hash_compare +{ +public: + static const size_t bucket_size = 1; + static const size_t min_buckets = 16; + size_t operator()( const CStr& Key ) const + { + return( Key.GetHashCode() ); + } + bool operator()( const CStr& _Key1, const CStr& _Key2 ) const + { + return( _Key1 < _Key2 ); + } +}; + // overloaded operator for ostreams ostream &operator<<(ostream &os, CStr &Str); diff --git a/source/ps/Entity.cpp b/source/ps/Entity.cpp deleted file mode 100755 index b8ca7aa234..0000000000 --- a/source/ps/Entity.cpp +++ /dev/null @@ -1,292 +0,0 @@ -// Last modified: 19 January 2004 (Mark Thompson) - -#include "Entity.h" - -//-------------------------------------------------------- -// CEntity: Entity class -//-------------------------------------------------------- - -//-------------------------------------------------------- -// CEntity::CEntity() -//-------------------------------------------------------- - -CEntity::CEntity() -{ -} - -//-------------------------------------------------------- -// CEntity::~CEntity() -//-------------------------------------------------------- - -CEntity::~CEntity() -{ -} - -//-------------------------------------------------------- -// CEntity::Dispatch( CEvent* ev ) -// -// Handles the event ev, sent by the scheduler -//-------------------------------------------------------- - -void CEntity::Dispatch( CEvent* ev ) -{ -} - -//-------------------------------------------------------- -// CHandle: Stores entity refcounts, etc. -//-------------------------------------------------------- - -//-------------------------------------------------------- -// CHandle::CHandle() -//-------------------------------------------------------- - -CHandle::CHandle() -{ - ptr = NULL; - refcount = 0; -} - -//-------------------------------------------------------- -// CHandle::~CHandle() -//-------------------------------------------------------- - -CHandle::~CHandle() -{ - if( refcount ) - { - // WARNING: RELEASING LIVE HANDLE! - // TODO: Link this into the new logfile system. - } - delete ptr; -} - -//-------------------------------------------------------- -// CHandlePool: Tracks entity handles. -//-------------------------------------------------------- - -//-------------------------------------------------------- -// CHandlePool::CHandlePool() -//-------------------------------------------------------- - -CHandlePool::CHandlePool() -{ - for( unsigned short t = 0; t < MAX_HANDLES; t++ ) - { - Pool[t].nextfree = t + 1; - } - FreeHandle = 0; -} - -//-------------------------------------------------------- -// CHandlePool::~CHandlePool() -//-------------------------------------------------------- - -CHandlePool::~CHandlePool() -{ - //Terminating, clearing remaining handles... -} - -//-------------------------------------------------------- -// CHandlePool::Assign( CEntity* ptr ) -//-------------------------------------------------------- - -HEntity CHandlePool::Assign( CEntity* ptr ) -{ - assert( FreeHandle != BAD_HANDLE ); - unsigned short i = FreeHandle; - ptr->Handle = HEntityWeak( i ); - FreeHandle = Pool[i].nextfree; - Pool[i].ptr = ptr; - return HEntity( i ); -} - -//-------------------------------------------------------- -// CHandlePool::Destroy( unsigned short index ) -//-------------------------------------------------------- - -void CHandlePool::Destroy( unsigned short index ) -{ - //Garbage collection - delete Pool[index].ptr; - Pool[index].nextfree = FreeHandle; - Pool[index].refcount = 0; - FreeHandle = index; -} - -//-------------------------------------------------------- -// HEntity: Refcounted handle to entities. -//-------------------------------------------------------- - -//-------------------------------------------------------- -// HEntity::HEntity() -//-------------------------------------------------------- - -HEntity::HEntity() -{ - index = BAD_HANDLE; -} - -//-------------------------------------------------------- -// HEntity::HEntity( unsigned short index ) -//-------------------------------------------------------- - -HEntity::HEntity( unsigned short _index ) -{ - index = _index; - AddRef(); -} - -//-------------------------------------------------------- -// HEntity::HEntity( const HEntity& copy ) -//-------------------------------------------------------- - -HEntity::HEntity( const HEntity& copy ) -{ - index = copy.index; - AddRef(); -} - -//-------------------------------------------------------- -// HEntity::HEntity( const HEntityWeak& copy ) -//-------------------------------------------------------- - -HEntity::HEntity( const HEntityWeak& copy ) -{ - index = copy.index; - AddRef(); -} - -//-------------------------------------------------------- -// HEntity::AddRef() -// -// Increments reference count -//-------------------------------------------------------- - -void HEntity::AddRef() -{ - if( index == BAD_HANDLE ) return; - g_HandlePool.Pool[index].refcount++; -} - -//-------------------------------------------------------- -// HEntity::DecRef() -// -// Decrements reference count -//-------------------------------------------------------- - -void HEntity::DecRef() -{ - if( index == BAD_HANDLE ) return; - if( !g_HandlePool.Pool[index].refcount ) return; - if( --g_HandlePool.Pool[index].refcount == 0 ) - g_HandlePool.Destroy( index ); -} - -//-------------------------------------------------------- -// HEntity::operator=( const HEntity& copy ) -//-------------------------------------------------------- - -void HEntity::operator=( const HEntity& copy ) -{ - DecRef(); - index = copy.index; - AddRef(); -} - -//-------------------------------------------------------- -// HEntity::operator=( const HEntityWeak& copy ) -//-------------------------------------------------------- - -void HEntity::operator=( const HEntityWeak& copy ) -{ - DecRef(); - index = copy.index; - AddRef(); -} - -//-------------------------------------------------------- -// HEntity::operator*() -//-------------------------------------------------------- - -CEntity& HEntity::operator*() -{ - assert( index != BAD_HANDLE ); - assert( g_HandlePool.Pool[index].ptr ); - return( *g_HandlePool.Pool[index].ptr ); -} - -//-------------------------------------------------------- -// HEntity: operator->() -//-------------------------------------------------------- - -CEntity* HEntity::operator->() -{ - assert( index != BAD_HANDLE ); - assert( g_HandlePool.Pool[index].ptr ); - return( g_HandlePool.Pool[index].ptr ); -} - -//-------------------------------------------------------- -// HEntity::~HEntity() -//-------------------------------------------------------- - -HEntity::~HEntity() -{ - DecRef(); -} - -//-------------------------------------------------------- -// HEntityWeak: Like HEntity, but it isn't refcounted. -// used mainly to hold references-to-self. -// It's slightly faster, and automatically -// converts to a safe HEntity when needed. -//-------------------------------------------------------- - -//-------------------------------------------------------- -// HEntityWeak::HEntityWeak() -//-------------------------------------------------------- - -HEntityWeak::HEntityWeak() -{ - index = BAD_HANDLE; -} - -//-------------------------------------------------------- -// HEntityWeak::HEntityWeak( unsigned short _index ) -//-------------------------------------------------------- - -HEntityWeak::HEntityWeak( unsigned short _index ) -{ - index = _index; -} - -//-------------------------------------------------------- -// HEntityWeak::operator*() -//-------------------------------------------------------- - -CEntity& HEntityWeak::operator*() -{ - assert( index != BAD_HANDLE ); - assert( g_HandlePool.Pool[index].ptr ); - return( *g_HandlePool.Pool[index].ptr ); -} - -//-------------------------------------------------------- -// HEntityWeak::operator->() -//-------------------------------------------------------- - -CEntity* HEntityWeak::operator->() -{ - assert( index != BAD_HANDLE ); - assert( g_HandlePool.Pool[index].ptr ); - return( g_HandlePool.Pool[index].ptr ); -} - -//-------------------------------------------------------- -// HEntityWeak::operator HEntity() -//-------------------------------------------------------- - -HEntityWeak::operator HEntity() -{ - return HEntity( index ); -} diff --git a/source/ps/Entity.h b/source/ps/Entity.h deleted file mode 100755 index 95eb3aba52..0000000000 --- a/source/ps/Entity.h +++ /dev/null @@ -1,138 +0,0 @@ -/* -Entity.h - -Entities and associated classes -Mark Thompson (markt@0ad.wildfiregames.com) - -Last modified: 19 January 2004 (Mark Thompson) - ---Overview-- - -Contains the class definitions for entities, netsafe entity handles, handle manager - ---Usage-- - -TODO - ---Examples-- - -TODO - ---More info-- - -TDD at http://forums.wildfiregames.com/0ad - -*/ - -#ifndef ENTITY_INCLUDED -#define ENTITY_INCLUDED - -#include "assert.h" -#include "stdio.h" -#include "Singleton.h" -#include "Event.h" - -// Handle defines - -#define MAX_HANDLES 8192 -#define BAD_HANDLE MAX_HANDLES -#define NULL 0 -typedef unsigned long DWORD; - -// Forward-declarations - -class CHandlePool; -class CEntity; -class HEntity; -class HEntityWeak; - -// HEntityWeak: Weak (non-refcounted) smart pointer - -class HEntityWeak -{ - friend class CHandlePool; - friend class HEntity; -private: - unsigned short index; - HEntityWeak( unsigned short index ); -public: - HEntityWeak(); - CEntity& operator*(); - CEntity* operator->(); - operator HEntity(); -}; - -// CEntity: Entity class - -class CEntity -{ - friend class CHandlePool; -private: - HEntityWeak Handle; // Reference to self, to include in messages, etc. - // Weak handle isn't refcounted, but is as soon - // as it gets passed out of this class. -public: - CEntity(); - ~CEntity(); - void Dispatch( CEvent* ev ); -}; - -// CHandle: Entity handles, used by manager class - -class CHandle -{ - friend class CHandlePool; - friend class HEntity; - friend class HEntityWeak; -private: - CEntity* ptr; - unsigned short refcount; - unsigned short nextfree; //Linked list for free handles - CHandle(); - ~CHandle(); -}; - -// HEntity: Entity smart pointer - -class HEntity -{ - friend class CHandlePool; - friend class HEntityWeak; -private: - unsigned short index; - HEntity( unsigned short index ); - void AddRef(); - void DecRef(); -public: - CEntity& operator*(); - CEntity* operator->(); - HEntity(); - HEntity( const HEntity& copy ); - HEntity( const HEntityWeak& copy ); - void operator=( const HEntity& copy ); - void operator=( const HEntityWeak& copy ); - ~HEntity(); -}; - -// CHandlePool: Tracks entity handles - -#define g_HandlePool CHandlePool::GetSingleton() - -class CHandlePool : public Singleton -{ - friend class HEntity; - friend class HEntityWeak; -private: - unsigned short FreeHandle; - CHandle Pool[MAX_HANDLES]; -public: - CHandlePool(); - ~CHandlePool(); - HEntity Assign( CEntity* ptr ); - HEntity Create() { return Assign( new CEntity ); }; - void Destroy( unsigned short index ); -}; - -#endif // !defined( ENTITY_INCLUDED ) - - diff --git a/source/ps/Event.cpp b/source/ps/Event.cpp deleted file mode 100755 index e69de29bb2..0000000000 diff --git a/source/ps/Event.h b/source/ps/Event.h deleted file mode 100755 index f6187771a2..0000000000 --- a/source/ps/Event.h +++ /dev/null @@ -1,46 +0,0 @@ -/* -Event.h - -Game event (scheduled messages) definitions - -Mark Thompson (markt@0ad.wildfiregames.com) - -Last modified: 19 January 2004 (Mark Thompson) - ---Overview-- - -Contains the class definitions for serializable event messages. ---Usage-- - -TODO - ---Examples-- - -TODO - ---More info-- - -TDD at http://forums.wildfiregames.com/0ad - -*/ - -#ifndef EVENT_INCLUDED -#define EVENT_INCLUDED - -#include "assert.h" -#include "stdio.h" -#include "Network/Serialization.h" -#include "Entity.h" -#include "Network/NetMessage.h" - -class CEvent : public CNetMessage -{ -public: - virtual uint GetSerializedLength() = 0; - virtual u8* Serialize( u8* buffer ) = 0; -}; - - -#endif // EVENT_INCLUDED - - diff --git a/source/ps/EventTypes.h b/source/ps/EventTypes.h deleted file mode 100755 index d7efb4df4f..0000000000 --- a/source/ps/EventTypes.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - - Net Message Creator registration - -*/ - - #ifdef CREATING_NMT - - //HACKA HACKA HACKA HACKA HACKA HACK... - - #ifdef NMT_CREATOR_PASS_CLASSDEF - -/* - - The Event classes; - - Adding an event currently requires four steps. - - One, create the event class within the NMT_CREATOR_PASS_CLASSDEF - ifdef. The classEvent macro will help. - - Two, assign an message type in NetMessage.h. - - Three, provide a deserializer function mapping in the - NMT_CREATOR_PASS_REGISTRATION ifdef, below. - - Four, implement the interface ISerializable for the new class in - Event.cpp. - -*/ - - #define classEvent( _ev ) \ - struct CEvent##_ev : public CEvent \ - { \ - public: \ - uint GetSerializedLength(); \ - u8* Serialize( u8* buffer ); \ - static CNetMessage* Deserialize( const u8* buffer, \ - uint length ); - - - -/* - classEvent( TestOnly ) - int16 TheIntegerIveGot; - }; -*/ - - #endif - - #ifdef NMT_CREATOR_PASS_REGISTRATION - -/* - { NMT_Event_IveGotAnInteger, CEventTestOnly::Deserialize }, -*/ - - #endif - - #endif \ No newline at end of file diff --git a/source/ps/NPFont.cpp b/source/ps/NPFont.cpp index 1a35211bba..c0f2072077 100755 --- a/source/ps/NPFont.cpp +++ b/source/ps/NPFont.cpp @@ -1,102 +1,102 @@ -#include "NPFont.h" - -NPFont::NPFont() -{ -} - -NPFont::~NPFont() -{ -} - -NPFont* NPFont::create(const char* name) -{ - // try and open up the file - FILE* fp=fopen(name,"rb"); - if (!fp) return 0; - - // create a new font - NPFont* font=new NPFont; - - // read text metrics - if (fread(&font->_metrics,sizeof(font->_metrics),1,fp)!=1) { - fclose(fp); - delete font; - return 0; - } - - // read characters - if (fread(font->_chars,sizeof(CharData)*128,1,fp)!=1) { - fclose(fp); - delete font; - return 0; - } - - // read number of rows, cols of characters - if (fread(&font->_numRows,sizeof(font->_numRows),1,fp)!=1) { - fclose(fp); - delete font; - return 0; - } - if (fread(&font->_numCols,sizeof(font->_numCols),1,fp)!=1) { - fclose(fp); - delete font; - return 0; - } - - // read texture dimensions - if (fread(&font->_texwidth,sizeof(font->_texwidth),1,fp)!=1) { - fclose(fp); - delete font; - return 0; - } - if (fread(&font->_texheight,sizeof(font->_texheight),1,fp)!=1) { - fclose(fp); - delete font; - return 0; - } - - // read texture name - unsigned int namelen; - if (fread(&namelen,sizeof(unsigned int),1,fp)!=1) { - fclose(fp); - delete font; - return 0; - } - CStr texname("gui/fonts/"); - for (uint i=0;i_texture.SetName((const char*) texname); - - // store font name - font->_name=name; - - // return created font - return font; -} - -// GetOutputStringSize: return the rendered size of given font -void NPFont::GetOutputStringSize(const char* str,int& sx,int& sy) -{ - sx=0; - sy=_metrics._height; - - int i=0; - while (str && str[i]!='\0') { - const NPFont::CharData& cdata=chardata(str[i]); - const int* cw=&cdata._widthA; - - if (cw[0]>0) sx+=cw[0]; - sx+=cw[1]+1; - if (cw[2]>0) sx+=cw[2]; - - i++; - } -} - +#include "NPFont.h" + +NPFont::NPFont() +{ +} + +NPFont::~NPFont() +{ +} + +NPFont* NPFont::create(const char* name) +{ + // try and open up the file + FILE* fp=fopen(name,"rb"); + if (!fp) return 0; + + // create a new font + NPFont* font=new NPFont; + + // read text metrics + if (fread(&font->_metrics,sizeof(font->_metrics),1,fp)!=1) { + fclose(fp); + delete font; + return 0; + } + + // read characters + if (fread(font->_chars,sizeof(CharData)*128,1,fp)!=1) { + fclose(fp); + delete font; + return 0; + } + + // read number of rows, cols of characters + if (fread(&font->_numRows,sizeof(font->_numRows),1,fp)!=1) { + fclose(fp); + delete font; + return 0; + } + if (fread(&font->_numCols,sizeof(font->_numCols),1,fp)!=1) { + fclose(fp); + delete font; + return 0; + } + + // read texture dimensions + if (fread(&font->_texwidth,sizeof(font->_texwidth),1,fp)!=1) { + fclose(fp); + delete font; + return 0; + } + if (fread(&font->_texheight,sizeof(font->_texheight),1,fp)!=1) { + fclose(fp); + delete font; + return 0; + } + + // read texture name + unsigned int namelen; + if (fread(&namelen,sizeof(unsigned int),1,fp)!=1) { + fclose(fp); + delete font; + return 0; + } + CStr texname("gui/fonts/"); + for (uint i=0;i_texture.SetName((const char*) texname); + + // store font name + font->_name=name; + + // return created font + return font; +} + +// GetOutputStringSize: return the rendered size of given font +void NPFont::GetOutputStringSize(const char* str,int& sx,int& sy) +{ + sx=0; + sy=_metrics._height; + + int i=0; + while (str && str[i]!='\0') { + const NPFont::CharData& cdata=chardata(str[i]); + const int* cw=&cdata._widthA; + + if (cw[0]>0) sx+=cw[0]; + sx+=cw[1]+1; + if (cw[2]>0) sx+=cw[2]; + + i++; + } +} + diff --git a/source/ps/NPFont.h b/source/ps/NPFont.h index 1c7077a7e9..5080b2e708 100755 --- a/source/ps/NPFont.h +++ b/source/ps/NPFont.h @@ -1,80 +1,80 @@ -#ifndef _NPFONT_H -#define _NPFONT_H - -// necessary includes -#include "CStr.h" -#include "terrain/Texture.h" - -///////////////////////////////////////////////////////////////////////////////////////// -// NPFont: -class NPFont -{ -public: - struct CharData { - int _width; // total width in pixels - int _widthA,_widthB,_widthC; // ABC widths - }; - -public: - // create - create font from given font file - static NPFont* create(const char* fontfilename); - // destructor - ~NPFont(); - - // accessor for name (font file name) - const char* name() const { return (const char*) _name; } - - // accessors for font metrics - int width(int c) const { assert(c>=0 && c<128); return _chars[c]._width; } - int height() const { return _metrics._height; } - int descent() const { return _metrics._descent; } - int maxcharwidth() const { return _metrics._maxcharwidth; } - - // accessors for texture data - int textureWidth() const { return _texwidth; } - int textureHeight() const { return _texheight; } - CTexture& texture() { return _texture; } - - - - int numCols() const { return _numCols; } - int numRows() const { return _numRows; } - - // accessor for character data - const CharData& chardata(char c) const { - assert(c>=0 && c<128); - return _chars[c]; - } - - void GetOutputStringSize(const char* str,int& sx,int& sy); - -private: - // constructor (private - all fonts created through create()) - NPFont(); - - // font name - CStr _name; - // font texture width - int _texwidth; - // font texture height - int _texheight; - // font texture - CTexture _texture; - // font metrics - struct { - int _height; - int _descent; - int _maxcharwidth; - } _metrics; - // number of rows of characters - int _numRows; - // number of columns of characters - int _numCols; - // details about specific characters in this font - CharData _chars[128]; -}; -///////////////////////////////////////////////////////////////////////////////////////// - - -#endif - +#ifndef _NPFONT_H +#define _NPFONT_H + +// necessary includes +#include "CStr.h" +#include "terrain/Texture.h" + +///////////////////////////////////////////////////////////////////////////////////////// +// NPFont: +class NPFont +{ +public: + struct CharData { + int _width; // total width in pixels + int _widthA,_widthB,_widthC; // ABC widths + }; + +public: + // create - create font from given font file + static NPFont* create(const char* fontfilename); + // destructor + ~NPFont(); + + // accessor for name (font file name) + const char* name() const { return (const char*) _name; } + + // accessors for font metrics + int width(int c) const { assert(c>=0 && c<128); return _chars[c]._width; } + int height() const { return _metrics._height; } + int descent() const { return _metrics._descent; } + int maxcharwidth() const { return _metrics._maxcharwidth; } + + // accessors for texture data + int textureWidth() const { return _texwidth; } + int textureHeight() const { return _texheight; } + CTexture& texture() { return _texture; } + + + + int numCols() const { return _numCols; } + int numRows() const { return _numRows; } + + // accessor for character data + const CharData& chardata(char c) const { + assert(c>=0 && c<128); + return _chars[c]; + } + + void GetOutputStringSize(const char* str,int& sx,int& sy); + +private: + // constructor (private - all fonts created through create()) + NPFont(); + + // font name + CStr _name; + // font texture width + int _texwidth; + // font texture height + int _texheight; + // font texture + CTexture _texture; + // font metrics + struct { + int _height; + int _descent; + int _maxcharwidth; + } _metrics; + // number of rows of characters + int _numRows; + // number of columns of characters + int _numCols; + // details about specific characters in this font + CharData _chars[128]; +}; +///////////////////////////////////////////////////////////////////////////////////////// + + +#endif + diff --git a/source/ps/NPFontManager.cpp b/source/ps/NPFontManager.cpp index bd7c472a38..e73fd3db9a 100755 --- a/source/ps/NPFontManager.cpp +++ b/source/ps/NPFontManager.cpp @@ -1,102 +1,102 @@ -#include "NPFontManager.h" -#include "NPFont.h" - -#include - -// the sole instance of the NPFontManager -NPFontManager* NPFontManager::_instance=0; - -/////////////////////////////////////////////////////////////////////////////// -// instance: return the sole font manager instance -NPFontManager& NPFontManager::instance() -{ - if (!_instance) { - _instance=new NPFontManager; - } - return *_instance; -} - -/////////////////////////////////////////////////////////////////////////////// -// NPFontManager constructor (hidden); access available only through instance() -NPFontManager::NPFontManager() -{ -} - -/////////////////////////////////////////////////////////////////////////////// -// NPFontManager destructor -NPFontManager::~NPFontManager() -{ - // delete all collected fonts - for (uint i=0;i<_fonts.size();++i) { - delete _fonts[i]; - } -} - -/////////////////////////////////////////////////////////////////////////////// -// release this font manager -void NPFontManager::release() -{ - if (_instance) { - delete _instance; - _instance=0; - } -} - -/////////////////////////////////////////////////////////////////////////////// -// add a font; return the created font, or 0 if not found -NPFont* NPFontManager::add(const char* name) -{ - // try and find font first - NPFont* font=find(name); - if (font) { - // ok - already got this font, return it - return font; - } - - // try and create font - font=NPFont::create(name); - if (font) { - // success - add to list - _fonts.push_back(font); - return font; - } else { - // mark as bad? just return failure for the moment - return 0; - } -} - -/////////////////////////////////////////////////////////////////////////////// -// remove a font -bool NPFontManager::remove(const char* name) -{ - // try and find font first - NPFont* font=find(name); - if (!font) { - // font not present .. - return false; - } else { - typedef std::vector::iterator Iter; - Iter iter=std::find(_fonts.begin(),_fonts.end(),font); - assert(iter != _fonts.end()); - _fonts.erase(iter); - } - - return true; -} - -/////////////////////////////////////////////////////////////////////////////// -// find a font (return 0 if not found) -NPFont* NPFontManager::find(const char* name) -{ - // scan through font list checking names - for (uint i=0;i<_fonts.size();++i) { - NPFont* font=_fonts[i]; - if (strcmp(name,font->name())==0) { - return font; - } - } - - // got this far, font not found - return 0; - -} +#include "NPFontManager.h" +#include "NPFont.h" + +#include + +// the sole instance of the NPFontManager +NPFontManager* NPFontManager::_instance=0; + +/////////////////////////////////////////////////////////////////////////////// +// instance: return the sole font manager instance +NPFontManager& NPFontManager::instance() +{ + if (!_instance) { + _instance=new NPFontManager; + } + return *_instance; +} + +/////////////////////////////////////////////////////////////////////////////// +// NPFontManager constructor (hidden); access available only through instance() +NPFontManager::NPFontManager() +{ +} + +/////////////////////////////////////////////////////////////////////////////// +// NPFontManager destructor +NPFontManager::~NPFontManager() +{ + // delete all collected fonts + for (uint i=0;i<_fonts.size();++i) { + delete _fonts[i]; + } +} + +/////////////////////////////////////////////////////////////////////////////// +// release this font manager +void NPFontManager::release() +{ + if (_instance) { + delete _instance; + _instance=0; + } +} + +/////////////////////////////////////////////////////////////////////////////// +// add a font; return the created font, or 0 if not found +NPFont* NPFontManager::add(const char* name) +{ + // try and find font first + NPFont* font=find(name); + if (font) { + // ok - already got this font, return it + return font; + } + + // try and create font + font=NPFont::create(name); + if (font) { + // success - add to list + _fonts.push_back(font); + return font; + } else { + // mark as bad? just return failure for the moment + return 0; + } +} + +/////////////////////////////////////////////////////////////////////////////// +// remove a font +bool NPFontManager::remove(const char* name) +{ + // try and find font first + NPFont* font=find(name); + if (!font) { + // font not present .. + return false; + } else { + typedef std::vector::iterator Iter; + Iter iter=std::find(_fonts.begin(),_fonts.end(),font); + assert(iter != _fonts.end()); + _fonts.erase(iter); + } + + return true; +} + +/////////////////////////////////////////////////////////////////////////////// +// find a font (return 0 if not found) +NPFont* NPFontManager::find(const char* name) +{ + // scan through font list checking names + for (uint i=0;i<_fonts.size();++i) { + NPFont* font=_fonts[i]; + if (strcmp(name,font->name())==0) { + return font; + } + } + + // got this far, font not found + return 0; + +} diff --git a/source/ps/NPFontManager.h b/source/ps/NPFontManager.h index 79a7c01dde..da1a21176b 100755 --- a/source/ps/NPFontManager.h +++ b/source/ps/NPFontManager.h @@ -1,39 +1,39 @@ -#ifndef _FONTMANAGER_H -#define _FONTMANAGER_H - -// necessary includes -#include - -// necessary declaration -class NPFont; - -class NPFontManager -{ -public: - // accessor; return the font manager - static NPFontManager& instance(); - // release this font manager - static void release(); - - // destructor - ~NPFontManager(); - - // add a font; return the created font, or 0 if not found - NPFont* add(const char* name); - // remove a font - bool remove(const char* name); - // find a font (return 0 if not found) - NPFont* find(const char* name); - -private: - // hidden constructor; access available only through instance() - NPFontManager(); - - // list of recorded fonts - std::vector _fonts; - - // the sole instance of the FontManager - static NPFontManager* _instance; -}; - -#endif +#ifndef _FONTMANAGER_H +#define _FONTMANAGER_H + +// necessary includes +#include + +// necessary declaration +class NPFont; + +class NPFontManager +{ +public: + // accessor; return the font manager + static NPFontManager& instance(); + // release this font manager + static void release(); + + // destructor + ~NPFontManager(); + + // add a font; return the created font, or 0 if not found + NPFont* add(const char* name); + // remove a font + bool remove(const char* name); + // find a font (return 0 if not found) + NPFont* find(const char* name); + +private: + // hidden constructor; access available only through instance() + NPFontManager(); + + // list of recorded fonts + std::vector _fonts; + + // the sole instance of the FontManager + static NPFontManager* _instance; +}; + +#endif diff --git a/source/ps/Overlay.cpp b/source/ps/Overlay.cpp index e3f356c3f1..bb0e9568c1 100755 --- a/source/ps/Overlay.cpp +++ b/source/ps/Overlay.cpp @@ -1,23 +1,23 @@ -/* -COverlay -by Rich Cross -rich@0ad.wildfiregames.com -*/ - -#include "Overlay.h" - -COverlay::COverlay() - : m_Rect(CRect(0,0,0,0)), m_Z(0), m_Color(CColor(0,0,0,0)), m_Texture(""), m_HasBorder(false), m_BorderColor(CColor(0,0,0,0)) -{ -} - - -COverlay::COverlay(const CRect& rect,int z,const CColor& color,const char* texturename, - bool hasBorder,const CColor& bordercolor) - : m_Rect(rect), m_Z(z), m_Color(color), m_Texture(texturename), m_HasBorder(hasBorder), m_BorderColor(bordercolor) -{ -} - -COverlay::~COverlay() -{ +/* +COverlay +by Rich Cross +rich@0ad.wildfiregames.com +*/ + +#include "Overlay.h" + +COverlay::COverlay() + : m_Rect(CRect(0,0,0,0)), m_Z(0), m_Color(CColor(0,0,0,0)), m_Texture(""), m_HasBorder(false), m_BorderColor(CColor(0,0,0,0)) +{ +} + + +COverlay::COverlay(const CRect& rect,int z,const CColor& color,const char* texturename, + bool hasBorder,const CColor& bordercolor) + : m_Rect(rect), m_Z(z), m_Color(color), m_Texture(texturename), m_HasBorder(hasBorder), m_BorderColor(bordercolor) +{ +} + +COverlay::~COverlay() +{ } \ No newline at end of file diff --git a/source/ps/Overlay.h b/source/ps/Overlay.h index 4ab593eb50..87492596c5 100755 --- a/source/ps/Overlay.h +++ b/source/ps/Overlay.h @@ -1,142 +1,142 @@ -/* -COverlay -by Rich Cross, rich@0ad.wildfiregames.com - - ---Overview-- - - Class representing 2D screen overlays; includes functionality for overlay - position, color, texture and borders. -*/ - -#ifndef COVERLAY_H -#define COVERLAY_H - -struct CColor -{ - CColor() {} - CColor(float cr,float cg,float cb,float ca) : r(cr), g(cg), b(cb), a(ca) {} - - float r, g, b, a; -}; - -// yuck - MFC already defines a CRect class... -#define CRect PS_CRect - -struct CRect -{ - CRect() {} - CRect(int _l, int _t, int _r, int _b) : - left(_l), - top(_t), - right(_r), - bottom(_b) {} - int bottom, top, left, right; - - bool operator ==(const CRect &rect) const - { - return (bottom==rect.bottom) && - (top==rect.top) && - (left==rect.left) && - (right==rect.right); - } - - bool operator !=(const CRect &rect) const - { - return !(*this==rect); - } -}; - - -//-------------------------------------------------------- -// Includes / Compiler directives -//-------------------------------------------------------- -#include "terrain/Texture.h" - - -//-------------------------------------------------------- -// Macros -//-------------------------------------------------------- - -//-------------------------------------------------------- -// Types -//-------------------------------------------------------- - -//-------------------------------------------------------- -// Error declarations -//-------------------------------------------------------- - -//-------------------------------------------------------- -// Declarations -//-------------------------------------------------------- - -/** - * @author Rich Cross - * - * Overlay class definition. - */ -class COverlay -{ -public: - /** - * Default constructor; creates an overlay that won't actually be renderable - */ - COverlay(); - /** - * Constructor with setup for more common parameters - */ - COverlay(const CRect& rect,int z,const CColor& color,const char* texturename="",bool hasBorder=false, - const CColor& bordercolor=CColor(0,0,0,0)); - /** - * Destructor - */ - ~COverlay(); - - /** - * Get coordinates - */ - const CRect& GetRect() const { return m_Rect; } - - /** - * Get depth - */ - int GetZ() const { return m_Z; } - - /** - * Get texture (not const as Renderer need to modify texture to store handle) - */ - CTexture& GetTexture() { return m_Texture; } - - /** - * Get color - */ - const CColor& GetColor() const { return m_Color; } - - /** - * Get border flag - */ - bool HasBorder() const { return m_HasBorder; } - - /** - * Get border color - */ - const CColor& GetBorderColor() const { return m_BorderColor; } - - -private: - /// screen space coordinates of overlay - CRect m_Rect; - /// depth of overlay, for correctly overlapping overlays; higher z implies in-front-of behaviour - int m_Z; - /// texture to use in rendering overlay; can be a null texture - CTexture m_Texture; - /// overlay color - CColor m_Color; - // flag indicating whether to render overlay using a border - bool m_HasBorder; - /// border color - CColor m_BorderColor; -}; - - +/* +COverlay +by Rich Cross, rich@0ad.wildfiregames.com + + +--Overview-- + + Class representing 2D screen overlays; includes functionality for overlay + position, color, texture and borders. +*/ + +#ifndef COVERLAY_H +#define COVERLAY_H + +struct CColor +{ + CColor() {} + CColor(float cr,float cg,float cb,float ca) : r(cr), g(cg), b(cb), a(ca) {} + + float r, g, b, a; +}; + +// yuck - MFC already defines a CRect class... +#define CRect PS_CRect + +struct CRect +{ + CRect() {} + CRect(int _l, int _t, int _r, int _b) : + left(_l), + top(_t), + right(_r), + bottom(_b) {} + int bottom, top, left, right; + + bool operator ==(const CRect &rect) const + { + return (bottom==rect.bottom) && + (top==rect.top) && + (left==rect.left) && + (right==rect.right); + } + + bool operator !=(const CRect &rect) const + { + return !(*this==rect); + } +}; + + +//-------------------------------------------------------- +// Includes / Compiler directives +//-------------------------------------------------------- +#include "terrain/Texture.h" + + +//-------------------------------------------------------- +// Macros +//-------------------------------------------------------- + +//-------------------------------------------------------- +// Types +//-------------------------------------------------------- + +//-------------------------------------------------------- +// Error declarations +//-------------------------------------------------------- + +//-------------------------------------------------------- +// Declarations +//-------------------------------------------------------- + +/** + * @author Rich Cross + * + * Overlay class definition. + */ +class COverlay +{ +public: + /** + * Default constructor; creates an overlay that won't actually be renderable + */ + COverlay(); + /** + * Constructor with setup for more common parameters + */ + COverlay(const CRect& rect,int z,const CColor& color,const char* texturename="",bool hasBorder=false, + const CColor& bordercolor=CColor(0,0,0,0)); + /** + * Destructor + */ + ~COverlay(); + + /** + * Get coordinates + */ + const CRect& GetRect() const { return m_Rect; } + + /** + * Get depth + */ + int GetZ() const { return m_Z; } + + /** + * Get texture (not const as Renderer need to modify texture to store handle) + */ + CTexture& GetTexture() { return m_Texture; } + + /** + * Get color + */ + const CColor& GetColor() const { return m_Color; } + + /** + * Get border flag + */ + bool HasBorder() const { return m_HasBorder; } + + /** + * Get border color + */ + const CColor& GetBorderColor() const { return m_BorderColor; } + + +private: + /// screen space coordinates of overlay + CRect m_Rect; + /// depth of overlay, for correctly overlapping overlays; higher z implies in-front-of behaviour + int m_Z; + /// texture to use in rendering overlay; can be a null texture + CTexture m_Texture; + /// overlay color + CColor m_Color; + // flag indicating whether to render overlay using a border + bool m_HasBorder; + /// border color + CColor m_BorderColor; +}; + + #endif \ No newline at end of file diff --git a/source/ps/OverlayText.cpp b/source/ps/OverlayText.cpp index 4a3824279f..c8637dbe7c 100755 --- a/source/ps/OverlayText.cpp +++ b/source/ps/OverlayText.cpp @@ -1,32 +1,32 @@ -/* -COverlayText -by Rich Cross -rich@0ad.wildfiregames.com -*/ - -#include "OverlayText.h" -#include "NPFont.h" -#include "NPFontManager.h" - -COverlayText::COverlayText() - : m_X(0), m_Y(0), m_Z(0), m_Color(CColor(0,0,0,0)), m_Font(0), m_String("") -{ -} - - -COverlayText::COverlayText(float x,float y,int z,const char* fontname,const char* string,const CColor& color) - : m_X(x), m_Y(y), m_Z(z), m_String(string), m_Color(color) -{ - m_Font=NPFontManager::instance().add(fontname); -} - -COverlayText::~COverlayText() -{ -} - -bool COverlayText::GetOutputStringSize(int& sx,int& sy) -{ - if (!m_Font) return false; - m_Font->GetOutputStringSize((const char*) m_String,sx,sy); - return true; -} +/* +COverlayText +by Rich Cross +rich@0ad.wildfiregames.com +*/ + +#include "OverlayText.h" +#include "NPFont.h" +#include "NPFontManager.h" + +COverlayText::COverlayText() + : m_X(0), m_Y(0), m_Z(0), m_Color(CColor(0,0,0,0)), m_Font(0), m_String("") +{ +} + + +COverlayText::COverlayText(float x,float y,int z,const char* fontname,const char* string,const CColor& color) + : m_X(x), m_Y(y), m_Z(z), m_String(string), m_Color(color) +{ + m_Font=NPFontManager::instance().add(fontname); +} + +COverlayText::~COverlayText() +{ +} + +bool COverlayText::GetOutputStringSize(int& sx,int& sy) +{ + if (!m_Font) return false; + m_Font->GetOutputStringSize((const char*) m_String,sx,sy); + return true; +} diff --git a/source/ps/OverlayText.h b/source/ps/OverlayText.h index 61afbdba41..4b09bc2417 100755 --- a/source/ps/OverlayText.h +++ b/source/ps/OverlayText.h @@ -1,108 +1,108 @@ -/* -COverlayText -by Rich Cross, rich@0ad.wildfiregames.com - - ---Overview-- - - Class representing 2D screen text overlay -*/ - -#ifndef COVERLAYTEXT_H -#define COVERLAYTEXT_H - - -//-------------------------------------------------------- -// Includes / Compiler directives -//-------------------------------------------------------- -#include "terrain/Texture.h" -#include "Overlay.h" // just for CColor at the mo - - -//-------------------------------------------------------- -// Macros -//-------------------------------------------------------- - -//-------------------------------------------------------- -// Types -//-------------------------------------------------------- - -//-------------------------------------------------------- -// Error declarations -//-------------------------------------------------------- - -//-------------------------------------------------------- -// Declarations -//-------------------------------------------------------- -class NPFont; - -/** - * @author Rich Cross - * - * OverlayText class definition. - */ -class COverlayText -{ -public: - /** - * Default constructor; creates an overlay text object that won't actually be renderable - */ - COverlayText(); - /** - * Constructor with setup for more common parameters - */ - COverlayText(float x,float y,int z,const char* fontname,const char* string,const CColor& color); - /** - * Destructor - */ - ~COverlayText(); - - /** - * Get position - */ - void GetPosition(float& x,float& y) { - x=m_X; - y=m_Y; - } - - /** - * Get depth - */ - int GetZ() const { return m_Z; } - - /** - * Get font (not const as Renderer need to modify texture to store handle) - */ - NPFont* GetFont() { return m_Font; } - - /** - * Get string to render - */ - const CStr& GetString() const { return m_String; } - - /** - * Get color - */ - const CColor& GetColor() const { return m_Color; } - - /** - * Get size of this string when rendered; return false if font is invalid and string size cannot - * actually by determined, or true on success - */ - bool GetOutputStringSize(int& sx,int& sy); - -private: - /// coordinates to start rendering string - float m_X,m_Y; - /// depth of overlay text, for correctly overlapping overlays; higher z implies in-front-of behaviour - int m_Z; - /// text color - CColor m_Color; - /// pointer to the font to use in rendering out text; not owned by the overlay, never attempt to delete - NPFont* m_Font; - /// actual text string - CStr m_String; -}; - - -#endif +/* +COverlayText +by Rich Cross, rich@0ad.wildfiregames.com + + +--Overview-- + + Class representing 2D screen text overlay +*/ + +#ifndef COVERLAYTEXT_H +#define COVERLAYTEXT_H + + +//-------------------------------------------------------- +// Includes / Compiler directives +//-------------------------------------------------------- +#include "terrain/Texture.h" +#include "Overlay.h" // just for CColor at the mo + + +//-------------------------------------------------------- +// Macros +//-------------------------------------------------------- + +//-------------------------------------------------------- +// Types +//-------------------------------------------------------- + +//-------------------------------------------------------- +// Error declarations +//-------------------------------------------------------- + +//-------------------------------------------------------- +// Declarations +//-------------------------------------------------------- +class NPFont; + +/** + * @author Rich Cross + * + * OverlayText class definition. + */ +class COverlayText +{ +public: + /** + * Default constructor; creates an overlay text object that won't actually be renderable + */ + COverlayText(); + /** + * Constructor with setup for more common parameters + */ + COverlayText(float x,float y,int z,const char* fontname,const char* string,const CColor& color); + /** + * Destructor + */ + ~COverlayText(); + + /** + * Get position + */ + void GetPosition(float& x,float& y) { + x=m_X; + y=m_Y; + } + + /** + * Get depth + */ + int GetZ() const { return m_Z; } + + /** + * Get font (not const as Renderer need to modify texture to store handle) + */ + NPFont* GetFont() { return m_Font; } + + /** + * Get string to render + */ + const CStr& GetString() const { return m_String; } + + /** + * Get color + */ + const CColor& GetColor() const { return m_Color; } + + /** + * Get size of this string when rendered; return false if font is invalid and string size cannot + * actually by determined, or true on success + */ + bool GetOutputStringSize(int& sx,int& sy); + +private: + /// coordinates to start rendering string + float m_X,m_Y; + /// depth of overlay text, for correctly overlapping overlays; higher z implies in-front-of behaviour + int m_Z; + /// text color + CColor m_Color; + /// pointer to the font to use in rendering out text; not owned by the overlay, never attempt to delete + NPFont* m_Font; + /// actual text string + CStr m_String; +}; + + +#endif diff --git a/source/simulation/BaseEntity.cpp b/source/simulation/BaseEntity.cpp new file mode 100755 index 0000000000..3cfbdd66ac --- /dev/null +++ b/source/simulation/BaseEntity.cpp @@ -0,0 +1,91 @@ +#include "BaseEntity.h" +#include "ObjectManager.h" +#include "CStr.h" + +// xerces XML stuff +#include +#include +#include +#include +#include + +// Gee's custom error handler +#include + +// automatically use namespace .. +XERCES_CPP_NAMESPACE_USE + +bool CBaseEntity::loadXML( CStr filename ) +{ + // I can only assume Rich knows what this does ;) + + bool parseOK = false; + + // Initialize XML library + XMLPlatformUtils::Initialize(); + { + // Create parser instance + XercesDOMParser *parser = new XercesDOMParser(); + + // Setup parser + parser->setValidationScheme(XercesDOMParser::Val_Auto); + parser->setDoNamespaces(false); + parser->setDoSchema(false); + parser->setCreateEntityReferenceNodes(false); + + // Set customized error handler + CXercesErrorHandler *errorHandler = new CXercesErrorHandler(); + parser->setErrorHandler(errorHandler); + + // Get main node + LocalFileInputSource source( XMLString::transcode(filename) ); + + // Parse file + parser->parse(source); + + // Check how many errors + parseOK = parser->getErrorCount() == 0; + + if (parseOK) { + // parsed successfully - grab our data + DOMDocument *doc = parser->getDocument(); + DOMElement *element = doc->getDocumentElement(); + + // root_name should be Object + CStr root_name = XMLString::transcode( element->getNodeName() ); + + // should have at least 3 children - Name, ModelName and TextureName + DOMNodeList *children = element->getChildNodes(); + int numChildren=children->getLength(); + for (int i=0; iitem(i); + + // A child element + if (child->getNodeType() == DOMNode::ELEMENT_NODE) + { + // First get element and not node + DOMElement *child_element = (DOMElement*)child; + + CStr element_name = XMLString::transcode( child_element->getNodeName() ); + DOMNode *value_node= child_element->getChildNodes()->item(0); + CStr element_value=value_node ? XMLString::transcode(value_node->getNodeValue()) : ""; + + if (element_name==CStr("Name")) { + m_name = element_value; + } else if (element_name==CStr("Actor")) { + m_actorObject = g_ObjMan.FindObject( element_value ); + } else if (element_name==CStr("Speed")) { + m_speed = element_value.ToFloat(); + } + } + } + + } + + delete parser; + } + XMLPlatformUtils::Terminate(); + + return parseOK; +} diff --git a/source/simulation/BaseEntity.h b/source/simulation/BaseEntity.h new file mode 100755 index 0000000000..d0be8b63ec --- /dev/null +++ b/source/simulation/BaseEntity.h @@ -0,0 +1,27 @@ +#ifndef BASE_ENTITY_INCLUDED +#define BASE_ENTITY_INCLUDED + +#include "CStr.h" +#include "ObjectEntry.h" + +#include "EntityProperties.h" + +class CBaseEntity +{ +public: + // Load from XML + bool loadXML( CStr filename ); + + // Base stats + + CObjectEntry* m_actorObject; + + CStr m_name; + float m_speed; + + // Extended properties table + + std::hash_map m_properties; +}; + +#endif \ No newline at end of file diff --git a/source/simulation/BaseEntityCollection.cpp b/source/simulation/BaseEntityCollection.cpp new file mode 100755 index 0000000000..391513c2c8 --- /dev/null +++ b/source/simulation/BaseEntityCollection.cpp @@ -0,0 +1,67 @@ +// Last modified: May 15 2004, Mark Thompson (mark@wildfiregames.com) + +#include "BaseEntityCollection.h" +#include "ObjectManager.h" +#include "Model.h" +#include "io.h" + +void CBaseEntityCollection::loadTemplates() +{ + _finddata_t file; + intptr_t handle; + + CStr pathname = "mods/official/entities/templates/"; + CStr filespec = pathname + "*.xml"; + + handle = _findfirst( filespec, &file ); + if( handle != -1 ) + { + do + { + CBaseEntity newTemplate; + if( newTemplate.loadXML( pathname + file.name ) ) + addTemplate( newTemplate ); + } + while( !_findnext( handle, &file ) ); + + _findclose(handle); + } + + // He's so annoyingly slow... + CBaseEntity* dude = getTemplate( "Prometheus Dude" ); + dude->m_actorObject->m_WalkAnim->m_FrameTime /= 10.0f; + dude->m_speed *= 10.0f; + +/* + + // Nasty evil wicked hardcoding. + CBaseEntity dude; + dude.m_name = CStr( "Prometheus Dude" ); + dude.m_actorObject = g_ObjMan.FindObject( "The Dude" ); + dude.m_actorObject->m_Model->GetAnimation()->m_FrameTime /= 3.0f; + dude.speed = 0.3f; + + addTemplate( dude ); +*/ +} + +void CBaseEntityCollection::addTemplate( CBaseEntity& temp ) +{ + m_templates.push_back( temp ); +} + +CBaseEntity* CBaseEntityCollection::getTemplate( CStr name ) +{ + for( int t = 0; t < m_templates.size(); t++ ) + if( m_templates[t].m_name == name ) return( &( m_templates[t] ) ); + + return( NULL ); +} + +CBaseEntity* CBaseEntityCollection::getTemplateByActor( CObjectEntry* actor ) +{ + for( int t = 0; t < m_templates.size(); t++ ) + if( m_templates[t].m_actorObject == actor ) return( &( m_templates[t] ) ); + + return( NULL ); +} diff --git a/source/simulation/BaseEntityCollection.h b/source/simulation/BaseEntityCollection.h new file mode 100755 index 0000000000..daa5b967eb --- /dev/null +++ b/source/simulation/BaseEntityCollection.h @@ -0,0 +1,24 @@ +// Last modified: May 15 2004, Mark Thompson (mark@wildfiregames.com) + +#ifndef BASEENT_COLLECTION_INCLUDED +#define BASEENT_COLLECTION_INCLUDED + +#include +#include "CStr.h" +#include "Singleton.h" +#include "ObjectEntry.h" +#include "BaseEntity.h" + +#define g_EntityTemplateCollection CBaseEntityCollection::GetSingleton() + +class CBaseEntityCollection : public Singleton +{ + std::vector m_templates; +public: + CBaseEntity* getTemplate( CStr entityType ); + void loadTemplates(); + void addTemplate( CBaseEntity& temp ); + CBaseEntity* getTemplateByActor( CObjectEntry* actor ); +}; + +#endif \ No newline at end of file diff --git a/source/simulation/Entity.cpp b/source/simulation/Entity.cpp new file mode 100755 index 0000000000..d9076d72cf --- /dev/null +++ b/source/simulation/Entity.cpp @@ -0,0 +1,242 @@ +// Last modified: May 15 2004, Mark Thompson (mark@wildfiregames.com) + +#include "Entity.h" +#include "Model.h" +#include "Terrain.h" +#include "EntityManager.h" +#include "BaseEntityCollection.h" + + +CEntity::CEntity( CBaseEntity* base, CVector3D position, float orientation ) +{ + // Set our parent unit and build us an actor. + + m_base = base; + m_actor = new CUnit; + + m_actor->m_Object = m_base->m_actorObject; + m_actor->m_Model = ( m_actor->m_Object->m_Model ) ? m_actor->m_Object->m_Model->Clone() : NULL; + + // Register the actor with the renderer. + + g_UnitMan.AddUnit( m_actor ); + + // Set up our instance data + + m_speed = m_base->m_speed; + m_position = position; + m_orientation = orientation; + + snapToGround(); + updateActorTransforms(); + + // Register the addresses of our native properties with the properties table + m_properties["speed"] = &m_speed; + m_properties["orientation"] = &m_orientation; + m_properties["position"] = &m_position; +} + +bool isWaypoint( CEntity* e ) +{ + return( e->m_base->m_name == CStr( "Waypoint" ) ); +} + +void CEntity::updateActorTransforms() +{ + CMatrix3D m; + + m.SetYRotation( m_orientation ); + + m.Translate( m_position ); + + m_actor->m_Model->SetTransform( m ); +} + +float CEntity::getExactGroundLevel( float x, float y ) +{ + // TODO MT: If OK with Rich, move to terrain core. Once this works, that is. + + x /= 4.0f; + y /= 4.0f; + + int xi = floor( x ); + int yi = floor( y ); + float xf = x - (float)xi; + float yf = y - (float)yi; + + u16* heightmap = g_Terrain.GetHeightMap(); + u16 mapsize = g_Terrain.GetVerticesPerSide(); + + float h00 = heightmap[yi*mapsize + xi]; + float h01 = heightmap[yi*mapsize + xi + mapsize]; + float h10 = heightmap[yi*mapsize + xi + 1]; + float h11 = heightmap[yi*mapsize + xi + mapsize + 1]; + + /* + if( xf < ( 1.0f - yf ) ) + { + return( HEIGHT_SCALE * ( ( 1 - xf - yf ) * h00 + xf * h10 + yf * h01 ) ); + } + else + return( HEIGHT_SCALE * ( ( xf + yf - 1 ) * h11 + ( 1 - xf ) * h01 + ( 1 - yf ) * h10 ) ); + */ + + /* + if( xf > yf ) + { + return( HEIGHT_SCALE * ( ( 1 - xf ) * h00 + ( xf - yf ) * h10 + yf * h11 ) ); + } + else + return( HEIGHT_SCALE * ( ( 1 - yf ) * h00 + ( yf - xf ) * h01 + xf * h11 ) ); + */ + + return( HEIGHT_SCALE * ( ( 1 - yf ) * ( ( 1 - xf ) * h00 + xf * h10 ) + yf * ( ( 1 - xf ) * h01 + xf * h11 ) ) ); + +} + +void CEntity::snapToGround() +{ + m_position.Y = getExactGroundLevel( m_position.X, m_position.Z ); +} + +void CEntity::update( float timestep ) +{ + while( !m_orderQueue.empty() ) + { + CEntityOrder* current = &m_orderQueue.front(); + + switch( current->m_type ) + { + case CEntityOrder::ORDER_GOTO_NOPATHING: + { + float deltax = (float)current->m_data[0].location.x - m_position.X; + float deltay = (float)current->m_data[0].location.y - m_position.Z; + + m_targetorientation = atan2( -deltax, -deltay ); + float deltatheta = m_targetorientation - m_orientation; + if( deltatheta > PI ) + deltatheta -= 2 * PI; + if( deltatheta < -PI ) + deltatheta += 2 * PI; + + /* + if( deltatheta > 1.0f * timestep ) + deltatheta = 1.0f * timestep; + if( deltatheta < -1.0f * timestep ) + deltatheta = -1.0f * timestep; + */ + + m_orientation += deltatheta; + + float len = sqrt( deltax * deltax + deltay * deltay ); + float scale = timestep * m_speed; + if( scale > len ) + scale = len; + + deltax = -sinf( m_orientation ) * scale; deltay = -cosf( m_orientation ) * scale; + m_position.X += deltax; + m_position.Z += deltay; + + snapToGround(); + updateActorTransforms(); + if( len < 0.1f ) + m_orderQueue.pop_front(); + return; + break; + } + case CEntityOrder::ORDER_GOTO: + { + CEntityOrder pathfind_solution; + pathfind_solution.m_type = CEntityOrder::ORDER_GOTO_NOPATHING; + pathfind_solution.m_data[0] = current->m_data[0]; + m_orderQueue.pop_front(); + m_orderQueue.push_front( pathfind_solution ); + if( m_actor->m_Model->GetAnimation() != m_actor->m_Object->m_WalkAnim ) + m_actor->m_Model->SetAnimation( m_actor->m_Object->m_WalkAnim ); + break; + } + case CEntityOrder::ORDER_PATROL: + { + CEntityOrder this_segment; + CEntityOrder repeat_patrol; + this_segment.m_type = CEntityOrder::ORDER_GOTO; + this_segment.m_data[0] = current->m_data[0]; + repeat_patrol.m_type = CEntityOrder::ORDER_PATROL; + repeat_patrol.m_data[0] = current->m_data[0]; + m_orderQueue.pop_front(); + m_orderQueue.push_front( this_segment ); + m_orderQueue.push_back( repeat_patrol ); + break; + } + default: + assert( 0 && "Invalid entity order" ); + } + } + if( m_actor->m_Model->GetAnimation() != m_actor->m_Object->m_IdleAnim ) + m_actor->m_Model->SetAnimation( m_actor->m_Object->m_IdleAnim ); +} + +void CEntity::dispatch( CMessage* msg ) +{ + switch( msg->type ) + { + case CMessage::EMSG_TICK: + break; + case CMessage::EMSG_INIT: + if( m_base->m_name == CStr( "Prometheus Dude" ) ) + { + std::vector* waypoints = g_EntityManager.matches( isWaypoint ); + while( !waypoints->empty() ) + { + CEntityOrder patrol; + int id = rand() % waypoints->size(); + std::vector::iterator it = waypoints->begin(); + it += id; + HEntity waypoint = *it; + patrol.m_type = CEntityOrder::ORDER_PATROL; + patrol.m_data[0].location.x = waypoint->m_position.X; + patrol.m_data[0].location.y = waypoint->m_position.Z; + pushOrder( patrol ); + waypoints->erase( it ); + } + } + break; + } +} + +void CEntity::pushOrder( CEntityOrder& order ) +{ + m_orderQueue.push_back( order ); +} + +void PASAPScenario() +{ + // Entity demo. I don't know where this information is going to come from for pre-PASAP. + // So, it's hardcoded here. *shrug* + + /* + float waypoints[4][2] = { { 12.0f, 64.0f }, + { 28.0f, 64.0f }, + { 56.0f, 52.0f }, + { 24.0f, 28.0f } }; + */ + + /* + + for( int i = 0; i < 4; i++ ) + { + HEntity bob = g_EntityManager.create( "Prometheus Dude", CVector3D( waypoints[i][0], 0.0f, waypoints[i][1] ), 0.0f ); + + for( int t = 0; t < 4; t++ ) + { + CEntityOrder march_of_bob; + march_of_bob.m_type = CEntityOrder::ORDER_PATROL ; + march_of_bob.m_data[0].location.x = waypoints[(i+t+1)%4][0]; + march_of_bob.m_data[0].location.y = waypoints[(i+t+1)%4][1]; + + bob->pushOrder( march_of_bob ); + } + } + + */ +} \ No newline at end of file diff --git a/source/simulation/Entity.h b/source/simulation/Entity.h new file mode 100755 index 0000000000..045442c9de --- /dev/null +++ b/source/simulation/Entity.h @@ -0,0 +1,54 @@ +// Last modified: May 15 2004, Mark Thompson (mark@wildfiregames.com) + +#ifndef ENTITY_INCLUDED +#define ENTITY_INCLUDED + +#include +#include "EntityProperties.h" + +#include "BaseEntity.h" +#include "Vector3D.h" +#include "Unit.h" +#include "UnitManager.h" +#include "EntityOrders.h" +#include "EntityHandles.h" +#include "EntityMessage.h" + +class CEntityManager; + +class CEntity +{ + friend CEntityManager; +private: + // Intrinsic properties +public: + CStr m_name; + float m_speed; + CVector3D m_position; + float m_targetorientation; + float m_orientation; + CBaseEntity* m_base; + CUnit* m_actor; + + std::deque m_orderQueue; + + // Extended properties table + + std::hash_map m_properties; + + CEntity( CBaseEntity* base, CVector3D position, float orientation ); +public: + + // Handle-to-self. + HEntity me; + void dispatch( CMessage* msg ); + void update( float timestep ); + void updateActorTransforms(); + float getExactGroundLevel( float x, float y ); + void snapToGround(); + void pushOrder( CEntityOrder& order ); +}; + +extern void PASAPScenario(); + +#endif \ No newline at end of file diff --git a/source/simulation/EntityHandles.cpp b/source/simulation/EntityHandles.cpp new file mode 100755 index 0000000000..54c4075cae --- /dev/null +++ b/source/simulation/EntityHandles.cpp @@ -0,0 +1,71 @@ +#include "EntityHandles.h" +#include "EntityManager.h" + +CHandle::CHandle() +{ + m_entity = NULL; + m_refcount = 0; +} + +HEntity::HEntity( u16 index ) +{ + m_handle = index; + addRef(); +} + +HEntity::HEntity( const HEntity& copy ) +{ + m_handle = copy.m_handle; + addRef(); +} + +HEntity::HEntity() +{ + m_handle = INVALID_HANDLE; +} + +HEntity::~HEntity() +{ + if( CEntityManager::extant() ) + decRef(); +} + +void HEntity::operator=( const HEntity& copy ) +{ + decRef(); + m_handle = copy.m_handle; + addRef(); +} + +void HEntity::addRef() +{ + if( m_handle != INVALID_HANDLE ) + g_EntityManager.m_entities[m_handle].m_refcount++; +} + +void HEntity::decRef() +{ + if( m_handle != INVALID_HANDLE ) + { + assert( g_EntityManager.m_entities[m_handle].m_refcount != 0 ); + if( --g_EntityManager.m_entities[m_handle].m_refcount == 0 ) + { + delete( g_EntityManager.m_entities[m_handle].m_entity ); + } + } +} + +CEntity* HEntity::operator->() +{ + assert( m_handle != INVALID_HANDLE ); + assert( g_EntityManager.m_entities[m_handle].m_refcount != 0 ); + return( g_EntityManager.m_entities[m_handle].m_entity ); +} + +CEntity& HEntity::operator*() +{ + assert( m_handle != INVALID_HANDLE ); + assert( g_EntityManager.m_entities[m_handle].m_refcount != 0 ); + return( *g_EntityManager.m_entities[m_handle].m_entity ); +} + diff --git a/source/simulation/EntityHandles.h b/source/simulation/EntityHandles.h new file mode 100755 index 0000000000..b201471b20 --- /dev/null +++ b/source/simulation/EntityHandles.h @@ -0,0 +1,35 @@ +#ifndef ENTITY_HANDLE_INCLUDED +#define ENTITY_HANDLE_INCLUDED + +#include "types.h" + +#define INVALID_HANDLE 65535 + +class CEntity; +class CEntityManager; + +class CHandle +{ +public: + CEntity* m_entity; + u16 m_refcount; + CHandle(); +}; + +class HEntity +{ + friend CEntityManager; + u16 m_handle; + void addRef(); + void decRef(); + HEntity( u16 index ); +public: + CEntity& operator*(); + CEntity* operator->(); + HEntity(); + HEntity( const HEntity& copy ); + void operator=( const HEntity& copy ); + ~HEntity(); +}; + +#endif \ No newline at end of file diff --git a/source/simulation/EntityManager.cpp b/source/simulation/EntityManager.cpp new file mode 100755 index 0000000000..698c8a04c5 --- /dev/null +++ b/source/simulation/EntityManager.cpp @@ -0,0 +1,56 @@ +#include "EntityManager.h" +#include "BaseEntityCollection.h" + + +CEntityManager::CEntityManager() +{ + m_nextalloc = 0; + m_extant = true; +} + +CEntityManager::~CEntityManager() +{ + m_extant = false; +} + +HEntity CEntityManager::create( CBaseEntity* base, CVector3D position, float orientation ) +{ + assert( base ); + while( m_entities[m_nextalloc].m_refcount ) + m_nextalloc++; + m_entities[m_nextalloc].m_entity = new CEntity( base, position, orientation ); + m_entities[m_nextalloc].m_entity->me = HEntity( m_nextalloc ); + return( HEntity( m_nextalloc++ ) ); +} + +HEntity CEntityManager::create( CStr templatename, CVector3D position, float orientation ) +{ + CBaseEntity* templateobj = g_EntityTemplateCollection.getTemplate( templatename ); + return( create( templateobj, position, orientation ) ); +} + +std::vector* CEntityManager::matches( EntityPredicate predicate ) +{ + std::vector* matchlist = new std::vector; + for( int i = 0; i < MAX_HANDLES; i++ ) + if( m_entities[i].m_refcount ) + if( predicate( m_entities[i].m_entity ) ) + matchlist->push_back( HEntity( i ) ); + return( matchlist ); +} + +void CEntityManager::dispatchAll( CMessage* msg ) +{ + for( int i = 0; i < MAX_HANDLES; i++ ) + if( m_entities[i].m_refcount ) + m_entities[i].m_entity->dispatch( msg ); +} + +void CEntityManager::updateAll( float timestep ) +{ + for( int i = 0; i < MAX_HANDLES; i++ ) + if( m_entities[i].m_refcount ) + m_entities[i].m_entity->update( timestep ); +} + +bool CEntityManager::m_extant = false; \ No newline at end of file diff --git a/source/simulation/EntityManager.h b/source/simulation/EntityManager.h new file mode 100755 index 0000000000..5695f193e2 --- /dev/null +++ b/source/simulation/EntityManager.h @@ -0,0 +1,35 @@ +#ifndef ENTITY_MANAGER_INCLUDED +#define ENTITY_MANAGER_INCLUDED + +#include "Singleton.h" +#include "Entity.h" +#include "EntityHandles.h" +#include "EntityMessage.h" + +#define MAX_HANDLES 4096 + +#define g_EntityManager CEntityManager::GetSingleton() + +class CEntityManager : public Singleton +{ +friend HEntity; +friend CHandle; + CHandle m_entities[MAX_HANDLES]; + int m_nextalloc; + static bool m_extant; +public: + typedef bool (*EntityPredicate)( CEntity* target ); + CEntityManager(); + ~CEntityManager(); + HEntity create( CBaseEntity* base, CVector3D position, float orientation ); + HEntity create( CStr templatename, CVector3D position, float orientation ); + void updateAll( float timestep ); + void dispatchAll( CMessage* msg ); + std::vector* matches( EntityPredicate predicate ); + static inline bool extant() // True if the singleton is actively maintaining handles. When false, system is shutting down, handles are quietly dumped. + { + return( m_extant ); + } +}; + +#endif \ No newline at end of file diff --git a/source/simulation/EntityMessage.h b/source/simulation/EntityMessage.h new file mode 100755 index 0000000000..c2369998bd --- /dev/null +++ b/source/simulation/EntityMessage.h @@ -0,0 +1,19 @@ +// Message structure + +#ifndef MESSAGING_INCLUDED +#define MESSAGING_INCLUDED + +struct CMessage +{ + enum EMessageType + { + EMSG_TICK, + EMSG_INIT + } type; + CMessage( EMessageType _type ) + { + type = _type; + } +}; + +#endif \ No newline at end of file diff --git a/source/simulation/EntityOrders.h b/source/simulation/EntityOrders.h new file mode 100755 index 0000000000..e65759f681 --- /dev/null +++ b/source/simulation/EntityOrders.h @@ -0,0 +1,36 @@ +// Last modified: May 15 2004, Mark Thompson (mark@wildfiregames.com) + +#ifndef ENTITY_ORDER_INCLUDED +#define ENTITY_ORDER_INCLUDED + +#define ORDER_MAX_DATA 1 + +#include "EntityHandles.h" + +struct SOrderData +{ + union + { + struct + { + float x; + float y; + } location; + u64 data; // miscellaneous + }; + HEntity entity; +}; + +class CEntityOrder +{ +public: + enum + { + ORDER_GOTO_NOPATHING, + ORDER_GOTO, + ORDER_PATROL + } m_type; + SOrderData m_data[ORDER_MAX_DATA]; +}; + +#endif \ No newline at end of file diff --git a/source/simulation/EntityProperties.cpp b/source/simulation/EntityProperties.cpp new file mode 100755 index 0000000000..e2da5b0988 --- /dev/null +++ b/source/simulation/EntityProperties.cpp @@ -0,0 +1,160 @@ +#include "EntityProperties.h" + +CGenericProperty::CGenericProperty() +{ + m_type = PROP_INTEGER; + m_integer = 0; +} + +CGenericProperty::CGenericProperty( i32 value ) +{ + m_type = PROP_INTEGER; + m_integer = value; +} + +CGenericProperty::CGenericProperty( float value ) +{ + m_type = PROP_FLOAT; + m_float = value; +} + +CGenericProperty::CGenericProperty( CStr& value ) +{ + m_type = PROP_STRING; + m_string = new CStr( value ); +} + +CGenericProperty::CGenericProperty( CVector3D& value ) +{ + m_type = PROP_VECTOR; + m_vector = new CVector3D( value ); +} + +CGenericProperty::CGenericProperty( void* value ) +{ + m_type = PROP_PTR; + m_ptr = value; +} + +CGenericProperty::CGenericProperty( i32* value ) +{ + m_type = PROP_INTEGER_INTRINSIC; + m_integerptr = value; +} + +CGenericProperty::CGenericProperty( float* value ) +{ + m_type = PROP_FLOAT_INTRINSIC; + m_floatptr = value; +} + +CGenericProperty::CGenericProperty( CStr* value ) +{ + m_type = PROP_STRING_INTRINSIC; + m_string = value; +} + +CGenericProperty::CGenericProperty( CVector3D* value ) +{ + m_type = PROP_VECTOR_INTRINSIC; + m_vector = value; +} + +CGenericProperty::~CGenericProperty() +{ + switch( m_type ) + { + case PROP_STRING: + delete( m_string ); break; + case PROP_VECTOR: + delete( m_vector ); break; + default: + break; + } +} + +CGenericProperty::operator CStr() +{ + char working[64]; + switch( m_type ) + { + case PROP_STRING: + case PROP_STRING_INTRINSIC: + return( *m_string ); + case PROP_VECTOR: + case PROP_VECTOR_INTRINSIC: + snprintf( working, 63, "{ %f, %f, %f }", m_vector->X, m_vector->Y, m_vector->Z ); + working[63] = 0; + return( CStr( working ) ); + case PROP_INTEGER: + return( CStr( m_integer ) ); + case PROP_INTEGER_INTRINSIC: + return( CStr( *m_integerptr ) ); + case PROP_FLOAT: + return( CStr( m_float ) ); + case PROP_FLOAT_INTRINSIC: + return( CStr( *m_floatptr ) ); + default: + return( CStr() ); + } +} + +CGenericProperty::operator CVector3D() +{ + switch( m_type ) + { + case PROP_VECTOR: + return( *m_vector ); + default: + return( CVector3D() ); + } +} + +CGenericProperty::operator i32() +{ + switch( m_type ) + { + case PROP_INTEGER: + return( m_integer ); + case PROP_INTEGER_INTRINSIC: + return( *m_integerptr ); + case PROP_FLOAT: + return( (i32)m_float ); + case PROP_FLOAT_INTRINSIC: + return( (i32)*m_floatptr ); + case PROP_STRING: + return( m_string->ToInt() ); + default: + return( 0 ); + } +} + +CGenericProperty::operator float() +{ + switch( m_type ) + { + case PROP_INTEGER: + return( (float)m_integer ); + case PROP_INTEGER_INTRINSIC: + return( (float)*m_integerptr ); + case PROP_FLOAT: + return( m_float ); + case PROP_FLOAT_INTRINSIC: + return( *m_floatptr ); + case PROP_STRING: + return( m_string->ToFloat() ); + default: + return( 0.0f ); + } +} + +CGenericProperty::operator void*() +{ + switch( m_type ) + { + case PROP_PTR: + return( m_ptr ); + default: + return( NULL ); + } +} diff --git a/source/simulation/EntityProperties.h b/source/simulation/EntityProperties.h new file mode 100755 index 0000000000..47c42a6f25 --- /dev/null +++ b/source/simulation/EntityProperties.h @@ -0,0 +1,65 @@ +// Inefficiency warning. +// Will move frequently accessed properties (position, name, etc.) to native C++ primitives. +// Just playing around with this idea, will probably keep it for at least some of the more exotic and/or user-defined properties. + +// TODO: Fix the silent failures of the conversion functions: need to work out what to do in these cases. + +// Mark Thompson mot20@cam.ac.uk / mark@wildfiregames.com + +#ifndef ENTITY_PROPERTIES_INCLUDED +#define ENTITY_PROPERTIES_INCLUDED + +#include "CStr.h" +#include "Vector3D.h" + +#include + +class CGenericProperty +{ +public: + enum EPropTypes + { + PROP_INTRINSIC = 256, + PROP_INTEGER = 0, + PROP_FLOAT, + PROP_STRING, + PROP_VECTOR, + PROP_PTR, + PROP_INTEGER_INTRINSIC = PROP_INTEGER | PROP_INTRINSIC, + PROP_FLOAT_INTRINSIC = PROP_FLOAT | PROP_INTRINSIC, + PROP_STRING_INTRINSIC = PROP_STRING | PROP_INTRINSIC, + PROP_VECTOR_INTRINSIC = PROP_VECTOR | PROP_INTRINSIC + }; +private: + EPropTypes m_type; + union + { + i32 m_integer; + i32* m_integerptr; + float m_float; + float* m_floatptr; + CStr* m_string; + CVector3D* m_vector; + void* m_ptr; + }; +public: + CGenericProperty(); // Create an integer property containing 0. + CGenericProperty( i32 value ); // Create an integer property with a given value. + CGenericProperty( i32* value ); // Create an integer property that points to the given variable. + CGenericProperty( float value ); // Create a floating-point property with a given value. + CGenericProperty( float* value ); // Create a floating-point property that points to the given variable. + CGenericProperty( CStr& value ); // Create a string object property that's initialized to a copy of the given string. + CGenericProperty( CStr* value ); // Create a string object property that points to the given variable. + CGenericProperty( CVector3D& value ); // Create a vector object property that's initialized to a copy of the given vector. + CGenericProperty( CVector3D* value ); // Create a vector object property that points to the given variable. + CGenericProperty( void* value ); // Create a general property that points to the given value. + ~CGenericProperty(); + operator i32(); // Convert to an integer if possible (integer, float, some strings), otherwise returns 0. + operator float(); // Convert to a float if possible (integer, float, some strings), otherwise returns 0.0f. + operator CStr(); // Convert to a string if possible (all except generic pointer), otherwise returns CStr(). + operator CVector3D(); // If this property is a vector, returns that vector, otherwise returns CVector3D(). + operator void*(); // If this property is a generic pointer, returns that pointer, otherwise returns NULL. +}; + +#endif + diff --git a/source/terrain/AlphaMapCalculator.cpp b/source/terrain/AlphaMapCalculator.cpp index ffa351b535..071b2d4935 100755 --- a/source/terrain/AlphaMapCalculator.cpp +++ b/source/terrain/AlphaMapCalculator.cpp @@ -1,303 +1,303 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Name: AlphaMapCalculator.cpp -// Author: Rich Cross -// Contact: rich@wildfiregames.com -// -/////////////////////////////////////////////////////////////////////////////// - -#include "AlphaMapCalculator.h" -#include -#include - -/////////////////////////////////////////////////////////////////////////////// -// CAlphaMapCalculator: functionality for calculating which alpha blend map -// fits a given shape -namespace CAlphaMapCalculator { - -/////////////////////////////////////////////////////////////////////////////// -// Blend4: structure mapping a blend shape for N,E,S,W to a particular map -struct Blend4 { - Blend4(BlendShape4 shape,int alphamap) : m_Shape(shape), m_AlphaMap(alphamap) {} - - BlendShape4 m_Shape; - int m_AlphaMap; -}; - -/////////////////////////////////////////////////////////////////////////////// -// Blend8: structure mapping a blend shape for N,NE,E,SE,S,SW,W,NW to a -// particular map -struct Blend8 { - Blend8(BlendShape8 shape,int alphamap) : m_Shape(shape), m_AlphaMap(alphamap) {} - - BlendShape8 m_Shape; - int m_AlphaMap; -}; - -/////////////////////////////////////////////////////////////////////////////// -// Data tables for mapping between shapes and blend maps -/////////////////////////////////////////////////////////////////////////////// - -const Blend4 Blends1Neighbour[] = -{ - Blend4(BlendShape4(1,0,0,0), 12) -}; - - -const Blend4 Blends2Neighbour[] = -{ - Blend4(BlendShape4(0,1,1,0), 7), - Blend4(BlendShape4(1,0,1,0), 10) -}; - -const Blend8 Blends2Neighbour8[] = -{ - Blend8(BlendShape8(1,1,0,0,0,0,0,0), 12), - Blend8(BlendShape8(1,0,0,0,0,1,0,0), 12), - Blend8(BlendShape8(0,1,0,1,0,0,0,0), 0) , - Blend8(BlendShape8(0,1,0,0,0,1,0,0), 0) -}; - -const Blend4 Blends3Neighbour[] = -{ - Blend4(BlendShape4(1,1,1,0), 4) -}; - -const Blend8 Blends3Neighbour8[] = -{ - Blend8(BlendShape8(1,1,0,0,1,0,0,0), 10), - Blend8(BlendShape8(1,1,0,0,0,0,0,1), 12), - Blend8(BlendShape8(1,1,1,0,0,0,0,0), 1), - Blend8(BlendShape8(0,1,1,0,1,0,0,0), 7), - Blend8(BlendShape8(0,0,1,0,1,0,1,0), 4), - Blend8(BlendShape8(1,1,0,0,0,1,0,0), 12), - Blend8(BlendShape8(1,1,0,1,0,0,0,0), 12), - Blend8(BlendShape8(0,0,1,0,1,0,0,1), 7), - Blend8(BlendShape8(1,0,0,1,0,1,0,0), 12), - Blend8(BlendShape8(0,1,0,1,0,1,0,0), 0) -}; - -const Blend8 Blends4Neighbour8[] = -{ - Blend8(BlendShape8(1,1,0,0,1,0,0,1), 10), - Blend8(BlendShape8(1,1,0,1,1,0,0,0), 10), - Blend8(BlendShape8(1,1,0,0,1,1,0,0), 10), - Blend8(BlendShape8(1,1,0,1,0,0,0,1), 12), - Blend8(BlendShape8(0,1,1,0,1,1,0,0), 7), - Blend8(BlendShape8(1,1,1,1,0,0,0,0), 1), - Blend8(BlendShape8(1,1,1,0,1,0,0,0), 3), - Blend8(BlendShape8(0,0,1,0,1,1,0,1), 7), - Blend8(BlendShape8(1,0,1,0,1,1,0,0), 4), - Blend8(BlendShape8(1,1,1,0,0,1,0,0), 1), - Blend8(BlendShape8(1,1,0,1,0,1,0,0), 12), - Blend8(BlendShape8(0,1,0,1,0,1,0,1), 0) -}; - -const Blend8 Blends5Neighbour8[] = -{ - Blend8(BlendShape8(1,1,1,1,1,0,0,0), 2), - Blend8(BlendShape8(1,1,1,1,0,0,0,1), 1), - Blend8(BlendShape8(1,1,1,0,1,0,0,1), 3), - Blend8(BlendShape8(1,1,1,0,1,0,1,0), 11), - Blend8(BlendShape8(1,1,1,0,0,1,0,1), 1), - Blend8(BlendShape8(1,1,0,1,1,1,0,0), 10), - Blend8(BlendShape8(1,1,1,0,1,1,0,0), 3), - Blend8(BlendShape8(1,0,1,0,1,1,0,1), 4), - Blend8(BlendShape8(1,1,0,1,0,1,0,1), 12), - Blend8(BlendShape8(0,1,1,0,1,1,0,1), 7) -}; - -const Blend8 Blends6Neighbour8[] = -{ - Blend8(BlendShape8(1,1,1,1,1,1,0,0), 2), - Blend8(BlendShape8(1,1,1,1,1,0,1,0), 8), - Blend8(BlendShape8(1,1,1,1,0,1,0,1), 1), - Blend8(BlendShape8(1,1,1,0,1,1,1,0), 6), - Blend8(BlendShape8(1,1,1,0,1,1,0,1), 3), - Blend8(BlendShape8(1,1,0,1,1,1,0,1), 10) -}; - -const Blend8 Blends7Neighbour8[] = -{ - Blend8(BlendShape8(1,1,1,1,1,1,0,1), 2), - Blend8(BlendShape8(1,1,1,1,1,1,1,0), 9) -}; - -/////////////////////////////////////////////////////////////////////////////// - - - -/////////////////////////////////////////////////////////////////////////////// -// MatchBlendShapeFlipped: test if the given shape can be made to fit the -// template in either unflipped state, or by flipping the shape in U or V -template -bool MatchBlendShapeFlipped(const T& templateshape,const T& shape,unsigned int& flags) -{ - // test unrotated shape - if (shape==templateshape) { - return true; - } - - // test against shape flipped in U - T tstShape; - templateshape.FlipU(tstShape); - if (shape==tstShape) { - flags|=BLENDMAP_FLIPU; - return true; - } - - // test against shape flipped in V - templateshape.FlipV(tstShape); - if (shape==tstShape) { - flags|=BLENDMAP_FLIPV; - return true; - } - - // no joy; no match by flipping - return false; -} - -/////////////////////////////////////////////////////////////////////////////// -// MatchBlendShape: try and find a matching blendmap, and the required flip/ -// rotation flags, to fit the given shape to the template -template -int MatchBlendShape(const T& templateshape,const T& shape,unsigned int& flags) -{ - // try matching unrotated shape first using just flipping - if (MatchBlendShapeFlipped(templateshape,shape,flags)) { - return true; - } - - // now try iterating through rotations of 90,180,270 degrees - T tstShape; - templateshape.Rotate90(tstShape); - if (MatchBlendShapeFlipped(tstShape,shape,flags)) { - // update flags - note if we've flipped in u or v, we need to rotate in - // the opposite direction - flags|=flags ? BLENDMAP_ROTATE270 : BLENDMAP_ROTATE90; - return true; - } - - templateshape.Rotate180(tstShape); - if (MatchBlendShapeFlipped(tstShape,shape,flags)) { - flags|=BLENDMAP_ROTATE180; - return true; - } - - templateshape.Rotate270(tstShape); - if (MatchBlendShapeFlipped(tstShape,shape,flags)) { - // update flags - note if we've flipped in u or v, we need to rotate in - // the opposite direction - flags|=flags ? BLENDMAP_ROTATE90 : BLENDMAP_ROTATE270; - return true; - } - - return false; -} - -/////////////////////////////////////////////////////////////////////////////// -// LookupBlend: find and return the blendmap fitting the given shape by -// iterating through the given data table and testing each shape in flipped and -// rotated forms until a match is found -template -int LookupBlend(int tableSize,const S* table,const T& shape,unsigned int& flags) -{ - // iterate through known blend shapes - for (int b=0;b +#include + +/////////////////////////////////////////////////////////////////////////////// +// CAlphaMapCalculator: functionality for calculating which alpha blend map +// fits a given shape +namespace CAlphaMapCalculator { + +/////////////////////////////////////////////////////////////////////////////// +// Blend4: structure mapping a blend shape for N,E,S,W to a particular map +struct Blend4 { + Blend4(BlendShape4 shape,int alphamap) : m_Shape(shape), m_AlphaMap(alphamap) {} + + BlendShape4 m_Shape; + int m_AlphaMap; +}; + +/////////////////////////////////////////////////////////////////////////////// +// Blend8: structure mapping a blend shape for N,NE,E,SE,S,SW,W,NW to a +// particular map +struct Blend8 { + Blend8(BlendShape8 shape,int alphamap) : m_Shape(shape), m_AlphaMap(alphamap) {} + + BlendShape8 m_Shape; + int m_AlphaMap; +}; + +/////////////////////////////////////////////////////////////////////////////// +// Data tables for mapping between shapes and blend maps +/////////////////////////////////////////////////////////////////////////////// + +const Blend4 Blends1Neighbour[] = +{ + Blend4(BlendShape4(1,0,0,0), 12) +}; + + +const Blend4 Blends2Neighbour[] = +{ + Blend4(BlendShape4(0,1,1,0), 7), + Blend4(BlendShape4(1,0,1,0), 10) +}; + +const Blend8 Blends2Neighbour8[] = +{ + Blend8(BlendShape8(1,1,0,0,0,0,0,0), 12), + Blend8(BlendShape8(1,0,0,0,0,1,0,0), 12), + Blend8(BlendShape8(0,1,0,1,0,0,0,0), 0) , + Blend8(BlendShape8(0,1,0,0,0,1,0,0), 0) +}; + +const Blend4 Blends3Neighbour[] = +{ + Blend4(BlendShape4(1,1,1,0), 4) +}; + +const Blend8 Blends3Neighbour8[] = +{ + Blend8(BlendShape8(1,1,0,0,1,0,0,0), 10), + Blend8(BlendShape8(1,1,0,0,0,0,0,1), 12), + Blend8(BlendShape8(1,1,1,0,0,0,0,0), 1), + Blend8(BlendShape8(0,1,1,0,1,0,0,0), 7), + Blend8(BlendShape8(0,0,1,0,1,0,1,0), 4), + Blend8(BlendShape8(1,1,0,0,0,1,0,0), 12), + Blend8(BlendShape8(1,1,0,1,0,0,0,0), 12), + Blend8(BlendShape8(0,0,1,0,1,0,0,1), 7), + Blend8(BlendShape8(1,0,0,1,0,1,0,0), 12), + Blend8(BlendShape8(0,1,0,1,0,1,0,0), 0) +}; + +const Blend8 Blends4Neighbour8[] = +{ + Blend8(BlendShape8(1,1,0,0,1,0,0,1), 10), + Blend8(BlendShape8(1,1,0,1,1,0,0,0), 10), + Blend8(BlendShape8(1,1,0,0,1,1,0,0), 10), + Blend8(BlendShape8(1,1,0,1,0,0,0,1), 12), + Blend8(BlendShape8(0,1,1,0,1,1,0,0), 7), + Blend8(BlendShape8(1,1,1,1,0,0,0,0), 1), + Blend8(BlendShape8(1,1,1,0,1,0,0,0), 3), + Blend8(BlendShape8(0,0,1,0,1,1,0,1), 7), + Blend8(BlendShape8(1,0,1,0,1,1,0,0), 4), + Blend8(BlendShape8(1,1,1,0,0,1,0,0), 1), + Blend8(BlendShape8(1,1,0,1,0,1,0,0), 12), + Blend8(BlendShape8(0,1,0,1,0,1,0,1), 0) +}; + +const Blend8 Blends5Neighbour8[] = +{ + Blend8(BlendShape8(1,1,1,1,1,0,0,0), 2), + Blend8(BlendShape8(1,1,1,1,0,0,0,1), 1), + Blend8(BlendShape8(1,1,1,0,1,0,0,1), 3), + Blend8(BlendShape8(1,1,1,0,1,0,1,0), 11), + Blend8(BlendShape8(1,1,1,0,0,1,0,1), 1), + Blend8(BlendShape8(1,1,0,1,1,1,0,0), 10), + Blend8(BlendShape8(1,1,1,0,1,1,0,0), 3), + Blend8(BlendShape8(1,0,1,0,1,1,0,1), 4), + Blend8(BlendShape8(1,1,0,1,0,1,0,1), 12), + Blend8(BlendShape8(0,1,1,0,1,1,0,1), 7) +}; + +const Blend8 Blends6Neighbour8[] = +{ + Blend8(BlendShape8(1,1,1,1,1,1,0,0), 2), + Blend8(BlendShape8(1,1,1,1,1,0,1,0), 8), + Blend8(BlendShape8(1,1,1,1,0,1,0,1), 1), + Blend8(BlendShape8(1,1,1,0,1,1,1,0), 6), + Blend8(BlendShape8(1,1,1,0,1,1,0,1), 3), + Blend8(BlendShape8(1,1,0,1,1,1,0,1), 10) +}; + +const Blend8 Blends7Neighbour8[] = +{ + Blend8(BlendShape8(1,1,1,1,1,1,0,1), 2), + Blend8(BlendShape8(1,1,1,1,1,1,1,0), 9) +}; + +/////////////////////////////////////////////////////////////////////////////// + + + +/////////////////////////////////////////////////////////////////////////////// +// MatchBlendShapeFlipped: test if the given shape can be made to fit the +// template in either unflipped state, or by flipping the shape in U or V +template +bool MatchBlendShapeFlipped(const T& templateshape,const T& shape,unsigned int& flags) +{ + // test unrotated shape + if (shape==templateshape) { + return true; + } + + // test against shape flipped in U + T tstShape; + templateshape.FlipU(tstShape); + if (shape==tstShape) { + flags|=BLENDMAP_FLIPU; + return true; + } + + // test against shape flipped in V + templateshape.FlipV(tstShape); + if (shape==tstShape) { + flags|=BLENDMAP_FLIPV; + return true; + } + + // no joy; no match by flipping + return false; +} + +/////////////////////////////////////////////////////////////////////////////// +// MatchBlendShape: try and find a matching blendmap, and the required flip/ +// rotation flags, to fit the given shape to the template +template +int MatchBlendShape(const T& templateshape,const T& shape,unsigned int& flags) +{ + // try matching unrotated shape first using just flipping + if (MatchBlendShapeFlipped(templateshape,shape,flags)) { + return true; + } + + // now try iterating through rotations of 90,180,270 degrees + T tstShape; + templateshape.Rotate90(tstShape); + if (MatchBlendShapeFlipped(tstShape,shape,flags)) { + // update flags - note if we've flipped in u or v, we need to rotate in + // the opposite direction + flags|=flags ? BLENDMAP_ROTATE270 : BLENDMAP_ROTATE90; + return true; + } + + templateshape.Rotate180(tstShape); + if (MatchBlendShapeFlipped(tstShape,shape,flags)) { + flags|=BLENDMAP_ROTATE180; + return true; + } + + templateshape.Rotate270(tstShape); + if (MatchBlendShapeFlipped(tstShape,shape,flags)) { + // update flags - note if we've flipped in u or v, we need to rotate in + // the opposite direction + flags|=flags ? BLENDMAP_ROTATE90 : BLENDMAP_ROTATE270; + return true; + } + + return false; +} + +/////////////////////////////////////////////////////////////////////////////// +// LookupBlend: find and return the blendmap fitting the given shape by +// iterating through the given data table and testing each shape in flipped and +// rotated forms until a match is found +template +int LookupBlend(int tableSize,const S* table,const T& shape,unsigned int& flags) +{ + // iterate through known blend shapes + for (int b=0;b -#include "BlendShapes.h" - -// defines for blendmap flipping/rotating -#define BLENDMAP_FLIPV 0x01 -#define BLENDMAP_FLIPU 0x02 -#define BLENDMAP_ROTATE90 0x04 -#define BLENDMAP_ROTATE180 0x08 -#define BLENDMAP_ROTATE270 0x10 - -/////////////////////////////////////////////////////////////////////////////// -// CAlphaMapCalculator: functionality for calculating which alpha blend map -// fits a given shape -namespace CAlphaMapCalculator { - // Calculate: return the index of the blend map that fits the given shape, - // and the set of flip/rotation flags to get the shape correctly oriented - int Calculate(BlendShape8 shape,unsigned int& flags); -} - -#endif +/////////////////////////////////////////////////////////////////////////////// +// +// Name: AlphaMapCalculator.h +// Author: Rich Cross +// Contact: rich@wildfiregames.com +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _ALPHAMAPCALCULATOR_H +#define _ALPHAMAPCALCULATOR_H + +#include +#include "BlendShapes.h" + +// defines for blendmap flipping/rotating +#define BLENDMAP_FLIPV 0x01 +#define BLENDMAP_FLIPU 0x02 +#define BLENDMAP_ROTATE90 0x04 +#define BLENDMAP_ROTATE180 0x08 +#define BLENDMAP_ROTATE270 0x10 + +/////////////////////////////////////////////////////////////////////////////// +// CAlphaMapCalculator: functionality for calculating which alpha blend map +// fits a given shape +namespace CAlphaMapCalculator { + // Calculate: return the index of the blend map that fits the given shape, + // and the set of flip/rotation flags to get the shape correctly oriented + int Calculate(BlendShape8 shape,unsigned int& flags); +} + +#endif diff --git a/source/terrain/BlendShapes.h b/source/terrain/BlendShapes.h index 9d2e346a66..b5f6daa686 100755 --- a/source/terrain/BlendShapes.h +++ b/source/terrain/BlendShapes.h @@ -1,142 +1,142 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Name: BlendShapes.h -// Author: Rich Cross -// Contact: rich@wildfiregames.com -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef _BLENDSHAPES_H -#define _BLENDSHAPES_H - -struct BlendShape4 -{ -public: - BlendShape4() {} - BlendShape4(int a,int b,int c,int d) { - m_Data[0]=a; m_Data[1]=b; m_Data[2]=c; m_Data[3]=d; - } - - int& operator[](int index) { return m_Data[index]; } - const int& operator[](int index) const { return m_Data[index]; } - - bool operator==(const BlendShape4& lhs) const { - return memcmp(m_Data,lhs.m_Data,sizeof(BlendShape4))==0; - } - - void Rotate90(BlendShape4& dst) const { - dst[0]=m_Data[3]; - dst[1]=m_Data[0]; - dst[2]=m_Data[1]; - dst[3]=m_Data[2]; - } - - void Rotate180(BlendShape4& dst) const { - dst[0]=m_Data[2]; - dst[1]=m_Data[3]; - dst[2]=m_Data[0]; - dst[3]=m_Data[1]; - } - - void Rotate270(BlendShape4& dst) const { - dst[0]=m_Data[1]; - dst[1]=m_Data[2]; - dst[2]=m_Data[3]; - dst[3]=m_Data[0]; - } - - void FlipU(BlendShape4& dst) const { - dst[0]=m_Data[2]; - dst[1]=m_Data[1]; - dst[2]=m_Data[0]; - dst[3]=m_Data[3]; - } - - void FlipV(BlendShape4& dst) const { - dst[0]=m_Data[0]; - dst[1]=m_Data[3]; - dst[2]=m_Data[2]; - dst[3]=m_Data[1]; - } - -private: - int m_Data[4]; -}; - - -struct BlendShape8 -{ -public: - BlendShape8() {} - BlendShape8(int a,int b,int c,int d,int e,int f,int g,int h) { - m_Data[0]=a; m_Data[1]=b; m_Data[2]=c; m_Data[3]=d; - m_Data[4]=e; m_Data[5]=f; m_Data[6]=g; m_Data[7]=h; - } - - int& operator[](int index) { return m_Data[index]; } - const int& operator[](int index) const { return m_Data[index]; } - - bool operator==(const BlendShape8& lhs) const { - return memcmp(m_Data,lhs.m_Data,sizeof(BlendShape8))==0; - } - - void Rotate90(BlendShape8& dst) const { - dst[0]=m_Data[6]; - dst[1]=m_Data[7]; - dst[2]=m_Data[0]; - dst[3]=m_Data[1]; - dst[4]=m_Data[2]; - dst[5]=m_Data[3]; - dst[6]=m_Data[4]; - dst[7]=m_Data[5]; - } - - void Rotate180(BlendShape8& dst) const { - dst[0]=m_Data[4]; - dst[1]=m_Data[5]; - dst[2]=m_Data[6]; - dst[3]=m_Data[7]; - dst[4]=m_Data[0]; - dst[5]=m_Data[1]; - dst[6]=m_Data[2]; - dst[7]=m_Data[3]; - } - - void Rotate270(BlendShape8& dst) const { - dst[0]=m_Data[2]; - dst[1]=m_Data[3]; - dst[2]=m_Data[4]; - dst[3]=m_Data[5]; - dst[4]=m_Data[6]; - dst[5]=m_Data[7]; - dst[6]=m_Data[0]; - dst[7]=m_Data[1]; - } - - void FlipU(BlendShape8& dst) const { - dst[0]=m_Data[4]; - dst[1]=m_Data[3]; - dst[2]=m_Data[2]; - dst[3]=m_Data[1]; - dst[4]=m_Data[0]; - dst[5]=m_Data[7]; - dst[6]=m_Data[6]; - dst[7]=m_Data[5]; - } - - void FlipV(BlendShape8& dst) const { - dst[0]=m_Data[0]; - dst[1]=m_Data[7]; - dst[2]=m_Data[6]; - dst[3]=m_Data[5]; - dst[4]=m_Data[4]; - dst[5]=m_Data[3]; - dst[6]=m_Data[2]; - dst[7]=m_Data[1]; - } - -private: - int m_Data[8]; -}; - -#endif +/////////////////////////////////////////////////////////////////////////////// +// +// Name: BlendShapes.h +// Author: Rich Cross +// Contact: rich@wildfiregames.com +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _BLENDSHAPES_H +#define _BLENDSHAPES_H + +struct BlendShape4 +{ +public: + BlendShape4() {} + BlendShape4(int a,int b,int c,int d) { + m_Data[0]=a; m_Data[1]=b; m_Data[2]=c; m_Data[3]=d; + } + + int& operator[](int index) { return m_Data[index]; } + const int& operator[](int index) const { return m_Data[index]; } + + bool operator==(const BlendShape4& lhs) const { + return memcmp(m_Data,lhs.m_Data,sizeof(BlendShape4))==0; + } + + void Rotate90(BlendShape4& dst) const { + dst[0]=m_Data[3]; + dst[1]=m_Data[0]; + dst[2]=m_Data[1]; + dst[3]=m_Data[2]; + } + + void Rotate180(BlendShape4& dst) const { + dst[0]=m_Data[2]; + dst[1]=m_Data[3]; + dst[2]=m_Data[0]; + dst[3]=m_Data[1]; + } + + void Rotate270(BlendShape4& dst) const { + dst[0]=m_Data[1]; + dst[1]=m_Data[2]; + dst[2]=m_Data[3]; + dst[3]=m_Data[0]; + } + + void FlipU(BlendShape4& dst) const { + dst[0]=m_Data[2]; + dst[1]=m_Data[1]; + dst[2]=m_Data[0]; + dst[3]=m_Data[3]; + } + + void FlipV(BlendShape4& dst) const { + dst[0]=m_Data[0]; + dst[1]=m_Data[3]; + dst[2]=m_Data[2]; + dst[3]=m_Data[1]; + } + +private: + int m_Data[4]; +}; + + +struct BlendShape8 +{ +public: + BlendShape8() {} + BlendShape8(int a,int b,int c,int d,int e,int f,int g,int h) { + m_Data[0]=a; m_Data[1]=b; m_Data[2]=c; m_Data[3]=d; + m_Data[4]=e; m_Data[5]=f; m_Data[6]=g; m_Data[7]=h; + } + + int& operator[](int index) { return m_Data[index]; } + const int& operator[](int index) const { return m_Data[index]; } + + bool operator==(const BlendShape8& lhs) const { + return memcmp(m_Data,lhs.m_Data,sizeof(BlendShape8))==0; + } + + void Rotate90(BlendShape8& dst) const { + dst[0]=m_Data[6]; + dst[1]=m_Data[7]; + dst[2]=m_Data[0]; + dst[3]=m_Data[1]; + dst[4]=m_Data[2]; + dst[5]=m_Data[3]; + dst[6]=m_Data[4]; + dst[7]=m_Data[5]; + } + + void Rotate180(BlendShape8& dst) const { + dst[0]=m_Data[4]; + dst[1]=m_Data[5]; + dst[2]=m_Data[6]; + dst[3]=m_Data[7]; + dst[4]=m_Data[0]; + dst[5]=m_Data[1]; + dst[6]=m_Data[2]; + dst[7]=m_Data[3]; + } + + void Rotate270(BlendShape8& dst) const { + dst[0]=m_Data[2]; + dst[1]=m_Data[3]; + dst[2]=m_Data[4]; + dst[3]=m_Data[5]; + dst[4]=m_Data[6]; + dst[5]=m_Data[7]; + dst[6]=m_Data[0]; + dst[7]=m_Data[1]; + } + + void FlipU(BlendShape8& dst) const { + dst[0]=m_Data[4]; + dst[1]=m_Data[3]; + dst[2]=m_Data[2]; + dst[3]=m_Data[1]; + dst[4]=m_Data[0]; + dst[5]=m_Data[7]; + dst[6]=m_Data[6]; + dst[7]=m_Data[5]; + } + + void FlipV(BlendShape8& dst) const { + dst[0]=m_Data[0]; + dst[1]=m_Data[7]; + dst[2]=m_Data[6]; + dst[3]=m_Data[5]; + dst[4]=m_Data[4]; + dst[5]=m_Data[3]; + dst[6]=m_Data[2]; + dst[7]=m_Data[1]; + } + +private: + int m_Data[8]; +}; + +#endif diff --git a/source/terrain/Bound.cpp b/source/terrain/Bound.cpp index da44782a20..696d511170 100755 --- a/source/terrain/Bound.cpp +++ b/source/terrain/Bound.cpp @@ -1,162 +1,162 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Name: Bound.cpp -// Author: Rich Cross -// Contact: rich@wildfiregames.com -// -/////////////////////////////////////////////////////////////////////////////// - - -// necessary includes -#include -#include -#include "Bound.h" - -/////////////////////////////////////////////////////////////////////////////// -// operator+=: extend this bound to include given bound -CBound& CBound::operator+=(const CBound& b) -{ - for (int i=0;i<3;++i) { - if (b[0][i]m_Data[1][i]) - m_Data[1][i]=b[1][i]; - } - - return *this; -} - -/////////////////////////////////////////////////////////////////////////////// -// operator+=: extend this bound to include given point -CBound& CBound::operator+=(const CVector3D& pt) -{ - for (int i=0;i<3;++i) { - if (pt[i]m_Data[1][i]) - m_Data[1][i]=pt[i]; - } - - return *this; -} - -/////////////////////////////////////////////////////////////////////////////// -// RayIntersect: intersect ray with this bound; return true -// if ray hits (and store entry and exit times), or false -// otherwise -// note: incoming ray direction must be normalised -bool CBound::RayIntersect(const CVector3D& origin,const CVector3D& dir, - float& tmin,float& tmax) const -{ - float t1,t2; - float tnear,tfar; - - if (dir[0]==0) { - if (origin[0]m_Data[1][0]) - return false; - else { - tnear=(float) FLT_MIN; - tfar=(float) FLT_MAX; - } - } else { - t1=(m_Data[0][0]-origin[0])/dir[0]; - t2=(m_Data[1][0]-origin[0])/dir[0]; - - if (dir[0]<0) { - tnear = t2; - tfar = t1; - } else { - tnear = t1; - tfar = t2; - } - - if (tfar<0) - return false; - } - - if (dir[1]==0 && (origin[1]m_Data[1][1])) - return false; - else { - t1=(m_Data[0][1]-origin[1])/dir[1]; - t2=(m_Data[1][1]-origin[1])/dir[1]; - - if (dir[1]<0) { - if (t2>tnear) - tnear = t2; - if (t1tnear) - tnear = t1; - if (t2tfar || tfar<0) - return false; - } - - if (dir[2]==0 && (origin[2]m_Data[1][2])) - return false; - else { - t1=(m_Data[0][2]-origin[2])/dir[2]; - t2=(m_Data[1][2]-origin[2])/dir[2]; - - if (dir[2]<0) { - if (t2>tnear) - tnear = t2; - if (t1tnear) - tnear = t1; - if (t2tfar || tfar<0) - return false; - } - - tmin=tnear; - tmax=tfar; - - return true; -} - -/////////////////////////////////////////////////////////////////////////////// -// SetEmpty: initialise this bound as empty -void CBound::SetEmpty() -{ - m_Data[0]=CVector3D(FLT_MAX,FLT_MAX,FLT_MAX); - m_Data[1]=CVector3D(FLT_MIN,FLT_MIN,FLT_MIN); -} - -/////////////////////////////////////////////////////////////////////////////// -// Transform: transform this bound by given matrix; return transformed bound -// in 'result' parameter - slightly modified version of code in Graphic Gems -// (can't remember which one it was, though) -void CBound::Transform(const CMatrix3D& m,CBound& result) const -{ - assert(this!=&result); - - for (int i=0;i<3;++i) { - // handle translation - result[0][i]=result[1][i]=m(3,i); - - // Now find the extreme points by considering the product of the - // min and max with each component of matrix - for(int j=0;j<3;j++) { - float a=m(i,j)*m_Data[0][j]; - float b=m(i,j)*m_Data[1][j]; - - if (a +#include +#include "Bound.h" + +/////////////////////////////////////////////////////////////////////////////// +// operator+=: extend this bound to include given bound +CBound& CBound::operator+=(const CBound& b) +{ + for (int i=0;i<3;++i) { + if (b[0][i]m_Data[1][i]) + m_Data[1][i]=b[1][i]; + } + + return *this; +} + +/////////////////////////////////////////////////////////////////////////////// +// operator+=: extend this bound to include given point +CBound& CBound::operator+=(const CVector3D& pt) +{ + for (int i=0;i<3;++i) { + if (pt[i]m_Data[1][i]) + m_Data[1][i]=pt[i]; + } + + return *this; +} + +/////////////////////////////////////////////////////////////////////////////// +// RayIntersect: intersect ray with this bound; return true +// if ray hits (and store entry and exit times), or false +// otherwise +// note: incoming ray direction must be normalised +bool CBound::RayIntersect(const CVector3D& origin,const CVector3D& dir, + float& tmin,float& tmax) const +{ + float t1,t2; + float tnear,tfar; + + if (dir[0]==0) { + if (origin[0]m_Data[1][0]) + return false; + else { + tnear=(float) FLT_MIN; + tfar=(float) FLT_MAX; + } + } else { + t1=(m_Data[0][0]-origin[0])/dir[0]; + t2=(m_Data[1][0]-origin[0])/dir[0]; + + if (dir[0]<0) { + tnear = t2; + tfar = t1; + } else { + tnear = t1; + tfar = t2; + } + + if (tfar<0) + return false; + } + + if (dir[1]==0 && (origin[1]m_Data[1][1])) + return false; + else { + t1=(m_Data[0][1]-origin[1])/dir[1]; + t2=(m_Data[1][1]-origin[1])/dir[1]; + + if (dir[1]<0) { + if (t2>tnear) + tnear = t2; + if (t1tnear) + tnear = t1; + if (t2tfar || tfar<0) + return false; + } + + if (dir[2]==0 && (origin[2]m_Data[1][2])) + return false; + else { + t1=(m_Data[0][2]-origin[2])/dir[2]; + t2=(m_Data[1][2]-origin[2])/dir[2]; + + if (dir[2]<0) { + if (t2>tnear) + tnear = t2; + if (t1tnear) + tnear = t1; + if (t2tfar || tfar<0) + return false; + } + + tmin=tnear; + tmax=tfar; + + return true; +} + +/////////////////////////////////////////////////////////////////////////////// +// SetEmpty: initialise this bound as empty +void CBound::SetEmpty() +{ + m_Data[0]=CVector3D(FLT_MAX,FLT_MAX,FLT_MAX); + m_Data[1]=CVector3D(FLT_MIN,FLT_MIN,FLT_MIN); +} + +/////////////////////////////////////////////////////////////////////////////// +// Transform: transform this bound by given matrix; return transformed bound +// in 'result' parameter - slightly modified version of code in Graphic Gems +// (can't remember which one it was, though) +void CBound::Transform(const CMatrix3D& m,CBound& result) const +{ + assert(this!=&result); + + for (int i=0;i<3;++i) { + // handle translation + result[0][i]=result[1][i]=m(3,i); + + // Now find the extreme points by considering the product of the + // min and max with each component of matrix + for(int j=0;j<3;j++) { + float a=m(i,j)*m_Data[0][j]; + float b=m(i,j)*m_Data[1][j]; + + if (am_X; - m_ViewPort.m_Y = viewport->m_Y; - m_ViewPort.m_Width = viewport->m_Width; - m_ViewPort.m_Height = viewport->m_Height; -} +//*********************************************************** +// +// Name: Camera.Cpp +// Last Update: 24/2/02 +// Author: Poya Manouchehri +// +// Description: CCamera holds a view and a projection matrix. +// It also has a frustum which can be used to +// cull objects for rendering. +// +//*********************************************************** + +#include "Camera.h" + +CCamera::CCamera () +{ + // set viewport to something anything should handle, but should be initialised + // to window size before use + m_ViewPort.m_X = 0; + m_ViewPort.m_Y = 0; + m_ViewPort.m_Width = 800; + m_ViewPort.m_Height = 600; +} + +CCamera::~CCamera () +{ +} + +void CCamera::SetProjection (float nearp, float farp, float fov) +{ + float h, w, Q; + + m_NearPlane = nearp; + m_FarPlane = farp; + m_FOV = fov; + + float Aspect = (float)m_ViewPort.m_Width/(float)m_ViewPort.m_Height; + + w = 1/tanf (fov*0.5f*Aspect); + h = 1/tanf (fov*0.5f); + Q = m_FarPlane / (m_FarPlane - m_NearPlane); + + m_ProjMat.SetZero (); + m_ProjMat._11 = w; + m_ProjMat._22 = h; + m_ProjMat._33 = Q; + m_ProjMat._34 = -Q*m_NearPlane; + m_ProjMat._43 = 1.0f; +} + +//Updates the frustum planes. Should be called +//everytime the view or projection matrices are +//altered. +void CCamera::UpdateFrustum () +{ + CMatrix3D MatFinal; + CMatrix3D MatView; + + m_Orientation.GetInverse(MatView); + + MatFinal = m_ProjMat * MatView; + + //get the RIGHT plane + m_ViewFrustum.SetNumPlanes (6); + + m_ViewFrustum.m_aPlanes[0].m_Norm.X = MatFinal._41-MatFinal._11; + m_ViewFrustum.m_aPlanes[0].m_Norm.Y = MatFinal._42-MatFinal._12; + m_ViewFrustum.m_aPlanes[0].m_Norm.Z = MatFinal._43-MatFinal._13; + m_ViewFrustum.m_aPlanes[0].m_Dist = MatFinal._44-MatFinal._14; + + //get the LEFT plane + m_ViewFrustum.m_aPlanes[1].m_Norm.X = MatFinal._41+MatFinal._11; + m_ViewFrustum.m_aPlanes[1].m_Norm.Y = MatFinal._42+MatFinal._12; + m_ViewFrustum.m_aPlanes[1].m_Norm.Z = MatFinal._43+MatFinal._13; + m_ViewFrustum.m_aPlanes[1].m_Dist = MatFinal._44+MatFinal._14; + + //get the BOTTOM plane + m_ViewFrustum.m_aPlanes[2].m_Norm.X = MatFinal._41+MatFinal._21; + m_ViewFrustum.m_aPlanes[2].m_Norm.Y = MatFinal._42+MatFinal._22; + m_ViewFrustum.m_aPlanes[2].m_Norm.Z = MatFinal._43+MatFinal._23; + m_ViewFrustum.m_aPlanes[2].m_Dist = MatFinal._44+MatFinal._24; + + //get the TOP plane + m_ViewFrustum.m_aPlanes[3].m_Norm.X = MatFinal._41-MatFinal._21; + m_ViewFrustum.m_aPlanes[3].m_Norm.Y = MatFinal._42-MatFinal._22; + m_ViewFrustum.m_aPlanes[3].m_Norm.Z = MatFinal._43-MatFinal._23; + m_ViewFrustum.m_aPlanes[3].m_Dist = MatFinal._44-MatFinal._24; + + //get the FAR plane + m_ViewFrustum.m_aPlanes[4].m_Norm.X = MatFinal._41-MatFinal._31; + m_ViewFrustum.m_aPlanes[4].m_Norm.Y = MatFinal._42-MatFinal._32; + m_ViewFrustum.m_aPlanes[4].m_Norm.Z = MatFinal._43-MatFinal._33; + m_ViewFrustum.m_aPlanes[4].m_Dist = MatFinal._44-MatFinal._34; + + //get the NEAR plane + m_ViewFrustum.m_aPlanes[5].m_Norm.X = MatFinal._41+MatFinal._31; + m_ViewFrustum.m_aPlanes[5].m_Norm.Y = MatFinal._42+MatFinal._32; + m_ViewFrustum.m_aPlanes[5].m_Norm.Z = MatFinal._43+MatFinal._33; + m_ViewFrustum.m_aPlanes[5].m_Dist = MatFinal._44+MatFinal._34; +} + +void CCamera::SetViewPort (SViewPort *viewport) +{ + m_ViewPort.m_X = viewport->m_X; + m_ViewPort.m_Y = viewport->m_Y; + m_ViewPort.m_Width = viewport->m_Width; + m_ViewPort.m_Height = viewport->m_Height; +} diff --git a/source/terrain/Camera.h b/source/terrain/Camera.h index 6476c42183..90fa60b4cb 100755 --- a/source/terrain/Camera.h +++ b/source/terrain/Camera.h @@ -1,72 +1,72 @@ -//*********************************************************** -// -// Name: Camera.H -// Last Update: 24/2/02 -// Author: Poya Manouchehri -// -// Description: CCamera holds a view and a projection matrix. -// It also has a frustum which can be used to -// cull objects for rendering. -// -//*********************************************************** - -#ifndef CAMERA_H -#define CAMERA_H - -#include "Frustum.h" -#include "Matrix3D.h" - -//view port -struct SViewPort -{ - unsigned int m_X; - unsigned int m_Y; - unsigned int m_Width; - unsigned int m_Height; -}; - - -class CCamera -{ - public: - CCamera (); - ~CCamera (); - - //Methods for projection - void SetProjection (CMatrix3D *proj) { m_ProjMat = *proj; } - void SetProjection (float nearp, float farp, float fov); - CMatrix3D GetProjection () { return m_ProjMat; } - - //Updates the frustum planes. Should be called - //everytime the view or projection matrices are - //altered. - void UpdateFrustum (); - CFrustum GetFustum () { return m_ViewFrustum; } - - void SetViewPort (SViewPort *viewport); - SViewPort GetViewPort () { return m_ViewPort; } - - //getters - float GetNearPlane () { return m_NearPlane; } - float GetFarPlane () { return m_FarPlane; } - float GetFOV () { return m_FOV; } - - public: - //This is the orientation matrix. The inverse of this - //is the view matrix - CMatrix3D m_Orientation; - - private: - //keep the projection matrix private - //so we can't fiddle with it. - CMatrix3D m_ProjMat; - - float m_NearPlane; - float m_FarPlane; - float m_FOV; - SViewPort m_ViewPort; - - CFrustum m_ViewFrustum; -}; - -#endif +//*********************************************************** +// +// Name: Camera.H +// Last Update: 24/2/02 +// Author: Poya Manouchehri +// +// Description: CCamera holds a view and a projection matrix. +// It also has a frustum which can be used to +// cull objects for rendering. +// +//*********************************************************** + +#ifndef CAMERA_H +#define CAMERA_H + +#include "Frustum.h" +#include "Matrix3D.h" + +//view port +struct SViewPort +{ + unsigned int m_X; + unsigned int m_Y; + unsigned int m_Width; + unsigned int m_Height; +}; + + +class CCamera +{ + public: + CCamera (); + ~CCamera (); + + //Methods for projection + void SetProjection (CMatrix3D *proj) { m_ProjMat = *proj; } + void SetProjection (float nearp, float farp, float fov); + CMatrix3D GetProjection () { return m_ProjMat; } + + //Updates the frustum planes. Should be called + //everytime the view or projection matrices are + //altered. + void UpdateFrustum (); + CFrustum GetFustum () { return m_ViewFrustum; } + + void SetViewPort (SViewPort *viewport); + SViewPort GetViewPort () { return m_ViewPort; } + + //getters + float GetNearPlane () { return m_NearPlane; } + float GetFarPlane () { return m_FarPlane; } + float GetFOV () { return m_FOV; } + + public: + //This is the orientation matrix. The inverse of this + //is the view matrix + CMatrix3D m_Orientation; + + private: + //keep the projection matrix private + //so we can't fiddle with it. + CMatrix3D m_ProjMat; + + float m_NearPlane; + float m_FarPlane; + float m_FOV; + SViewPort m_ViewPort; + + CFrustum m_ViewFrustum; +}; + +#endif diff --git a/source/terrain/Color.h b/source/terrain/Color.h index d86e2ecf64..05078c6b16 100755 --- a/source/terrain/Color.h +++ b/source/terrain/Color.h @@ -1,30 +1,30 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Name: Color.h -// Author: Rich Cross -// Contact: rich@wildfiregames.com -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef _COLOR_H -#define _COLOR_H - -#include "Vector3D.h" -#include "Vector4D.h" - -// simple defines for 3 and 4 component floating point colors - just map to -// corresponding vector types -typedef CVector3D RGBColor; -typedef CVector4D RGBAColor; - -// SColor4ub: structure for packed RGBA colors -struct SColor4ub -{ - u8 R; - u8 G; - u8 B; - u8 A; -}; - - -#endif +/////////////////////////////////////////////////////////////////////////////// +// +// Name: Color.h +// Author: Rich Cross +// Contact: rich@wildfiregames.com +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _COLOR_H +#define _COLOR_H + +#include "Vector3D.h" +#include "Vector4D.h" + +// simple defines for 3 and 4 component floating point colors - just map to +// corresponding vector types +typedef CVector3D RGBColor; +typedef CVector4D RGBAColor; + +// SColor4ub: structure for packed RGBA colors +struct SColor4ub +{ + u8 R; + u8 G; + u8 B; + u8 A; +}; + + +#endif diff --git a/source/terrain/FilePacker.cpp b/source/terrain/FilePacker.cpp index 015ec6041d..2c59bafb82 100755 --- a/source/terrain/FilePacker.cpp +++ b/source/terrain/FilePacker.cpp @@ -1,76 +1,76 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Name: FilePacker.cpp -// Author: Rich Cross -// Contact: rich@wildfiregames.com -// -/////////////////////////////////////////////////////////////////////////////// - -#include "FilePacker.h" -#include - - -//////////////////////////////////////////////////////////////////////////////////////// -// CFilePacker constructor -CFilePacker::CFilePacker() -{ -} - -//////////////////////////////////////////////////////////////////////////////////////// -// Write: write out any packed data to file, using given version and magic bits -void CFilePacker::Write(const char* filename,u32 version,const char magicstr[4]) -{ - FILE* fp=fopen(filename,"wb"); - if (!fp) { - throw CFileOpenError(); - } - - // write magic bits - if (fwrite(magicstr,sizeof(char)*4,1,fp)!=1) { - fclose(fp); - throw CFileWriteError(); - } - - // write version - if (fwrite(&version,sizeof(version),1,fp)!=1) { - fclose(fp); - throw CFileWriteError(); - } - - // get size of data - u32 datasize=m_Data.size(); - if (fwrite(&datasize,sizeof(datasize),1,fp)!=1) { - fclose(fp); - throw CFileWriteError(); - } - - // write out one big chunk of data - if (fwrite(&m_Data[0],datasize,1,fp)!=1) { - fclose(fp); - throw CFileWriteError(); - } - - // all done - fclose(fp); -} - - -//////////////////////////////////////////////////////////////////////////////////////// -// PackRaw: pack given number of bytes onto the end of the data stream -void CFilePacker::PackRaw(const void* rawdata,u32 rawdatalen) -{ - u32 start=m_Data.size(); - m_Data.resize(m_Data.size()+rawdatalen); - memcpy(&m_Data[start],rawdata,rawdatalen); - -} - -//////////////////////////////////////////////////////////////////////////////////////// -// PackString: pack a string onto the end of the data stream -void CFilePacker::PackString(const CStr& str) -{ - u32 len=str.Length(); - PackRaw(&len,sizeof(len)); - PackRaw((const char*) str,len); -} - +/////////////////////////////////////////////////////////////////////////////// +// +// Name: FilePacker.cpp +// Author: Rich Cross +// Contact: rich@wildfiregames.com +// +/////////////////////////////////////////////////////////////////////////////// + +#include "FilePacker.h" +#include + + +//////////////////////////////////////////////////////////////////////////////////////// +// CFilePacker constructor +CFilePacker::CFilePacker() +{ +} + +//////////////////////////////////////////////////////////////////////////////////////// +// Write: write out any packed data to file, using given version and magic bits +void CFilePacker::Write(const char* filename,u32 version,const char magicstr[4]) +{ + FILE* fp=fopen(filename,"wb"); + if (!fp) { + throw CFileOpenError(); + } + + // write magic bits + if (fwrite(magicstr,sizeof(char)*4,1,fp)!=1) { + fclose(fp); + throw CFileWriteError(); + } + + // write version + if (fwrite(&version,sizeof(version),1,fp)!=1) { + fclose(fp); + throw CFileWriteError(); + } + + // get size of data + u32 datasize=m_Data.size(); + if (fwrite(&datasize,sizeof(datasize),1,fp)!=1) { + fclose(fp); + throw CFileWriteError(); + } + + // write out one big chunk of data + if (fwrite(&m_Data[0],datasize,1,fp)!=1) { + fclose(fp); + throw CFileWriteError(); + } + + // all done + fclose(fp); +} + + +//////////////////////////////////////////////////////////////////////////////////////// +// PackRaw: pack given number of bytes onto the end of the data stream +void CFilePacker::PackRaw(const void* rawdata,u32 rawdatalen) +{ + u32 start=m_Data.size(); + m_Data.resize(m_Data.size()+rawdatalen); + memcpy(&m_Data[start],rawdata,rawdatalen); + +} + +//////////////////////////////////////////////////////////////////////////////////////// +// PackString: pack a string onto the end of the data stream +void CFilePacker::PackString(const CStr& str) +{ + u32 len=str.Length(); + PackRaw(&len,sizeof(len)); + PackRaw((const char*) str,len); +} + diff --git a/source/terrain/FilePacker.h b/source/terrain/FilePacker.h index 65f0f9bb67..140f751f88 100755 --- a/source/terrain/FilePacker.h +++ b/source/terrain/FilePacker.h @@ -1,43 +1,43 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Name: FilePacker.h -// Author: Rich Cross -// Contact: rich@wildfiregames.com -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef _FILEPACKER_H -#define _FILEPACKER_H - -#include -#include "res/res.h" -#include "CStr.h" - -//////////////////////////////////////////////////////////////////////////////////////// -// CFilePacker: class to assist in writing of binary files -class CFilePacker -{ -public: - // CFilePacker exceptions - class CError { }; - class CFileOpenError : public CError { }; - class CFileWriteError : public CError { }; - -public: - // constructor - CFilePacker(); - - // Write: write out any packed data to file, using given version and magic bits - void Write(const char* filename,u32 version,const char magicstr[4]); - - // PackRaw: pack given number of bytes onto the end of the data stream - void PackRaw(const void* rawdata,u32 rawdatalen); - // PackString: pack a string onto the end of the data stream - void PackString(const CStr& str); - -private: - // the output data stream built during pack operations - std::vector m_Data; -}; - +/////////////////////////////////////////////////////////////////////////////// +// +// Name: FilePacker.h +// Author: Rich Cross +// Contact: rich@wildfiregames.com +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _FILEPACKER_H +#define _FILEPACKER_H + +#include +#include "res/res.h" +#include "CStr.h" + +//////////////////////////////////////////////////////////////////////////////////////// +// CFilePacker: class to assist in writing of binary files +class CFilePacker +{ +public: + // CFilePacker exceptions + class CError { }; + class CFileOpenError : public CError { }; + class CFileWriteError : public CError { }; + +public: + // constructor + CFilePacker(); + + // Write: write out any packed data to file, using given version and magic bits + void Write(const char* filename,u32 version,const char magicstr[4]); + + // PackRaw: pack given number of bytes onto the end of the data stream + void PackRaw(const void* rawdata,u32 rawdatalen); + // PackString: pack a string onto the end of the data stream + void PackString(const CStr& str); + +private: + // the output data stream built during pack operations + std::vector m_Data; +}; + #endif \ No newline at end of file diff --git a/source/terrain/FileUnpacker.cpp b/source/terrain/FileUnpacker.cpp index 56bfcc7827..067006cd24 100755 --- a/source/terrain/FileUnpacker.cpp +++ b/source/terrain/FileUnpacker.cpp @@ -1,101 +1,101 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Name: FileUnpacker.cpp -// Author: Rich Cross -// Contact: rich@wildfiregames.com -// -/////////////////////////////////////////////////////////////////////////////// - -#include "FileUnpacker.h" -#include - -//////////////////////////////////////////////////////////////////////////////////////// -// CFileUnpacker constructor -CFileUnpacker::CFileUnpacker() : m_UnpackPos(0), m_Version(0) -{ -} - -//////////////////////////////////////////////////////////////////////////////////////// -// Read: open and read in given file, check magic bits against those given; throw -// variety of exceptions for missing files etc -void CFileUnpacker::Read(const char* filename,const char magicstr[4]) -{ - FILE* fp=fopen(filename,"rb"); - if (!fp) { - throw CFileOpenError(); - } - - // read magic bits - char magic[4]; - if (fread(magic,sizeof(char)*4,1,fp)!=1) { - fclose(fp); - throw CFileReadError(); - } - - // check we've got the right kind of file - if (strncmp(magic,magicstr,4)!=0) { - // nope .. - fclose(fp); - throw CFileTypeError(); - } - - // get version - if (fread(&m_Version,sizeof(m_Version),1,fp)!=1) { - fclose(fp); - throw CFileReadError(); - } - - // get size of anim data - u32 datasize; - if (fread(&datasize,sizeof(datasize),1,fp)!=1) { - fclose(fp); - throw CFileReadError(); - } - - // allocate memory and read in a big chunk of data - m_Data.resize(datasize); - if (fread(&m_Data[0],datasize,1,fp)!=1) { - fclose(fp); - throw CFileReadError(); - } - - // all done - fclose(fp); -} - -//////////////////////////////////////////////////////////////////////////////////////// -// UnpackRaw: unpack given number of bytes from the input stream into the given array -// - throws CFileEOFError if the end of the data stream is reached before the given -// number of bytes have been read -void CFileUnpacker::UnpackRaw(void* rawdata,u32 rawdatalen) -{ - // got enough data to unpack? - if (m_UnpackPos+rawdatalen<=m_Data.size()) { - // yes .. copy over - memcpy(rawdata,&m_Data[m_UnpackPos],rawdatalen); - // advance pointer - m_UnpackPos+=rawdatalen; - } else { - // nope - throw exception - throw CFileEOFError(); - } -} - -//////////////////////////////////////////////////////////////////////////////////////// -// UnpackString: unpack a string from the raw data stream -void CFileUnpacker::UnpackString(CStr& result) -{ - // get string length - u32 length; - UnpackRaw(&length,sizeof(length)); - - // read string into temporary buffer - std::vector tmp; - tmp.resize(length+1); - UnpackRaw(&tmp[0],length); - tmp[length]='\0'; - - // assign to output - result=&tmp[0]; -} - +/////////////////////////////////////////////////////////////////////////////// +// +// Name: FileUnpacker.cpp +// Author: Rich Cross +// Contact: rich@wildfiregames.com +// +/////////////////////////////////////////////////////////////////////////////// + +#include "FileUnpacker.h" +#include + +//////////////////////////////////////////////////////////////////////////////////////// +// CFileUnpacker constructor +CFileUnpacker::CFileUnpacker() : m_UnpackPos(0), m_Version(0) +{ +} + +//////////////////////////////////////////////////////////////////////////////////////// +// Read: open and read in given file, check magic bits against those given; throw +// variety of exceptions for missing files etc +void CFileUnpacker::Read(const char* filename,const char magicstr[4]) +{ + FILE* fp=fopen(filename,"rb"); + if (!fp) { + throw CFileOpenError(); + } + + // read magic bits + char magic[4]; + if (fread(magic,sizeof(char)*4,1,fp)!=1) { + fclose(fp); + throw CFileReadError(); + } + + // check we've got the right kind of file + if (strncmp(magic,magicstr,4)!=0) { + // nope .. + fclose(fp); + throw CFileTypeError(); + } + + // get version + if (fread(&m_Version,sizeof(m_Version),1,fp)!=1) { + fclose(fp); + throw CFileReadError(); + } + + // get size of anim data + u32 datasize; + if (fread(&datasize,sizeof(datasize),1,fp)!=1) { + fclose(fp); + throw CFileReadError(); + } + + // allocate memory and read in a big chunk of data + m_Data.resize(datasize); + if (fread(&m_Data[0],datasize,1,fp)!=1) { + fclose(fp); + throw CFileReadError(); + } + + // all done + fclose(fp); +} + +//////////////////////////////////////////////////////////////////////////////////////// +// UnpackRaw: unpack given number of bytes from the input stream into the given array +// - throws CFileEOFError if the end of the data stream is reached before the given +// number of bytes have been read +void CFileUnpacker::UnpackRaw(void* rawdata,u32 rawdatalen) +{ + // got enough data to unpack? + if (m_UnpackPos+rawdatalen<=m_Data.size()) { + // yes .. copy over + memcpy(rawdata,&m_Data[m_UnpackPos],rawdatalen); + // advance pointer + m_UnpackPos+=rawdatalen; + } else { + // nope - throw exception + throw CFileEOFError(); + } +} + +//////////////////////////////////////////////////////////////////////////////////////// +// UnpackString: unpack a string from the raw data stream +void CFileUnpacker::UnpackString(CStr& result) +{ + // get string length + u32 length; + UnpackRaw(&length,sizeof(length)); + + // read string into temporary buffer + std::vector tmp; + tmp.resize(length+1); + UnpackRaw(&tmp[0],length); + tmp[length]='\0'; + + // assign to output + result=&tmp[0]; +} + diff --git a/source/terrain/FileUnpacker.h b/source/terrain/FileUnpacker.h index 3a0d33f86f..8160000a76 100755 --- a/source/terrain/FileUnpacker.h +++ b/source/terrain/FileUnpacker.h @@ -1,56 +1,56 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Name: FileUnpacker.h -// Author: Rich Cross -// Contact: rich@wildfiregames.com -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef _FILEUNPACKER_H -#define _FILEUNPACKER_H - -#include -#include "res/res.h" -#include "CStr.h" - -//////////////////////////////////////////////////////////////////////////////// -// CFileUnpacker: class to assist in reading of binary files -class CFileUnpacker -{ -public: - // exceptions thrown by class - class CError { }; - class CFileTypeError : public CError { }; - class CFileVersionError : public CError { }; - class CFileOpenError : public CError { }; - class CFileReadError : public CError { }; - class CFileEOFError : public CError { }; - -public: - // constructor - CFileUnpacker(); - - // Read: open and read in given file, check magic bits against those given; throw - // variety of exceptions for missing files etc - void Read(const char* filename,const char magicstr[4]); - - // GetVersion: return stored file version - u32 GetVersion() const { return m_Version; } - - // UnpackRaw: unpack given number of bytes from the input stream into the given array - // - throws CFileEOFError if the end of the data stream is reached before the given - // number of bytes have been read - void UnpackRaw(void* rawdata,u32 rawdatalen); - // UnpackString: unpack a string from the raw data stream - void UnpackString(CStr& result); - -private: - // the input data stream read from file and used during unpack operations - std::vector m_Data; - // current unpack position in stream - u32 m_UnpackPos; - // version of the file currently being read - u32 m_Version; -}; - +/////////////////////////////////////////////////////////////////////////////// +// +// Name: FileUnpacker.h +// Author: Rich Cross +// Contact: rich@wildfiregames.com +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _FILEUNPACKER_H +#define _FILEUNPACKER_H + +#include +#include "res/res.h" +#include "CStr.h" + +//////////////////////////////////////////////////////////////////////////////// +// CFileUnpacker: class to assist in reading of binary files +class CFileUnpacker +{ +public: + // exceptions thrown by class + class CError { }; + class CFileTypeError : public CError { }; + class CFileVersionError : public CError { }; + class CFileOpenError : public CError { }; + class CFileReadError : public CError { }; + class CFileEOFError : public CError { }; + +public: + // constructor + CFileUnpacker(); + + // Read: open and read in given file, check magic bits against those given; throw + // variety of exceptions for missing files etc + void Read(const char* filename,const char magicstr[4]); + + // GetVersion: return stored file version + u32 GetVersion() const { return m_Version; } + + // UnpackRaw: unpack given number of bytes from the input stream into the given array + // - throws CFileEOFError if the end of the data stream is reached before the given + // number of bytes have been read + void UnpackRaw(void* rawdata,u32 rawdatalen); + // UnpackString: unpack a string from the raw data stream + void UnpackString(CStr& result); + +private: + // the input data stream read from file and used during unpack operations + std::vector m_Data; + // current unpack position in stream + u32 m_UnpackPos; + // version of the file currently being read + u32 m_Version; +}; + #endif \ No newline at end of file diff --git a/source/terrain/LightEnv.h b/source/terrain/LightEnv.h index 43f6d6b933..3a17efea14 100755 --- a/source/terrain/LightEnv.h +++ b/source/terrain/LightEnv.h @@ -1,47 +1,47 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Name: LightEnv.h -// Author: Rich Cross -// Contact: rich@wildfiregames.com -// -// Description: class describing current lighting environment - -// at the minute, this is only sunlight and ambient light -// parameters; will be extended to handle dynamic lights at some -// later date -// -/////////////////////////////////////////////////////////////////////////////// - - -#ifndef __LIGHTENV_H -#define __LIGHTENV_H - -#include "Color.h" -#include "Vector3D.h" - -/////////////////////////////////////////////////////////////////////////////// -// CLightEnv: description of a lighting environment - contains all the -// necessary parameters for representation of the lighting within a scenario -class CLightEnv -{ -public: - RGBColor m_SunColor; - float m_Elevation; - float m_Rotation; - RGBColor m_TerrainAmbientColor; - RGBColor m_UnitsAmbientColor; - - // get sun direction from a rotation and elevation; defined such that: - // 0 rotation = (0,0,1) - // PI/2 rotation = (-1,0,0) - // 0 elevation = (0,0,0) - // PI/2 elevation = (0,-1,0) - void GetSunDirection(CVector3D& lightdir) const { - lightdir.Y=-float(sin(m_Elevation)); - float scale=1+lightdir.Y; - lightdir.X=scale*float(sin(m_Rotation)); - lightdir.Z=scale*float(cos(m_Rotation)); - lightdir.Normalize(); - } -}; - -#endif +/////////////////////////////////////////////////////////////////////////////// +// +// Name: LightEnv.h +// Author: Rich Cross +// Contact: rich@wildfiregames.com +// +// Description: class describing current lighting environment - +// at the minute, this is only sunlight and ambient light +// parameters; will be extended to handle dynamic lights at some +// later date +// +/////////////////////////////////////////////////////////////////////////////// + + +#ifndef __LIGHTENV_H +#define __LIGHTENV_H + +#include "Color.h" +#include "Vector3D.h" + +/////////////////////////////////////////////////////////////////////////////// +// CLightEnv: description of a lighting environment - contains all the +// necessary parameters for representation of the lighting within a scenario +class CLightEnv +{ +public: + RGBColor m_SunColor; + float m_Elevation; + float m_Rotation; + RGBColor m_TerrainAmbientColor; + RGBColor m_UnitsAmbientColor; + + // get sun direction from a rotation and elevation; defined such that: + // 0 rotation = (0,0,1) + // PI/2 rotation = (-1,0,0) + // 0 elevation = (0,0,0) + // PI/2 elevation = (0,-1,0) + void GetSunDirection(CVector3D& lightdir) const { + lightdir.Y=-float(sin(m_Elevation)); + float scale=1+lightdir.Y; + lightdir.X=scale*float(sin(m_Rotation)); + lightdir.Z=scale*float(cos(m_Rotation)); + lightdir.Normalize(); + } +}; + +#endif diff --git a/source/terrain/MapIO.h b/source/terrain/MapIO.h index 139c9b217d..57d6e2e6cc 100755 --- a/source/terrain/MapIO.h +++ b/source/terrain/MapIO.h @@ -1,35 +1,35 @@ -#ifndef _MAPIO_H -#define _MAPIO_H - -class CMapIO -{ -public: - // current file version given to saved maps - enum { FILE_VERSION = 2 }; - // supported file read version - file with version less than this will be reject - enum { FILE_READ_VERSION = 1 }; - -#pragma pack(push, 1) - // description of a tile for I/O purposes - struct STileDesc { - // index into the texture array of first texture on tile - u16 m_Tex1Index; - // index into the texture array of second texture; (0xffff) if none - u16 m_Tex2Index; - // priority - u32 m_Priority; - }; - - // description of an object for I/O purposes - struct SObjectDesc { - // index into the object array - u16 m_ObjectIndex; - // transformation matrix - float m_Transform[16]; - }; -#pragma pack(pop) -}; - -#endif - - +#ifndef _MAPIO_H +#define _MAPIO_H + +class CMapIO +{ +public: + // current file version given to saved maps + enum { FILE_VERSION = 2 }; + // supported file read version - file with version less than this will be reject + enum { FILE_READ_VERSION = 1 }; + +#pragma pack(push, 1) + // description of a tile for I/O purposes + struct STileDesc { + // index into the texture array of first texture on tile + u16 m_Tex1Index; + // index into the texture array of second texture; (0xffff) if none + u16 m_Tex2Index; + // priority + u32 m_Priority; + }; + + // description of an object for I/O purposes + struct SObjectDesc { + // index into the object array + u16 m_ObjectIndex; + // transformation matrix + float m_Transform[16]; + }; +#pragma pack(pop) +}; + +#endif + + diff --git a/source/terrain/MapReader.cpp b/source/terrain/MapReader.cpp index 439b9e36a0..0d502880e1 100755 --- a/source/terrain/MapReader.cpp +++ b/source/terrain/MapReader.cpp @@ -1,171 +1,188 @@ -// switch off warnings before including stl files -#pragma warning(disable : 4786) // identifier truncated to 255 chars - -#include "Types.h" -#include "MapReader.h" -#include "UnitManager.h" -#include "ObjectManager.h" -#include "terrain/Model.h" -#include "terrain/Terrain.h" -#include "terrain/TextureManager.h" - -extern CTerrain g_Terrain; -extern CLightEnv g_LightEnv; - -#include -#include - - -// CMapReader constructor: nothing to do at the minute -CMapReader::CMapReader() -{ -} - -// LoadMap: try to load the map from given file; reinitialise the scene to new data if successful -void CMapReader::LoadMap(const char* filename) -{ - CFileUnpacker unpacker; - unpacker.Read(filename,"PSMP"); - - // check version - if (unpacker.GetVersion()=2) { - UnpackLightEnv(unpacker); - } -} - -// UnpackLightEnv: unpack lighting parameters from input stream -void CMapReader::UnpackLightEnv(CFileUnpacker& unpacker) -{ - unpacker.UnpackRaw(&m_LightEnv.m_SunColor,sizeof(m_LightEnv.m_SunColor)); - unpacker.UnpackRaw(&m_LightEnv.m_Elevation,sizeof(m_LightEnv.m_Elevation)); - unpacker.UnpackRaw(&m_LightEnv.m_Rotation,sizeof(m_LightEnv.m_Rotation)); - unpacker.UnpackRaw(&m_LightEnv.m_TerrainAmbientColor,sizeof(m_LightEnv.m_TerrainAmbientColor)); - unpacker.UnpackRaw(&m_LightEnv.m_UnitsAmbientColor,sizeof(m_LightEnv.m_UnitsAmbientColor)); -} - -// UnpackObjects: unpack world objects from input stream -void CMapReader::UnpackObjects(CFileUnpacker& unpacker) -{ - // unpack object types - u32 numObjTypes; - unpacker.UnpackRaw(&numObjTypes,sizeof(numObjTypes)); - m_ObjectTypes.resize(numObjTypes); - for (uint i=0;im_Handle; - } - m_TerrainTextures.push_back(handle); - } - - // unpack tile data - u32 tilesPerSide=m_MapSize*PATCH_SIZE; - m_Tiles.resize(SQR(tilesPerSide)); - unpacker.UnpackRaw(&m_Tiles[0],sizeof(STileDesc)*m_Tiles.size()); -} - -// ApplyData: take all the input data, and rebuild the scene from it -void CMapReader::ApplyData(CFileUnpacker& unpacker) -{ - // initialise the terrain - g_Terrain.Initialize(m_MapSize,&m_Heightmap[0]); - - // setup the textures on the minipatches - STileDesc* tileptr=&m_Tiles[0]; - for (u32 j=0;jm_MiniPatches[m][k]; - - mp.Tex1=m_TerrainTextures[tileptr->m_Tex1Index]; - mp.Tex1Priority=tileptr->m_Priority; - - tileptr++; - } - } - } - } - - // empty out existing units - g_UnitMan.DeleteAll(); - - // add new objects - for (u32 i=0;im_Model) { - // create new unit - CUnit* unit=new CUnit; - unit->m_Object=objentry; - unit->m_Model=objentry->m_Model ? objentry->m_Model->Clone() : 0; - - CMatrix3D transform; - memcpy(&transform._11,m_Objects[i].m_Transform,sizeof(float)*16); - unit->m_Model->SetTransform(transform); - - // add this unit to list of units stored in unit manager - g_UnitMan.AddUnit(unit); - } - } - - if (unpacker.GetVersion()>=2) { - // copy over the lighting parameters - g_LightEnv=m_LightEnv; - } -} +// switch off warnings before including stl files +#pragma warning(disable : 4786) // identifier truncated to 255 chars + +#include "Types.h" +#include "MapReader.h" +#include "UnitManager.h" +#include "ObjectManager.h" +#include "BaseEntity.h" +#include "BaseEntityCollection.h" +#include "EntityManager.h" + +#include "terrain/Model.h" +#include "terrain/Terrain.h" +#include "terrain/TextureManager.h" + +extern CTerrain g_Terrain; +extern CLightEnv g_LightEnv; + +#include +#include + + +// CMapReader constructor: nothing to do at the minute +CMapReader::CMapReader() +{ +} + +// LoadMap: try to load the map from given file; reinitialise the scene to new data if successful +void CMapReader::LoadMap(const char* filename) +{ + CFileUnpacker unpacker; + unpacker.Read(filename,"PSMP"); + + // check version + if (unpacker.GetVersion()=2) { + UnpackLightEnv(unpacker); + } +} + +// UnpackLightEnv: unpack lighting parameters from input stream +void CMapReader::UnpackLightEnv(CFileUnpacker& unpacker) +{ + unpacker.UnpackRaw(&m_LightEnv.m_SunColor,sizeof(m_LightEnv.m_SunColor)); + unpacker.UnpackRaw(&m_LightEnv.m_Elevation,sizeof(m_LightEnv.m_Elevation)); + unpacker.UnpackRaw(&m_LightEnv.m_Rotation,sizeof(m_LightEnv.m_Rotation)); + unpacker.UnpackRaw(&m_LightEnv.m_TerrainAmbientColor,sizeof(m_LightEnv.m_TerrainAmbientColor)); + unpacker.UnpackRaw(&m_LightEnv.m_UnitsAmbientColor,sizeof(m_LightEnv.m_UnitsAmbientColor)); +} + +// UnpackObjects: unpack world objects from input stream +void CMapReader::UnpackObjects(CFileUnpacker& unpacker) +{ + // unpack object types + u32 numObjTypes; + unpacker.UnpackRaw(&numObjTypes,sizeof(numObjTypes)); + m_ObjectTypes.resize(numObjTypes); + for (uint i=0;im_Handle; + } + m_TerrainTextures.push_back(handle); + } + + // unpack tile data + u32 tilesPerSide=m_MapSize*PATCH_SIZE; + m_Tiles.resize(SQR(tilesPerSide)); + unpacker.UnpackRaw(&m_Tiles[0],sizeof(STileDesc)*m_Tiles.size()); +} + +// ApplyData: take all the input data, and rebuild the scene from it +void CMapReader::ApplyData(CFileUnpacker& unpacker) +{ + // initialise the terrain + g_Terrain.Initialize(m_MapSize,&m_Heightmap[0]); + + // setup the textures on the minipatches + STileDesc* tileptr=&m_Tiles[0]; + for (u32 j=0;jm_MiniPatches[m][k]; + + mp.Tex1=m_TerrainTextures[tileptr->m_Tex1Index]; + mp.Tex1Priority=tileptr->m_Priority; + + tileptr++; + } + } + } + } + + // empty out existing units + g_UnitMan.DeleteAll(); + + // add new objects + for (u32 i=0;im_Model) { + // Hijack the standard actor instantiation for actors that correspond to entities. + // Not an ideal solution; we'll have to figure out a map format that can define entities seperately or somesuch. + + CBaseEntity* templateObject = g_EntityTemplateCollection.getTemplateByActor( objentry ); + if( templateObject ) + { + CVector3D orient = ((CMatrix3D*)m_Objects[i].m_Transform)->GetIn(); + CVector3D position = ((CMatrix3D*)m_Objects[i].m_Transform)->GetTranslation(); + + g_EntityManager.create( templateObject, position, atan2( orient.X, orient.Z ) ); + } + else + { + CUnit* unit=new CUnit; + unit->m_Object=objentry; + unit->m_Model=objentry->m_Model ? objentry->m_Model->Clone() : 0; + + CMatrix3D transform; + memcpy(&transform._11,m_Objects[i].m_Transform,sizeof(float)*16); + unit->m_Model->SetTransform(transform); + + // add this unit to list of units stored in unit manager + g_UnitMan.AddUnit(unit); + } + } + } + + if (unpacker.GetVersion()>=2) { + // copy over the lighting parameters + g_LightEnv=m_LightEnv; + } +} diff --git a/source/terrain/MapReader.h b/source/terrain/MapReader.h index 2a95202530..b7da34ace4 100755 --- a/source/terrain/MapReader.h +++ b/source/terrain/MapReader.h @@ -1,48 +1,48 @@ -#ifndef _MAPREADER_H -#define _MAPREADER_H - -#include "MapIO.h" -#include "CStr.h" -#include "terrain/LightEnv.h" -#include "terrain/FileUnpacker.h" - -class CObjectEntry; - -class CMapReader : public CMapIO -{ -public: - // constructor - CMapReader(); - // LoadMap: try to load the map from given file; reinitialise the scene to new data if successful - void LoadMap(const char* filename); - -private: - // UnpackMap: unpack the given data from the raw data stream into local variables - void UnpackMap(CFileUnpacker& unpacker); - // UnpackTerrain: unpack the terrain from the input stream - void UnpackTerrain(CFileUnpacker& unpacker); - // UnpackObjects: unpack world objects from the input stream - void UnpackObjects(CFileUnpacker& unpacker); - // UnpackObjects: unpack lighting parameters from the input stream - void UnpackLightEnv(CFileUnpacker& unpacker); - - // ApplyData: take all the input data, and rebuild the scene from it - void ApplyData(CFileUnpacker& unpacker); - - // size of map - u32 m_MapSize; - // heightmap for map - std::vector m_Heightmap; - // list of terrain textures used by map - std::vector m_TerrainTextures; - // tile descriptions for each tile - std::vector m_Tiles; - // list of object types used by map - std::vector m_ObjectTypes; - // descriptions for each objects - std::vector m_Objects; - // lightenv stored in file - CLightEnv m_LightEnv; -}; - +#ifndef _MAPREADER_H +#define _MAPREADER_H + +#include "MapIO.h" +#include "CStr.h" +#include "terrain/LightEnv.h" +#include "terrain/FileUnpacker.h" + +class CObjectEntry; + +class CMapReader : public CMapIO +{ +public: + // constructor + CMapReader(); + // LoadMap: try to load the map from given file; reinitialise the scene to new data if successful + void LoadMap(const char* filename); + +private: + // UnpackMap: unpack the given data from the raw data stream into local variables + void UnpackMap(CFileUnpacker& unpacker); + // UnpackTerrain: unpack the terrain from the input stream + void UnpackTerrain(CFileUnpacker& unpacker); + // UnpackObjects: unpack world objects from the input stream + void UnpackObjects(CFileUnpacker& unpacker); + // UnpackObjects: unpack lighting parameters from the input stream + void UnpackLightEnv(CFileUnpacker& unpacker); + + // ApplyData: take all the input data, and rebuild the scene from it + void ApplyData(CFileUnpacker& unpacker); + + // size of map + u32 m_MapSize; + // heightmap for map + std::vector m_Heightmap; + // list of terrain textures used by map + std::vector m_TerrainTextures; + // tile descriptions for each tile + std::vector m_Tiles; + // list of object types used by map + std::vector m_ObjectTypes; + // descriptions for each objects + std::vector m_Objects; + // lightenv stored in file + CLightEnv m_LightEnv; +}; + #endif \ No newline at end of file diff --git a/source/terrain/MapWriter.cpp b/source/terrain/MapWriter.cpp index bcffca513d..6998423288 100755 --- a/source/terrain/MapWriter.cpp +++ b/source/terrain/MapWriter.cpp @@ -1,226 +1,226 @@ -// switch off warnings before including stl files -#pragma warning(disable : 4786) // identifier truncated to 255 chars - -#include "Types.h" -#include "MapWriter.h" -#include "UnitManager.h" -#include "ObjectManager.h" -#include "terrain/Model.h" -#include "terrain/Terrain.h" -#include "terrain/LightEnv.h" -#include "terrain/TextureManager.h" - -extern CTerrain g_Terrain; -extern CLightEnv g_LightEnv; - -#include -#include - -/////////////////////////////////////////////////////////////////////////////////////////////////// -// CMapWriter constructor: nothing to do at the minute -CMapWriter::CMapWriter() -{ -} - -/////////////////////////////////////////////////////////////////////////////////////////////////// -// SaveMap: try to save the current map to the given file -void CMapWriter::SaveMap(const char* filename) -{ - CFilePacker packer; - - // build necessary data - PackMap(packer); - - // write it out - packer.Write(filename,FILE_VERSION,"PSMP"); -} - -/////////////////////////////////////////////////////////////////////////////////////////////////// -// GetHandleIndex: return the index of the given handle in the given list; or 0xffff if -// handle isn't in list -static u16 GetHandleIndex(const Handle handle,const std::vector& handles) -{ - for (uint i=0;i& objects) -{ - for (uint i=0;i& textures, - std::vector& tiles) -{ - // the list of all handles in use - std::vector handles; - - // resize tile array to required size - tiles.resize(SQR(g_Terrain.GetVerticesPerSide()-1)); - STileDesc* tileptr=&tiles[0]; - - // now iterate through all the tiles - u32 mapsize=g_Terrain.GetPatchesPerSide(); - for (u32 j=0;jm_MiniPatches[m][k]; - u16 index=u16(GetHandleIndex(mp.Tex1,handles)); - if (index==0xffff) { - index=handles.size(); - handles.push_back(mp.Tex1); - } - - tileptr->m_Tex1Index=index; - tileptr->m_Tex2Index=0xffff; - tileptr->m_Priority=mp.Tex1Priority; - tileptr++; - } - } - } - } - - // now find the texture names for each handle - for (uint i=0;im_Name; - } - textures.push_back(texturename); - } -} - -/////////////////////////////////////////////////////////////////////////////////////////////////// -// EnumObjects: build lists of object types used by map, and object descriptions for -// each object in the world -void CMapWriter::EnumObjects(std::vector& objectTypes,std::vector& objects) -{ - // the list of all object entries in use - std::vector objectsInUse; - - // resize object array to required size - const std::vector& units=g_UnitMan.GetUnits(); - objects.resize(units.size()); - SObjectDesc* objptr=&objects[0]; - - // now iterate through all the units - for (u32 j=0;jm_Object,objectsInUse)); - if (index==0xffff) { - index=objectsInUse.size(); - objectsInUse.push_back(unit->m_Object); - } - - objptr->m_ObjectIndex=index; - memcpy(objptr->m_Transform,&unit->m_Model->GetTransform()._11,sizeof(float)*16); - objptr++; - } - - // now build outgoing objectTypes array - for (uint i=0;im_Name); - } -} - -/////////////////////////////////////////////////////////////////////////////////////////////////// -// PackMap: pack the current world into a raw data stream -void CMapWriter::PackMap(CFilePacker& packer) -{ - // now pack everything up - PackTerrain(packer); - PackObjects(packer); - PackLightEnv(packer); -} - -/////////////////////////////////////////////////////////////////////////////////////////////////// -// PackLightEnv: pack lighting parameters onto the end of the output data stream -void CMapWriter::PackLightEnv(CFilePacker& packer) -{ - packer.PackRaw(&g_LightEnv.m_SunColor,sizeof(g_LightEnv.m_SunColor)); - packer.PackRaw(&g_LightEnv.m_Elevation,sizeof(g_LightEnv.m_Elevation)); - packer.PackRaw(&g_LightEnv.m_Rotation,sizeof(g_LightEnv.m_Rotation)); - packer.PackRaw(&g_LightEnv.m_TerrainAmbientColor,sizeof(g_LightEnv.m_TerrainAmbientColor)); - packer.PackRaw(&g_LightEnv.m_UnitsAmbientColor,sizeof(g_LightEnv.m_UnitsAmbientColor)); -} - -/////////////////////////////////////////////////////////////////////////////////////////////////// -// PackObjects: pack world objects onto the end of the output data stream -// - data: list of objects types used by map, list of object descriptions -void CMapWriter::PackObjects(CFilePacker& packer) -{ - // the list of object types used by map - std::vector objectTypes; - // descriptions of each object - std::vector objects; - - // build lists by scanning through the world - EnumObjects(objectTypes,objects); - - // pack object types - u32 numObjTypes=objectTypes.size(); - packer.PackRaw(&numObjTypes,sizeof(numObjTypes)); - for (uint i=0;i terrainTextures; - // descriptions of each tile - std::vector tiles; - - // build lists by scanning through the terrain - EnumTerrainTextures(terrainTextures,tiles); - - // pack texture names - u32 numTextures=terrainTextures.size(); - packer.PackRaw(&numTextures,sizeof(numTextures)); - for (uint i=0;i +#include + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// CMapWriter constructor: nothing to do at the minute +CMapWriter::CMapWriter() +{ +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// SaveMap: try to save the current map to the given file +void CMapWriter::SaveMap(const char* filename) +{ + CFilePacker packer; + + // build necessary data + PackMap(packer); + + // write it out + packer.Write(filename,FILE_VERSION,"PSMP"); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// GetHandleIndex: return the index of the given handle in the given list; or 0xffff if +// handle isn't in list +static u16 GetHandleIndex(const Handle handle,const std::vector& handles) +{ + for (uint i=0;i& objects) +{ + for (uint i=0;i& textures, + std::vector& tiles) +{ + // the list of all handles in use + std::vector handles; + + // resize tile array to required size + tiles.resize(SQR(g_Terrain.GetVerticesPerSide()-1)); + STileDesc* tileptr=&tiles[0]; + + // now iterate through all the tiles + u32 mapsize=g_Terrain.GetPatchesPerSide(); + for (u32 j=0;jm_MiniPatches[m][k]; + u16 index=u16(GetHandleIndex(mp.Tex1,handles)); + if (index==0xffff) { + index=handles.size(); + handles.push_back(mp.Tex1); + } + + tileptr->m_Tex1Index=index; + tileptr->m_Tex2Index=0xffff; + tileptr->m_Priority=mp.Tex1Priority; + tileptr++; + } + } + } + } + + // now find the texture names for each handle + for (uint i=0;im_Name; + } + textures.push_back(texturename); + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// EnumObjects: build lists of object types used by map, and object descriptions for +// each object in the world +void CMapWriter::EnumObjects(std::vector& objectTypes,std::vector& objects) +{ + // the list of all object entries in use + std::vector objectsInUse; + + // resize object array to required size + const std::vector& units=g_UnitMan.GetUnits(); + objects.resize(units.size()); + SObjectDesc* objptr=&objects[0]; + + // now iterate through all the units + for (u32 j=0;jm_Object,objectsInUse)); + if (index==0xffff) { + index=objectsInUse.size(); + objectsInUse.push_back(unit->m_Object); + } + + objptr->m_ObjectIndex=index; + memcpy(objptr->m_Transform,&unit->m_Model->GetTransform()._11,sizeof(float)*16); + objptr++; + } + + // now build outgoing objectTypes array + for (uint i=0;im_Name); + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// PackMap: pack the current world into a raw data stream +void CMapWriter::PackMap(CFilePacker& packer) +{ + // now pack everything up + PackTerrain(packer); + PackObjects(packer); + PackLightEnv(packer); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// PackLightEnv: pack lighting parameters onto the end of the output data stream +void CMapWriter::PackLightEnv(CFilePacker& packer) +{ + packer.PackRaw(&g_LightEnv.m_SunColor,sizeof(g_LightEnv.m_SunColor)); + packer.PackRaw(&g_LightEnv.m_Elevation,sizeof(g_LightEnv.m_Elevation)); + packer.PackRaw(&g_LightEnv.m_Rotation,sizeof(g_LightEnv.m_Rotation)); + packer.PackRaw(&g_LightEnv.m_TerrainAmbientColor,sizeof(g_LightEnv.m_TerrainAmbientColor)); + packer.PackRaw(&g_LightEnv.m_UnitsAmbientColor,sizeof(g_LightEnv.m_UnitsAmbientColor)); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// PackObjects: pack world objects onto the end of the output data stream +// - data: list of objects types used by map, list of object descriptions +void CMapWriter::PackObjects(CFilePacker& packer) +{ + // the list of object types used by map + std::vector objectTypes; + // descriptions of each object + std::vector objects; + + // build lists by scanning through the world + EnumObjects(objectTypes,objects); + + // pack object types + u32 numObjTypes=objectTypes.size(); + packer.PackRaw(&numObjTypes,sizeof(numObjTypes)); + for (uint i=0;i terrainTextures; + // descriptions of each tile + std::vector tiles; + + // build lists by scanning through the terrain + EnumTerrainTextures(terrainTextures,tiles); + + // pack texture names + u32 numTextures=terrainTextures.size(); + packer.PackRaw(&numTextures,sizeof(numTextures)); + for (uint i=0;i -#include "MapIO.h" -#include "CStr.h" -#include "terrain/FilePacker.h" - -class CMapWriter : public CMapIO -{ -public: - // constructor - CMapWriter(); - // SaveMap: try to save the current map to the given file - void SaveMap(const char* filename); - -private: - // PackMap: pack the current world into a raw data stream - void PackMap(CFilePacker& packer); - // PackTerrain: pack the terrain onto the end of the data stream - void PackTerrain(CFilePacker& packer); - // PackObjects: pack world objects onto the end of the output data stream - void PackObjects(CFilePacker& packer); - // PackLightEnv: pack lighting parameters onto the end of the output data stream - void PackLightEnv(CFilePacker& packer); - - // EnumTerrainTextures: build lists of textures used by map, and indices into this list - // for each tile on the terrain - void EnumTerrainTextures(std::vector& textures,std::vector& tileIndices); - - // EnumObjects: build lists of object types used by map, and object descriptions for - // each object in the world - void EnumObjects(std::vector& objectTypes,std::vector& objects); -}; - +#ifndef _MAPWRITER_H +#define _MAPWRITER_H + +#include +#include "MapIO.h" +#include "CStr.h" +#include "terrain/FilePacker.h" + +class CMapWriter : public CMapIO +{ +public: + // constructor + CMapWriter(); + // SaveMap: try to save the current map to the given file + void SaveMap(const char* filename); + +private: + // PackMap: pack the current world into a raw data stream + void PackMap(CFilePacker& packer); + // PackTerrain: pack the terrain onto the end of the data stream + void PackTerrain(CFilePacker& packer); + // PackObjects: pack world objects onto the end of the output data stream + void PackObjects(CFilePacker& packer); + // PackLightEnv: pack lighting parameters onto the end of the output data stream + void PackLightEnv(CFilePacker& packer); + + // EnumTerrainTextures: build lists of textures used by map, and indices into this list + // for each tile on the terrain + void EnumTerrainTextures(std::vector& textures,std::vector& tileIndices); + + // EnumObjects: build lists of object types used by map, and object descriptions for + // each object in the world + void EnumObjects(std::vector& objectTypes,std::vector& objects); +}; + #endif \ No newline at end of file diff --git a/source/terrain/MathUtil.h b/source/terrain/MathUtil.h index d56f64bded..15c7db7c7e 100755 --- a/source/terrain/MathUtil.h +++ b/source/terrain/MathUtil.h @@ -1,29 +1,29 @@ -//*********************************************************** -// -// Name: MathUtil.H -// Last Update: 28/1/02 -// Author: Poya Manouchehri -// -// Description: This file contains some maths related -// utility macros and fucntions. -// -//*********************************************************** - -#ifndef MATHUTIL_H -#define MATHUTIL_H - -#ifndef PI -#define PI 3.14159265358979323846f -#endif - -#define DEGTORAD(a) ((a) * (PI/180.0f)) -#define RADTODEG(a) ((a) * (180.0f/PI)) -#define SQR(x) ((x) * (x)) -//#define MAX(a,b) ((a < b) ? (b) : (a)) -//#define MIN(a,b) ((a < b) ? (a) : (b)) -#define MAX3(a,b,c) ( MAX (MAX(a,b), c) ) -#define ABS(a) ((a > 0) ? (a) : (-a)) - -//extern unsigned int F2DW (float f); - -#endif +//*********************************************************** +// +// Name: MathUtil.H +// Last Update: 28/1/02 +// Author: Poya Manouchehri +// +// Description: This file contains some maths related +// utility macros and fucntions. +// +//*********************************************************** + +#ifndef MATHUTIL_H +#define MATHUTIL_H + +#ifndef PI +#define PI 3.14159265358979323846f +#endif + +#define DEGTORAD(a) ((a) * (PI/180.0f)) +#define RADTODEG(a) ((a) * (180.0f/PI)) +#define SQR(x) ((x) * (x)) +//#define MAX(a,b) ((a < b) ? (b) : (a)) +//#define MIN(a,b) ((a < b) ? (a) : (b)) +#define MAX3(a,b,c) ( MAX (MAX(a,b), c) ) +#define ABS(a) ((a > 0) ? (a) : (-a)) + +//extern unsigned int F2DW (float f); + +#endif diff --git a/source/terrain/Matrix3D.cpp b/source/terrain/Matrix3D.cpp index b8ed364f5e..bc6dd54f3e 100755 --- a/source/terrain/Matrix3D.cpp +++ b/source/terrain/Matrix3D.cpp @@ -1,540 +1,540 @@ -//*********************************************************** -// -// Name: Matrix3D.Cpp -// Last Update: 31/1/02 -// Author: Poya Manouchehri -// -// Description: A Matrix class used for holding and -// manipulating transformation info. -// -//*********************************************************** - - -#include "Matrix3D.h" -#include "Quaternion.h" - -CMatrix3D::CMatrix3D () -{ -} - -CMatrix3D::CMatrix3D(float a11,float a12,float a13,float a14,float a21,float a22,float a23,float a24, - float a31,float a32,float a33,float a34,float a41,float a42,float a43,float a44) -{ - _11=a11; - _12=a12; - _13=a13; - _14=a14; - - _21=a21; - _22=a22; - _23=a23; - _24=a24; - - _31=a31; - _32=a32; - _33=a33; - _34=a34; - - _41=a41; - _42=a42; - _43=a43; - _44=a44; -} - -//Matrix multiplication -CMatrix3D CMatrix3D::operator * (const CMatrix3D &matrix) const -{ - CMatrix3D Temp; - - Temp._11 = _11*matrix._11 + - _12*matrix._21 + - _13*matrix._31 + - _14*matrix._41; - - Temp._12 = _11*matrix._12 + - _12*matrix._22 + - _13*matrix._32 + - _14*matrix._42; - - Temp._13 = _11*matrix._13 + - _12*matrix._23 + - _13*matrix._33 + - _14*matrix._43; - - Temp._14 = _11*matrix._14 + - _12*matrix._24 + - _13*matrix._34 + - _14*matrix._44; - - Temp._21 = _21*matrix._11 + - _22*matrix._21 + - _23*matrix._31 + - _24*matrix._41; - - Temp._22 = _21*matrix._12 + - _22*matrix._22 + - _23*matrix._32 + - _24*matrix._42; - - Temp._23 = _21*matrix._13 + - _22*matrix._23 + - _23*matrix._33 + - _24*matrix._43; - - Temp._24 = _21*matrix._14 + - _22*matrix._24 + - _23*matrix._34 + - _24*matrix._44; - - Temp._31 = _31*matrix._11 + - _32*matrix._21 + - _33*matrix._31 + - _34*matrix._41; - - Temp._32 = _31*matrix._12 + - _32*matrix._22 + - _33*matrix._32 + - _34*matrix._42; - - Temp._33 = _31*matrix._13 + - _32*matrix._23 + - _33*matrix._33 + - _34*matrix._43; - - Temp._34 = _31*matrix._14 + - _32*matrix._24 + - _33*matrix._34 + - _34*matrix._44; - - Temp._41 = _41*matrix._11 + - _42*matrix._21 + - _43*matrix._31 + - _44*matrix._41; - - Temp._42 = _41*matrix._12 + - _42*matrix._22 + - _43*matrix._32 + - _44*matrix._42; - - Temp._43 = _41*matrix._13 + - _42*matrix._23 + - _43*matrix._33 + - _44*matrix._43; - - Temp._44 = _41*matrix._14 + - _42*matrix._24 + - _43*matrix._34 + - _44*matrix._44; - - return Temp; -} - -//Matrix multiplication/assignment -CMatrix3D &CMatrix3D::operator *= (const CMatrix3D &matrix) -{ - CMatrix3D tmp=(*this) * matrix; - *this=tmp; - return *this; -} - -//Matrix scaling -CMatrix3D CMatrix3D::operator*(float f) const -{ - CMatrix3D tmp; - for (int i=0;i<16;i++) { - tmp._data[i]=_data[i]*f; - } - return tmp; -} - -//Matrix scaling/assignment -CMatrix3D& CMatrix3D::operator*=(float f) -{ - for (int i=0;i<16;i++) { - _data[i]*=f; - } - return *this; -} - -//Matrix addition -CMatrix3D CMatrix3D::operator+(const CMatrix3D& m) const -{ - CMatrix3D tmp; - for (int i=0;i<16;i++) { - tmp._data[i]=_data[i]+m._data[i]; - } - return tmp; -} - -//Matrix addition/assignment -CMatrix3D& CMatrix3D::operator+=(const CMatrix3D& m) -{ - for (int i=0;i<16;i++) { - _data[i]+=m._data[i]; - } - return *this; -} - -//Sets the identity matrix -void CMatrix3D::SetIdentity () -{ - _11=1.0f; _12=0.0f; _13=0.0f; _14=0.0f; - _21=0.0f; _22=1.0f; _23=0.0f; _24=0.0f; - _31=0.0f; _32=0.0f; _33=1.0f; _34=0.0f; - _41=0.0f; _42=0.0f; _43=0.0f; _44=1.0f; -} - -//Sets the zero matrix -void CMatrix3D::SetZero () -{ - _11=0.0f; _12=0.0f; _13=0.0f; _14=0.0f; - _21=0.0f; _22=0.0f; _23=0.0f; _24=0.0f; - _31=0.0f; _32=0.0f; _33=0.0f; _34=0.0f; - _41=0.0f; _42=0.0f; _43=0.0f; _44=0.0f; -} - -//The following clear the matrix and set the -//rotation of each of the 3 axes - -void CMatrix3D::SetXRotation (float angle) -{ - float Cos = cosf (angle); - float Sin = sinf (angle); - - _11=1.0f; _12=0.0f; _13=0.0f; _14=0.0f; - _21=0.0f; _22=Cos; _23=-Sin; _24=0.0f; - _31=0.0f; _32=Sin; _33=Cos; _34=0.0f; - _41=0.0f; _42=0.0f; _43=0.0f; _44=1.0f; -} - -void CMatrix3D::SetYRotation (float angle) -{ - float Cos = cosf (angle); - float Sin = sinf (angle); - - _11=Cos; _12=0.0f; _13=Sin; _14=0.0f; - _21=0.0f; _22=1.0f; _23=0.0f; _24=0.0f; - _31=-Sin; _32=0.0f; _33=Cos; _34=0.0f; - _41=0.0f; _42=0.0f; _43=0.0f; _44=1.0f; -} - -void CMatrix3D::SetZRotation (float angle) -{ - float Cos = cosf (angle); - float Sin = sinf (angle); - - _11=Cos; _12=-Sin; _13=0.0f; _14=0.0f; - _21=Sin; _22=Cos; _23=0.0f; _24=0.0f; - _31=0.0f; _32=0.0f; _33=1.0f; _34=0.0f; - _41=0.0f; _42=0.0f; _43=0.0f; _44=1.0f; -} - -//The following apply a rotation to the matrix -//about each of the axes; - -void CMatrix3D::RotateX (float angle) -{ - CMatrix3D Temp; - Temp.SetXRotation (angle); - - (*this) = Temp * (*this); -} - -void CMatrix3D::RotateY (float angle) -{ - CMatrix3D Temp; - Temp.SetYRotation (angle); - - (*this) = Temp * (*this); -} - -void CMatrix3D::RotateZ (float angle) -{ - CMatrix3D Temp; - Temp.SetZRotation (angle); - - (*this) = Temp * (*this); -} - -//Sets the translation of the matrix -void CMatrix3D::SetTranslation (float x, float y, float z) -{ - _11=1.0f; _12=0.0f; _13=0.0f; _14=x; - _21=0.0f; _22=1.0f; _23=0.0f; _24=y; - _31=0.0f; _32=0.0f; _33=1.0f; _34=z; - _41=0.0f; _42=0.0f; _43=0.0f; _44=1.0f; -} - -void CMatrix3D::SetTranslation(const CVector3D& vector) -{ - SetTranslation (vector.X, vector.Y, vector.Z); -} - -//Applies a translation to the matrix -void CMatrix3D::Translate (float x, float y, float z) -{ - CMatrix3D Temp; - Temp.SetTranslation (x, y, z); - - (*this) = Temp * (*this); -} - -void CMatrix3D::Translate (const CVector3D &vector) -{ - Translate (vector.X, vector.Y, vector.Z); -} - -CVector3D CMatrix3D::GetTranslation() const -{ - CVector3D Temp; - - Temp.X = _14; - Temp.Y = _24; - Temp.Z = _34; - - return Temp; -} - -//Clears and sets the scaling of the matrix -void CMatrix3D::SetScaling (float x_scale, float y_scale, float z_scale) -{ - _11=x_scale; _12=0.0f; _13=0.0f; _14=0.0f; - _21=0.0f; _22=y_scale; _23=0.0f; _24=0.0f; - _31=0.0f; _32=0.0f; _33=z_scale; _34=0.0f; - _41=0.0f; _42=0.0f; _43=0.0f; _44=1.0f; -} - -//Scales the matrix -void CMatrix3D::Scale (float x_scale, float y_scale, float z_scale) -{ - CMatrix3D Temp; - Temp.SetScaling (x_scale, y_scale, z_scale); - - (*this) = Temp * (*this); -} - -//Returns the transpose of the matrix. For orthonormal -//matrices, this is the same is the inverse matrix -void CMatrix3D::GetTranspose(CMatrix3D& result) const -{ - result._11 = _11; - result._21 = _12; - result._31 = _13; - result._41 = _14; - - result._12 = _21; - result._22 = _22; - result._32 = _23; - result._42 = _24; - - result._13 = _31; - result._23 = _32; - result._33 = _33; - result._43 = _34; - - result._14 = _41; - result._24 = _42; - result._34 = _43; - result._44 = _44; -} - - -//Get a vector which points to the left of the matrix -CVector3D CMatrix3D::GetLeft () const -{ - CVector3D Temp; - - Temp.X = -_11; - Temp.Y = -_21; - Temp.Z = -_31; - - return Temp; -} - -//Get a vector which points up from the matrix -CVector3D CMatrix3D::GetUp () const -{ - CVector3D Temp; - - Temp.X = _12; - Temp.Y = _22; - Temp.Z = _32; - - return Temp; -} - -//Get a vector which points to front of the matrix -CVector3D CMatrix3D::GetIn () const -{ - CVector3D Temp; - - Temp.X = _13; - Temp.Y = _23; - Temp.Z = _33; - - return Temp; -} - - -//Transform a vector by this matrix -CVector3D CMatrix3D::Transform (const CVector3D &vector) const -{ - CVector3D result; - Transform(vector,result); - return result; -} - -void CMatrix3D::Transform(const CVector3D& vector,CVector3D& result) const -{ - result.X = _11*vector.X + _12*vector.Y + _13*vector.Z + _14; - result.Y = _21*vector.X + _22*vector.Y + _23*vector.Z + _24; - result.Z = _31*vector.X + _32*vector.Y + _33*vector.Z + _34; -} - -//Transform a vector by this matrix -CVector4D CMatrix3D::Transform(const CVector4D &vector) const -{ - CVector4D result; - Transform(vector,result); - return result; -} - -void CMatrix3D::Transform(const CVector4D& vector,CVector4D& result) const -{ - result[0] = _11*vector[0] + _12*vector[1] + _13*vector[2] + _14*vector[3]; - result[1] = _21*vector[0] + _22*vector[1] + _23*vector[2] + _24*vector[3]; - result[2] = _31*vector[0] + _32*vector[1] + _33*vector[2] + _34*vector[3]; - result[3] = _41*vector[0] + _42*vector[1] + _43*vector[2] + _44*vector[3]; -} - -//Only rotate (not translate) a vector by this matrix -CVector3D CMatrix3D::Rotate (const CVector3D& vector) const -{ - CVector3D result; - Rotate(vector,result); - return result; -} - -void CMatrix3D::Rotate(const CVector3D& vector,CVector3D& result) const -{ - result.X = _11*vector.X + _12*vector.Y + _13*vector.Z; - result.Y = _21*vector.X + _22*vector.Y + _23*vector.Z; - result.Z = _31*vector.X + _32*vector.Y + _33*vector.Z; -} - -/////////////////////////////////////////////////////////////////////////////// -// RotateTransposed: rotate a vector by the transpose of this matrix -CVector3D CMatrix3D::RotateTransposed(const CVector3D& vector) const -{ - CVector3D result; - RotateTransposed(vector,result); - return result; -} - -/////////////////////////////////////////////////////////////////////////////// -// RotateTransposed: rotate a vector by the transpose of this matrix -void CMatrix3D::RotateTransposed(const CVector3D& vector,CVector3D& result) const -{ - result.X = _11*vector.X + _21*vector.Y + _31*vector.Z; - result.Y = _12*vector.X + _22*vector.Y + _32*vector.Z; - result.Z = _13*vector.X + _23*vector.Y + _33*vector.Z; -} - - -void CMatrix3D::GetInverse(CMatrix3D& dst) const -{ - float tmp[12]; // temp array for pairs - float src[16]; // array of transpose source matrix - float det; // determinant - - // transpose matrix - for (int i = 0; i < 4; ++i) { - src[i] = _data[i*4]; - src[i + 4] = _data[i*4 + 1]; - src[i + 8] = _data[i*4 + 2]; - src[i + 12] = _data[i*4 + 3]; - } - - // calculate pairs for first 8 elements (cofactors) - tmp[0] = src[10] * src[15]; - tmp[1] = src[11] * src[14]; - tmp[2] = src[9] * src[15]; - tmp[3] = src[11] * src[13]; - tmp[4] = src[9] * src[14]; - tmp[5] = src[10] * src[13]; - tmp[6] = src[8] * src[15]; - tmp[7] = src[11] * src[12]; - tmp[8] = src[8] * src[14]; - tmp[9] = src[10] * src[12]; - tmp[10] = src[8] * src[13]; - tmp[11] = src[9] * src[12]; - - // calculate first 8 elements (cofactors) - dst._data[0] = tmp[0]*src[5] + tmp[3]*src[6] + tmp[4]*src[7]; - dst._data[0] -= tmp[1]*src[5] + tmp[2]*src[6] + tmp[5]*src[7]; - dst._data[1] = tmp[1]*src[4] + tmp[6]*src[6] + tmp[9]*src[7]; - dst._data[1] -= tmp[0]*src[4] + tmp[7]*src[6] + tmp[8]*src[7]; - dst._data[2] = tmp[2]*src[4] + tmp[7]*src[5] + tmp[10]*src[7]; - dst._data[2] -= tmp[3]*src[4] + tmp[6]*src[5] + tmp[11]*src[7]; - dst._data[3] = tmp[5]*src[4] + tmp[8]*src[5] + tmp[11]*src[6]; - dst._data[3] -= tmp[4]*src[4] + tmp[9]*src[5] + tmp[10]*src[6]; - dst._data[4] = tmp[1]*src[1] + tmp[2]*src[2] + tmp[5]*src[3]; - dst._data[4] -= tmp[0]*src[1] + tmp[3]*src[2] + tmp[4]*src[3]; - dst._data[5] = tmp[0]*src[0] + tmp[7]*src[2] + tmp[8]*src[3]; - dst._data[5] -= tmp[1]*src[0] + tmp[6]*src[2] + tmp[9]*src[3]; - dst._data[6] = tmp[3]*src[0] + tmp[6]*src[1] + tmp[11]*src[3]; - dst._data[6] -= tmp[2]*src[0] + tmp[7]*src[1] + tmp[10]*src[3]; - dst._data[7] = tmp[4]*src[0] + tmp[9]*src[1] + tmp[10]*src[2]; - dst._data[7] -= tmp[5]*src[0] + tmp[8]*src[1] + tmp[11]*src[2]; - - // calculate pairs for second 8 elements (cofactors) - tmp[0] = src[2]*src[7]; - tmp[1] = src[3]*src[6]; - tmp[2] = src[1]*src[7]; - tmp[3] = src[3]*src[5]; - tmp[4] = src[1]*src[6]; - tmp[5] = src[2]*src[5]; - tmp[6] = src[0]*src[7]; - tmp[7] = src[3]*src[4]; - tmp[8] = src[0]*src[6]; - tmp[9] = src[2]*src[4]; - tmp[10] = src[0]*src[5]; - tmp[11] = src[1]*src[4]; - - // calculate second 8 elements (cofactors) - dst._data[8] = tmp[0]*src[13] + tmp[3]*src[14] + tmp[4]*src[15]; - dst._data[8] -= tmp[1]*src[13] + tmp[2]*src[14] + tmp[5]*src[15]; - dst._data[9] = tmp[1]*src[12] + tmp[6]*src[14] + tmp[9]*src[15]; - dst._data[9] -= tmp[0]*src[12] + tmp[7]*src[14] + tmp[8]*src[15]; - dst._data[10] = tmp[2]*src[12] + tmp[7]*src[13] + tmp[10]*src[15]; - dst._data[10]-= tmp[3]*src[12] + tmp[6]*src[13] + tmp[11]*src[15]; - dst._data[11] = tmp[5]*src[12] + tmp[8]*src[13] + tmp[11]*src[14]; - dst._data[11]-= tmp[4]*src[12] + tmp[9]*src[13] + tmp[10]*src[14]; - dst._data[12] = tmp[2]*src[10] + tmp[5]*src[11] + tmp[1]*src[9]; - dst._data[12]-= tmp[4]*src[11] + tmp[0]*src[9] + tmp[3]*src[10]; - dst._data[13] = tmp[8]*src[11] + tmp[0]*src[8] + tmp[7]*src[10]; - dst._data[13]-= tmp[6]*src[10] + tmp[9]*src[11] + tmp[1]*src[8]; - dst._data[14] = tmp[6]*src[9] + tmp[11]*src[11] + tmp[3]*src[8]; - dst._data[14]-= tmp[10]*src[11] + tmp[2]*src[8] + tmp[7]*src[9]; - dst._data[15] = tmp[10]*src[10] + tmp[4]*src[8] + tmp[9]*src[9]; - dst._data[15]-= tmp[8]*src[9] + tmp[11]*src[10] + tmp[5]*src[8]; - - // calculate matrix inverse - det=src[0]*dst._data[0]+src[1]*dst._data[1]+src[2]*dst._data[2]+src[3]*dst._data[3]; - det = 1/det; - for ( int j = 0; j < 16; j++) { - dst._data[j] *= det; - } -} - -void CMatrix3D::Rotate(const CQuaternion& quat) -{ - CMatrix3D rotationMatrix=quat.ToMatrix(); - (*this) = rotationMatrix * (*this); -} - -void CMatrix3D::SetRotation(const CQuaternion& quat) -{ - quat.ToMatrix(*this); -} - +//*********************************************************** +// +// Name: Matrix3D.Cpp +// Last Update: 31/1/02 +// Author: Poya Manouchehri +// +// Description: A Matrix class used for holding and +// manipulating transformation info. +// +//*********************************************************** + + +#include "Matrix3D.h" +#include "Quaternion.h" + +CMatrix3D::CMatrix3D () +{ +} + +CMatrix3D::CMatrix3D(float a11,float a12,float a13,float a14,float a21,float a22,float a23,float a24, + float a31,float a32,float a33,float a34,float a41,float a42,float a43,float a44) +{ + _11=a11; + _12=a12; + _13=a13; + _14=a14; + + _21=a21; + _22=a22; + _23=a23; + _24=a24; + + _31=a31; + _32=a32; + _33=a33; + _34=a34; + + _41=a41; + _42=a42; + _43=a43; + _44=a44; +} + +//Matrix multiplication +CMatrix3D CMatrix3D::operator * (const CMatrix3D &matrix) const +{ + CMatrix3D Temp; + + Temp._11 = _11*matrix._11 + + _12*matrix._21 + + _13*matrix._31 + + _14*matrix._41; + + Temp._12 = _11*matrix._12 + + _12*matrix._22 + + _13*matrix._32 + + _14*matrix._42; + + Temp._13 = _11*matrix._13 + + _12*matrix._23 + + _13*matrix._33 + + _14*matrix._43; + + Temp._14 = _11*matrix._14 + + _12*matrix._24 + + _13*matrix._34 + + _14*matrix._44; + + Temp._21 = _21*matrix._11 + + _22*matrix._21 + + _23*matrix._31 + + _24*matrix._41; + + Temp._22 = _21*matrix._12 + + _22*matrix._22 + + _23*matrix._32 + + _24*matrix._42; + + Temp._23 = _21*matrix._13 + + _22*matrix._23 + + _23*matrix._33 + + _24*matrix._43; + + Temp._24 = _21*matrix._14 + + _22*matrix._24 + + _23*matrix._34 + + _24*matrix._44; + + Temp._31 = _31*matrix._11 + + _32*matrix._21 + + _33*matrix._31 + + _34*matrix._41; + + Temp._32 = _31*matrix._12 + + _32*matrix._22 + + _33*matrix._32 + + _34*matrix._42; + + Temp._33 = _31*matrix._13 + + _32*matrix._23 + + _33*matrix._33 + + _34*matrix._43; + + Temp._34 = _31*matrix._14 + + _32*matrix._24 + + _33*matrix._34 + + _34*matrix._44; + + Temp._41 = _41*matrix._11 + + _42*matrix._21 + + _43*matrix._31 + + _44*matrix._41; + + Temp._42 = _41*matrix._12 + + _42*matrix._22 + + _43*matrix._32 + + _44*matrix._42; + + Temp._43 = _41*matrix._13 + + _42*matrix._23 + + _43*matrix._33 + + _44*matrix._43; + + Temp._44 = _41*matrix._14 + + _42*matrix._24 + + _43*matrix._34 + + _44*matrix._44; + + return Temp; +} + +//Matrix multiplication/assignment +CMatrix3D &CMatrix3D::operator *= (const CMatrix3D &matrix) +{ + CMatrix3D tmp=(*this) * matrix; + *this=tmp; + return *this; +} + +//Matrix scaling +CMatrix3D CMatrix3D::operator*(float f) const +{ + CMatrix3D tmp; + for (int i=0;i<16;i++) { + tmp._data[i]=_data[i]*f; + } + return tmp; +} + +//Matrix scaling/assignment +CMatrix3D& CMatrix3D::operator*=(float f) +{ + for (int i=0;i<16;i++) { + _data[i]*=f; + } + return *this; +} + +//Matrix addition +CMatrix3D CMatrix3D::operator+(const CMatrix3D& m) const +{ + CMatrix3D tmp; + for (int i=0;i<16;i++) { + tmp._data[i]=_data[i]+m._data[i]; + } + return tmp; +} + +//Matrix addition/assignment +CMatrix3D& CMatrix3D::operator+=(const CMatrix3D& m) +{ + for (int i=0;i<16;i++) { + _data[i]+=m._data[i]; + } + return *this; +} + +//Sets the identity matrix +void CMatrix3D::SetIdentity () +{ + _11=1.0f; _12=0.0f; _13=0.0f; _14=0.0f; + _21=0.0f; _22=1.0f; _23=0.0f; _24=0.0f; + _31=0.0f; _32=0.0f; _33=1.0f; _34=0.0f; + _41=0.0f; _42=0.0f; _43=0.0f; _44=1.0f; +} + +//Sets the zero matrix +void CMatrix3D::SetZero () +{ + _11=0.0f; _12=0.0f; _13=0.0f; _14=0.0f; + _21=0.0f; _22=0.0f; _23=0.0f; _24=0.0f; + _31=0.0f; _32=0.0f; _33=0.0f; _34=0.0f; + _41=0.0f; _42=0.0f; _43=0.0f; _44=0.0f; +} + +//The following clear the matrix and set the +//rotation of each of the 3 axes + +void CMatrix3D::SetXRotation (float angle) +{ + float Cos = cosf (angle); + float Sin = sinf (angle); + + _11=1.0f; _12=0.0f; _13=0.0f; _14=0.0f; + _21=0.0f; _22=Cos; _23=-Sin; _24=0.0f; + _31=0.0f; _32=Sin; _33=Cos; _34=0.0f; + _41=0.0f; _42=0.0f; _43=0.0f; _44=1.0f; +} + +void CMatrix3D::SetYRotation (float angle) +{ + float Cos = cosf (angle); + float Sin = sinf (angle); + + _11=Cos; _12=0.0f; _13=Sin; _14=0.0f; + _21=0.0f; _22=1.0f; _23=0.0f; _24=0.0f; + _31=-Sin; _32=0.0f; _33=Cos; _34=0.0f; + _41=0.0f; _42=0.0f; _43=0.0f; _44=1.0f; +} + +void CMatrix3D::SetZRotation (float angle) +{ + float Cos = cosf (angle); + float Sin = sinf (angle); + + _11=Cos; _12=-Sin; _13=0.0f; _14=0.0f; + _21=Sin; _22=Cos; _23=0.0f; _24=0.0f; + _31=0.0f; _32=0.0f; _33=1.0f; _34=0.0f; + _41=0.0f; _42=0.0f; _43=0.0f; _44=1.0f; +} + +//The following apply a rotation to the matrix +//about each of the axes; + +void CMatrix3D::RotateX (float angle) +{ + CMatrix3D Temp; + Temp.SetXRotation (angle); + + (*this) = Temp * (*this); +} + +void CMatrix3D::RotateY (float angle) +{ + CMatrix3D Temp; + Temp.SetYRotation (angle); + + (*this) = Temp * (*this); +} + +void CMatrix3D::RotateZ (float angle) +{ + CMatrix3D Temp; + Temp.SetZRotation (angle); + + (*this) = Temp * (*this); +} + +//Sets the translation of the matrix +void CMatrix3D::SetTranslation (float x, float y, float z) +{ + _11=1.0f; _12=0.0f; _13=0.0f; _14=x; + _21=0.0f; _22=1.0f; _23=0.0f; _24=y; + _31=0.0f; _32=0.0f; _33=1.0f; _34=z; + _41=0.0f; _42=0.0f; _43=0.0f; _44=1.0f; +} + +void CMatrix3D::SetTranslation(const CVector3D& vector) +{ + SetTranslation (vector.X, vector.Y, vector.Z); +} + +//Applies a translation to the matrix +void CMatrix3D::Translate (float x, float y, float z) +{ + CMatrix3D Temp; + Temp.SetTranslation (x, y, z); + + (*this) = Temp * (*this); +} + +void CMatrix3D::Translate (const CVector3D &vector) +{ + Translate (vector.X, vector.Y, vector.Z); +} + +CVector3D CMatrix3D::GetTranslation() const +{ + CVector3D Temp; + + Temp.X = _14; + Temp.Y = _24; + Temp.Z = _34; + + return Temp; +} + +//Clears and sets the scaling of the matrix +void CMatrix3D::SetScaling (float x_scale, float y_scale, float z_scale) +{ + _11=x_scale; _12=0.0f; _13=0.0f; _14=0.0f; + _21=0.0f; _22=y_scale; _23=0.0f; _24=0.0f; + _31=0.0f; _32=0.0f; _33=z_scale; _34=0.0f; + _41=0.0f; _42=0.0f; _43=0.0f; _44=1.0f; +} + +//Scales the matrix +void CMatrix3D::Scale (float x_scale, float y_scale, float z_scale) +{ + CMatrix3D Temp; + Temp.SetScaling (x_scale, y_scale, z_scale); + + (*this) = Temp * (*this); +} + +//Returns the transpose of the matrix. For orthonormal +//matrices, this is the same is the inverse matrix +void CMatrix3D::GetTranspose(CMatrix3D& result) const +{ + result._11 = _11; + result._21 = _12; + result._31 = _13; + result._41 = _14; + + result._12 = _21; + result._22 = _22; + result._32 = _23; + result._42 = _24; + + result._13 = _31; + result._23 = _32; + result._33 = _33; + result._43 = _34; + + result._14 = _41; + result._24 = _42; + result._34 = _43; + result._44 = _44; +} + + +//Get a vector which points to the left of the matrix +CVector3D CMatrix3D::GetLeft () const +{ + CVector3D Temp; + + Temp.X = -_11; + Temp.Y = -_21; + Temp.Z = -_31; + + return Temp; +} + +//Get a vector which points up from the matrix +CVector3D CMatrix3D::GetUp () const +{ + CVector3D Temp; + + Temp.X = _12; + Temp.Y = _22; + Temp.Z = _32; + + return Temp; +} + +//Get a vector which points to front of the matrix +CVector3D CMatrix3D::GetIn () const +{ + CVector3D Temp; + + Temp.X = _13; + Temp.Y = _23; + Temp.Z = _33; + + return Temp; +} + + +//Transform a vector by this matrix +CVector3D CMatrix3D::Transform (const CVector3D &vector) const +{ + CVector3D result; + Transform(vector,result); + return result; +} + +void CMatrix3D::Transform(const CVector3D& vector,CVector3D& result) const +{ + result.X = _11*vector.X + _12*vector.Y + _13*vector.Z + _14; + result.Y = _21*vector.X + _22*vector.Y + _23*vector.Z + _24; + result.Z = _31*vector.X + _32*vector.Y + _33*vector.Z + _34; +} + +//Transform a vector by this matrix +CVector4D CMatrix3D::Transform(const CVector4D &vector) const +{ + CVector4D result; + Transform(vector,result); + return result; +} + +void CMatrix3D::Transform(const CVector4D& vector,CVector4D& result) const +{ + result[0] = _11*vector[0] + _12*vector[1] + _13*vector[2] + _14*vector[3]; + result[1] = _21*vector[0] + _22*vector[1] + _23*vector[2] + _24*vector[3]; + result[2] = _31*vector[0] + _32*vector[1] + _33*vector[2] + _34*vector[3]; + result[3] = _41*vector[0] + _42*vector[1] + _43*vector[2] + _44*vector[3]; +} + +//Only rotate (not translate) a vector by this matrix +CVector3D CMatrix3D::Rotate (const CVector3D& vector) const +{ + CVector3D result; + Rotate(vector,result); + return result; +} + +void CMatrix3D::Rotate(const CVector3D& vector,CVector3D& result) const +{ + result.X = _11*vector.X + _12*vector.Y + _13*vector.Z; + result.Y = _21*vector.X + _22*vector.Y + _23*vector.Z; + result.Z = _31*vector.X + _32*vector.Y + _33*vector.Z; +} + +/////////////////////////////////////////////////////////////////////////////// +// RotateTransposed: rotate a vector by the transpose of this matrix +CVector3D CMatrix3D::RotateTransposed(const CVector3D& vector) const +{ + CVector3D result; + RotateTransposed(vector,result); + return result; +} + +/////////////////////////////////////////////////////////////////////////////// +// RotateTransposed: rotate a vector by the transpose of this matrix +void CMatrix3D::RotateTransposed(const CVector3D& vector,CVector3D& result) const +{ + result.X = _11*vector.X + _21*vector.Y + _31*vector.Z; + result.Y = _12*vector.X + _22*vector.Y + _32*vector.Z; + result.Z = _13*vector.X + _23*vector.Y + _33*vector.Z; +} + + +void CMatrix3D::GetInverse(CMatrix3D& dst) const +{ + float tmp[12]; // temp array for pairs + float src[16]; // array of transpose source matrix + float det; // determinant + + // transpose matrix + for (int i = 0; i < 4; ++i) { + src[i] = _data[i*4]; + src[i + 4] = _data[i*4 + 1]; + src[i + 8] = _data[i*4 + 2]; + src[i + 12] = _data[i*4 + 3]; + } + + // calculate pairs for first 8 elements (cofactors) + tmp[0] = src[10] * src[15]; + tmp[1] = src[11] * src[14]; + tmp[2] = src[9] * src[15]; + tmp[3] = src[11] * src[13]; + tmp[4] = src[9] * src[14]; + tmp[5] = src[10] * src[13]; + tmp[6] = src[8] * src[15]; + tmp[7] = src[11] * src[12]; + tmp[8] = src[8] * src[14]; + tmp[9] = src[10] * src[12]; + tmp[10] = src[8] * src[13]; + tmp[11] = src[9] * src[12]; + + // calculate first 8 elements (cofactors) + dst._data[0] = tmp[0]*src[5] + tmp[3]*src[6] + tmp[4]*src[7]; + dst._data[0] -= tmp[1]*src[5] + tmp[2]*src[6] + tmp[5]*src[7]; + dst._data[1] = tmp[1]*src[4] + tmp[6]*src[6] + tmp[9]*src[7]; + dst._data[1] -= tmp[0]*src[4] + tmp[7]*src[6] + tmp[8]*src[7]; + dst._data[2] = tmp[2]*src[4] + tmp[7]*src[5] + tmp[10]*src[7]; + dst._data[2] -= tmp[3]*src[4] + tmp[6]*src[5] + tmp[11]*src[7]; + dst._data[3] = tmp[5]*src[4] + tmp[8]*src[5] + tmp[11]*src[6]; + dst._data[3] -= tmp[4]*src[4] + tmp[9]*src[5] + tmp[10]*src[6]; + dst._data[4] = tmp[1]*src[1] + tmp[2]*src[2] + tmp[5]*src[3]; + dst._data[4] -= tmp[0]*src[1] + tmp[3]*src[2] + tmp[4]*src[3]; + dst._data[5] = tmp[0]*src[0] + tmp[7]*src[2] + tmp[8]*src[3]; + dst._data[5] -= tmp[1]*src[0] + tmp[6]*src[2] + tmp[9]*src[3]; + dst._data[6] = tmp[3]*src[0] + tmp[6]*src[1] + tmp[11]*src[3]; + dst._data[6] -= tmp[2]*src[0] + tmp[7]*src[1] + tmp[10]*src[3]; + dst._data[7] = tmp[4]*src[0] + tmp[9]*src[1] + tmp[10]*src[2]; + dst._data[7] -= tmp[5]*src[0] + tmp[8]*src[1] + tmp[11]*src[2]; + + // calculate pairs for second 8 elements (cofactors) + tmp[0] = src[2]*src[7]; + tmp[1] = src[3]*src[6]; + tmp[2] = src[1]*src[7]; + tmp[3] = src[3]*src[5]; + tmp[4] = src[1]*src[6]; + tmp[5] = src[2]*src[5]; + tmp[6] = src[0]*src[7]; + tmp[7] = src[3]*src[4]; + tmp[8] = src[0]*src[6]; + tmp[9] = src[2]*src[4]; + tmp[10] = src[0]*src[5]; + tmp[11] = src[1]*src[4]; + + // calculate second 8 elements (cofactors) + dst._data[8] = tmp[0]*src[13] + tmp[3]*src[14] + tmp[4]*src[15]; + dst._data[8] -= tmp[1]*src[13] + tmp[2]*src[14] + tmp[5]*src[15]; + dst._data[9] = tmp[1]*src[12] + tmp[6]*src[14] + tmp[9]*src[15]; + dst._data[9] -= tmp[0]*src[12] + tmp[7]*src[14] + tmp[8]*src[15]; + dst._data[10] = tmp[2]*src[12] + tmp[7]*src[13] + tmp[10]*src[15]; + dst._data[10]-= tmp[3]*src[12] + tmp[6]*src[13] + tmp[11]*src[15]; + dst._data[11] = tmp[5]*src[12] + tmp[8]*src[13] + tmp[11]*src[14]; + dst._data[11]-= tmp[4]*src[12] + tmp[9]*src[13] + tmp[10]*src[14]; + dst._data[12] = tmp[2]*src[10] + tmp[5]*src[11] + tmp[1]*src[9]; + dst._data[12]-= tmp[4]*src[11] + tmp[0]*src[9] + tmp[3]*src[10]; + dst._data[13] = tmp[8]*src[11] + tmp[0]*src[8] + tmp[7]*src[10]; + dst._data[13]-= tmp[6]*src[10] + tmp[9]*src[11] + tmp[1]*src[8]; + dst._data[14] = tmp[6]*src[9] + tmp[11]*src[11] + tmp[3]*src[8]; + dst._data[14]-= tmp[10]*src[11] + tmp[2]*src[8] + tmp[7]*src[9]; + dst._data[15] = tmp[10]*src[10] + tmp[4]*src[8] + tmp[9]*src[9]; + dst._data[15]-= tmp[8]*src[9] + tmp[11]*src[10] + tmp[5]*src[8]; + + // calculate matrix inverse + det=src[0]*dst._data[0]+src[1]*dst._data[1]+src[2]*dst._data[2]+src[3]*dst._data[3]; + det = 1/det; + for ( int j = 0; j < 16; j++) { + dst._data[j] *= det; + } +} + +void CMatrix3D::Rotate(const CQuaternion& quat) +{ + CMatrix3D rotationMatrix=quat.ToMatrix(); + (*this) = rotationMatrix * (*this); +} + +void CMatrix3D::SetRotation(const CQuaternion& quat) +{ + quat.ToMatrix(*this); +} + diff --git a/source/terrain/Matrix3D.h b/source/terrain/Matrix3D.h index b9057adf21..f3fcd0ad84 100755 --- a/source/terrain/Matrix3D.h +++ b/source/terrain/Matrix3D.h @@ -1,120 +1,120 @@ -#ifndef __MATRIX3D_H -#define __MATRIX3D_H - -#include -#include "Vector3D.h" -#include "Vector4D.h" - -class CQuaternion; - -///////////////////////////////////////////////////////////////////////// -// CMatrix3D: a 4x4 matrix class for common operations in 3D -class CMatrix3D -{ -public: - // the matrix data itself - accessible as either longhand names - // or via a flat array - union { - struct { - float _11, _21, _31, _41; - float _12, _22, _32, _42; - float _13, _23, _33, _43; - float _14, _24, _34, _44; - }; - float _data[16]; - }; - -public: - // constructors - CMatrix3D(); - CMatrix3D(float a11,float a12,float a13,float a14,float a21,float a22,float a23,float a24, - float a31,float a32,float a33,float a34,float a41,float a42,float a43,float a44); - - // accessors to individual elements of matrix - float& operator()(int col,int row) { - return _data[row*4+col]; - } - const float& operator()(int col,int row) const { - return _data[row*4+col]; - } - - // matrix multiplication - CMatrix3D operator*(const CMatrix3D &matrix) const; - // matrix multiplication/assignment - CMatrix3D& operator*=(const CMatrix3D &matrix); - // matrix scaling - CMatrix3D operator*(float f) const; - // matrix scaling/assignment - CMatrix3D& operator*=(float f); - // matrix addition - CMatrix3D operator+(const CMatrix3D &matrix) const; - // matrix addition/assignment - CMatrix3D& operator+=(const CMatrix3D &matrix); - - // set this matrix to the identity matrix - void SetIdentity(); - // set this matrix to the zero matrix - void SetZero(); - - // set this matrix to a rotation matrix for a rotation about X axis of given angle - void SetXRotation(float angle); - // set this matrix to a rotation matrix for a rotation about Y axis of given angle - void SetYRotation(float angle); - // set this matrix to a rotation matrix for a rotation about Z axis of given angle - void SetZRotation(float angle); - // set this matrix to a rotation described by given quaternion - void SetRotation(const CQuaternion& quat); - - // concatentate a rotation about the X axis onto this matrix - void RotateX(float angle); - // concatentate a rotation about the Y axis onto this matrix - void RotateY(float angle); - // concatentate a rotation about the Z axis onto this matrix - void RotateZ(float angle); - // concatentate a rotation described by given quaternion - void Rotate(const CQuaternion& quat); - - // set this matrix to given translation - void SetTranslation(float x, float y, float z); - void SetTranslation(const CVector3D& vector); - - // concatenate given translation onto this matrix - void Translate(float x, float y, float z); - void Translate(const CVector3D& vector); - - // set this matrix to the given scaling matrix - void SetScaling(float x_scale, float y_scale, float z_scale); - - // concatentate given scaling matrix onto this matrix - void Scale(float x_scale, float y_scale, float z_scale); - - // calculate the inverse of this matrix, store in dst - void GetInverse(CMatrix3D& dst) const; - - // calculate the transpose of this matrix, store in dst - void GetTranspose(CMatrix3D& dst) const; - - // return the translation component of this matrix - CVector3D GetTranslation() const; - // return left vector, derived from rotation - CVector3D GetLeft() const; - // return up vector, derived from rotation - CVector3D GetUp() const; - // return forward vector, derived from rotation - CVector3D GetIn() const; - - // transform a 3D vector by this matrix - void Transform(const CVector3D &vector,CVector3D& result) const; - CVector3D Transform(const CVector3D &vector) const; - // transform a 4D vector by this matrix - void Transform(const CVector4D &vector,CVector4D& result) const; - CVector4D Transform(const CVector4D &vector) const; - // rotate a vector by this matrix - void Rotate(const CVector3D& vector,CVector3D& result) const; - CVector3D Rotate(const CVector3D& vector) const; - // rotate a vector by the transpose of this matrix - void RotateTransposed(const CVector3D& vector,CVector3D& result) const; - CVector3D RotateTransposed(const CVector3D& vector) const; -}; - -#endif +#ifndef __MATRIX3D_H +#define __MATRIX3D_H + +#include +#include "Vector3D.h" +#include "Vector4D.h" + +class CQuaternion; + +///////////////////////////////////////////////////////////////////////// +// CMatrix3D: a 4x4 matrix class for common operations in 3D +class CMatrix3D +{ +public: + // the matrix data itself - accessible as either longhand names + // or via a flat array + union { + struct { + float _11, _21, _31, _41; + float _12, _22, _32, _42; + float _13, _23, _33, _43; + float _14, _24, _34, _44; + }; + float _data[16]; + }; + +public: + // constructors + CMatrix3D(); + CMatrix3D(float a11,float a12,float a13,float a14,float a21,float a22,float a23,float a24, + float a31,float a32,float a33,float a34,float a41,float a42,float a43,float a44); + + // accessors to individual elements of matrix + float& operator()(int col,int row) { + return _data[row*4+col]; + } + const float& operator()(int col,int row) const { + return _data[row*4+col]; + } + + // matrix multiplication + CMatrix3D operator*(const CMatrix3D &matrix) const; + // matrix multiplication/assignment + CMatrix3D& operator*=(const CMatrix3D &matrix); + // matrix scaling + CMatrix3D operator*(float f) const; + // matrix scaling/assignment + CMatrix3D& operator*=(float f); + // matrix addition + CMatrix3D operator+(const CMatrix3D &matrix) const; + // matrix addition/assignment + CMatrix3D& operator+=(const CMatrix3D &matrix); + + // set this matrix to the identity matrix + void SetIdentity(); + // set this matrix to the zero matrix + void SetZero(); + + // set this matrix to a rotation matrix for a rotation about X axis of given angle + void SetXRotation(float angle); + // set this matrix to a rotation matrix for a rotation about Y axis of given angle + void SetYRotation(float angle); + // set this matrix to a rotation matrix for a rotation about Z axis of given angle + void SetZRotation(float angle); + // set this matrix to a rotation described by given quaternion + void SetRotation(const CQuaternion& quat); + + // concatentate a rotation about the X axis onto this matrix + void RotateX(float angle); + // concatentate a rotation about the Y axis onto this matrix + void RotateY(float angle); + // concatentate a rotation about the Z axis onto this matrix + void RotateZ(float angle); + // concatentate a rotation described by given quaternion + void Rotate(const CQuaternion& quat); + + // set this matrix to given translation + void SetTranslation(float x, float y, float z); + void SetTranslation(const CVector3D& vector); + + // concatenate given translation onto this matrix + void Translate(float x, float y, float z); + void Translate(const CVector3D& vector); + + // set this matrix to the given scaling matrix + void SetScaling(float x_scale, float y_scale, float z_scale); + + // concatentate given scaling matrix onto this matrix + void Scale(float x_scale, float y_scale, float z_scale); + + // calculate the inverse of this matrix, store in dst + void GetInverse(CMatrix3D& dst) const; + + // calculate the transpose of this matrix, store in dst + void GetTranspose(CMatrix3D& dst) const; + + // return the translation component of this matrix + CVector3D GetTranslation() const; + // return left vector, derived from rotation + CVector3D GetLeft() const; + // return up vector, derived from rotation + CVector3D GetUp() const; + // return forward vector, derived from rotation + CVector3D GetIn() const; + + // transform a 3D vector by this matrix + void Transform(const CVector3D &vector,CVector3D& result) const; + CVector3D Transform(const CVector3D &vector) const; + // transform a 4D vector by this matrix + void Transform(const CVector4D &vector,CVector4D& result) const; + CVector4D Transform(const CVector4D &vector) const; + // rotate a vector by this matrix + void Rotate(const CVector3D& vector,CVector3D& result) const; + CVector3D Rotate(const CVector3D& vector) const; + // rotate a vector by the transpose of this matrix + void RotateTransposed(const CVector3D& vector,CVector3D& result) const; + CVector3D RotateTransposed(const CVector3D& vector) const; +}; + +#endif diff --git a/source/terrain/MiniPatch.cpp b/source/terrain/MiniPatch.cpp index 5fd1f77d14..333538599b 100755 --- a/source/terrain/MiniPatch.cpp +++ b/source/terrain/MiniPatch.cpp @@ -1,34 +1,34 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Name: MiniPatch.h -// Author: Rich Cross -// Contact: rich@wildfiregames.com -// -/////////////////////////////////////////////////////////////////////////////// - -#include "MiniPatch.h" -#include "Patch.h" - -/////////////////////////////////////////////////////////////////////////////// -// Constructor -CMiniPatch::CMiniPatch() : Tex1(0), Tex1Priority(0), m_Parent(0) -{ -} - -/////////////////////////////////////////////////////////////////////////////// -// Destructor -CMiniPatch::~CMiniPatch() -{ -} - - -/////////////////////////////////////////////////////////////////////////////// -// GetTileIndex: get the index of this tile in the root terrain object; -// on return, parameters x,y contain index in [0,MapSize) -void CMiniPatch::GetTileIndex(u32& x,u32& z) -{ - u32 tindex=this-&m_Parent->m_MiniPatches[0][0]; - x=(m_Parent->m_X*16)+tindex%16; - z=(m_Parent->m_Z*16)+tindex/16; -} - +/////////////////////////////////////////////////////////////////////////////// +// +// Name: MiniPatch.h +// Author: Rich Cross +// Contact: rich@wildfiregames.com +// +/////////////////////////////////////////////////////////////////////////////// + +#include "MiniPatch.h" +#include "Patch.h" + +/////////////////////////////////////////////////////////////////////////////// +// Constructor +CMiniPatch::CMiniPatch() : Tex1(0), Tex1Priority(0), m_Parent(0) +{ +} + +/////////////////////////////////////////////////////////////////////////////// +// Destructor +CMiniPatch::~CMiniPatch() +{ +} + + +/////////////////////////////////////////////////////////////////////////////// +// GetTileIndex: get the index of this tile in the root terrain object; +// on return, parameters x,y contain index in [0,MapSize) +void CMiniPatch::GetTileIndex(u32& x,u32& z) +{ + u32 tindex=this-&m_Parent->m_MiniPatches[0][0]; + x=(m_Parent->m_X*16)+tindex%16; + z=(m_Parent->m_Z*16)+tindex/16; +} + diff --git a/source/terrain/MiniPatch.h b/source/terrain/MiniPatch.h index 8b906262fd..36a3eb7fa3 100755 --- a/source/terrain/MiniPatch.h +++ b/source/terrain/MiniPatch.h @@ -1,39 +1,39 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Name: MiniPatch.h -// Author: Rich Cross -// Contact: rich@wildfiregames.com -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef _MINIPATCH_H -#define _MINIPATCH_H - -#include "res/res.h" - -class CPatch; - -/////////////////////////////////////////////////////////////////////////////// -// CMiniPatch: definition of a single terrain tile -class CMiniPatch -{ -public: - // constructor - CMiniPatch(); - // destructor - ~CMiniPatch(); - - // get the index of this tile in the root terrain object; x,y in [0,MapSize) - void GetTileIndex(u32& x,u32& z); - -public: - // texture applied to tile - Handle Tex1; - // 'priority' of the texture - determines drawing order of terrain textures - int Tex1Priority; - // parent patch - CPatch* m_Parent; -}; - - -#endif +/////////////////////////////////////////////////////////////////////////////// +// +// Name: MiniPatch.h +// Author: Rich Cross +// Contact: rich@wildfiregames.com +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _MINIPATCH_H +#define _MINIPATCH_H + +#include "res/res.h" + +class CPatch; + +/////////////////////////////////////////////////////////////////////////////// +// CMiniPatch: definition of a single terrain tile +class CMiniPatch +{ +public: + // constructor + CMiniPatch(); + // destructor + ~CMiniPatch(); + + // get the index of this tile in the root terrain object; x,y in [0,MapSize) + void GetTileIndex(u32& x,u32& z); + +public: + // texture applied to tile + Handle Tex1; + // 'priority' of the texture - determines drawing order of terrain textures + int Tex1Priority; + // parent patch + CPatch* m_Parent; +}; + + +#endif diff --git a/source/terrain/Model.cpp b/source/terrain/Model.cpp index c17e5afdff..752af76183 100755 --- a/source/terrain/Model.cpp +++ b/source/terrain/Model.cpp @@ -1,169 +1,169 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Name: Model.cpp -// Author: Rich Cross -// Contact: rich@wildfiregames.com -// -/////////////////////////////////////////////////////////////////////////////// - -#include "Model.h" -#include "Quaternion.h" -#include "Bound.h" - -/////////////////////////////////////////////////////////////////////////////// -// Constructor -CModel::CModel() - : m_pModelDef(0), m_Anim(0), m_AnimTime(0), - m_BoneMatrices(0), m_InvBoneMatrices(0) -{ -} - -/////////////////////////////////////////////////////////////////////////////// -// Destructor -CModel::~CModel() -{ - ReleaseData(); -} - -/////////////////////////////////////////////////////////////////////////////// -// ReleaseData: delete anything allocated by the model -void CModel::ReleaseData() -{ - delete[] m_BoneMatrices; - delete[] m_InvBoneMatrices; -} - -/////////////////////////////////////////////////////////////////////////////// -// InitModel: setup model from given geometry -bool CModel::InitModel(CModelDef* modeldef) -{ - // clean up any existing data first - ReleaseData(); - - m_pModelDef = modeldef; - - u32 numBones=modeldef->GetNumBones(); - if (numBones>0) { - // allocate matrices for bone transformations - m_BoneMatrices=new CMatrix3D[numBones]; - m_InvBoneMatrices=new CMatrix3D[numBones]; - // store default pose until animation assigned - CBoneState* defpose=modeldef->GetBones(); - for (uint i=0;iGetNumVertices(); - SModelVertex* verts=m_pModelDef->GetVertices(); - - u32 numbones=m_pModelDef->GetNumBones(); - if (numbones>0) { - // Boned object: tricky to get an ideal bound - for the minute, just use the bound of - // the reference pose. There's no guarantee that when animations are applied to the - // model, the bounds will be within this bound - ideally, we want the bound of the - // object to be the union of the bounds of the model for each animation - for (int i=0;iGetBones()); - m_Bounds+=m_Transform.Transform(tmp); - } - } else { - for (int i=0;iGetDuration(); - if (m_AnimTime>duration) { - m_AnimTime=(float) fmod(m_AnimTime,duration); - } - - m_Anim->BuildBoneMatrices(m_AnimTime,m_BoneMatrices); - for (int i=0;iGetNumBones();i++) { - m_BoneMatrices[i].GetInverse(m_InvBoneMatrices[i]); - } - - if (m_RenderData) m_RenderData->m_UpdateFlags|=RENDERDATA_UPDATE_VERTICES; - } -} - -///////////////////////////////////////////////////////////////////////////////////// -// SetAnimation: set the given animation as the current animation on this model; -// return false on error, else true -bool CModel::SetAnimation(CSkeletonAnim* anim) -{ - if (anim) { - if (!m_BoneMatrices) { - // not boned, can't animate - return false; - } - - if (anim->GetNumKeys()!=m_pModelDef->GetNumBones()) { - // mismatch between models skeleton and animations skeleton - return false; - } - } - - m_AnimTime=0; - m_Anim=anim; - - return true; -} - -///////////////////////////////////////////////////////////////////////////////////// -// Clone: return a clone of this model -CModel* CModel::Clone() const -{ - CModel* clone=new CModel; - clone->InitModel(m_pModelDef); - clone->SetTexture(m_Texture); - clone->SetAnimation(m_Anim); - return clone; +/////////////////////////////////////////////////////////////////////////////// +// +// Name: Model.cpp +// Author: Rich Cross +// Contact: rich@wildfiregames.com +// +/////////////////////////////////////////////////////////////////////////////// + +#include "Model.h" +#include "Quaternion.h" +#include "Bound.h" + +/////////////////////////////////////////////////////////////////////////////// +// Constructor +CModel::CModel() + : m_pModelDef(0), m_Anim(0), m_AnimTime(0), + m_BoneMatrices(0), m_InvBoneMatrices(0) +{ +} + +/////////////////////////////////////////////////////////////////////////////// +// Destructor +CModel::~CModel() +{ + ReleaseData(); +} + +/////////////////////////////////////////////////////////////////////////////// +// ReleaseData: delete anything allocated by the model +void CModel::ReleaseData() +{ + delete[] m_BoneMatrices; + delete[] m_InvBoneMatrices; +} + +/////////////////////////////////////////////////////////////////////////////// +// InitModel: setup model from given geometry +bool CModel::InitModel(CModelDef* modeldef) +{ + // clean up any existing data first + ReleaseData(); + + m_pModelDef = modeldef; + + u32 numBones=modeldef->GetNumBones(); + if (numBones>0) { + // allocate matrices for bone transformations + m_BoneMatrices=new CMatrix3D[numBones]; + m_InvBoneMatrices=new CMatrix3D[numBones]; + // store default pose until animation assigned + CBoneState* defpose=modeldef->GetBones(); + for (uint i=0;iGetNumVertices(); + SModelVertex* verts=m_pModelDef->GetVertices(); + + u32 numbones=m_pModelDef->GetNumBones(); + if (numbones>0) { + // Boned object: tricky to get an ideal bound - for the minute, just use the bound of + // the reference pose. There's no guarantee that when animations are applied to the + // model, the bounds will be within this bound - ideally, we want the bound of the + // object to be the union of the bounds of the model for each animation + for (int i=0;iGetBones()); + m_Bounds+=m_Transform.Transform(tmp); + } + } else { + for (int i=0;iGetDuration(); + if (m_AnimTime>duration) { + m_AnimTime=(float) fmod(m_AnimTime,duration); + } + + m_Anim->BuildBoneMatrices(m_AnimTime,m_BoneMatrices); + for (int i=0;iGetNumBones();i++) { + m_BoneMatrices[i].GetInverse(m_InvBoneMatrices[i]); + } + + if (m_RenderData) m_RenderData->m_UpdateFlags|=RENDERDATA_UPDATE_VERTICES; + } +} + +///////////////////////////////////////////////////////////////////////////////////// +// SetAnimation: set the given animation as the current animation on this model; +// return false on error, else true +bool CModel::SetAnimation(CSkeletonAnim* anim) +{ + if (anim) { + if (!m_BoneMatrices) { + // not boned, can't animate + return false; + } + + if (anim->GetNumKeys()!=m_pModelDef->GetNumBones()) { + // mismatch between models skeleton and animations skeleton + return false; + } + } + + m_AnimTime=0; + m_Anim=anim; + + return true; +} + +///////////////////////////////////////////////////////////////////////////////////// +// Clone: return a clone of this model +CModel* CModel::Clone() const +{ + CModel* clone=new CModel; + clone->InitModel(m_pModelDef); + clone->SetTexture(m_Texture); + clone->SetAnimation(m_Anim); + return clone; } \ No newline at end of file diff --git a/source/terrain/Model.h b/source/terrain/Model.h index 22e2782b18..e29462df7e 100755 --- a/source/terrain/Model.h +++ b/source/terrain/Model.h @@ -1,74 +1,74 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Name: Model.cpp -// Author: Rich Cross -// Contact: rich@wildfiregames.com -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef _MODEL_H -#define _MODEL_H - -#include "Texture.h" -#include "ModelDef.h" -#include "RenderableObject.h" - - -/////////////////////////////////////////////////////////////////////////////// -// CModel: basically, a mesh object - holds the texturing and skinning -// information for a model in game -class CModel : public CRenderableObject -{ -public: - // constructor - CModel(); - // destructor - ~CModel(); - - // setup model from given geometry - bool InitModel(CModelDef *modeldef); - // calculate the world space bounds of this model - void CalcBounds(); - // update this model's state; 'time' is the time since the last update, in MS - void Update(float time); - - // get the model's geometry data - CModelDef *GetModelDef() { return m_pModelDef; } - - // set the model's texture - void SetTexture(const CTexture& tex) { m_Texture=tex; } - // get the model's texture - CTexture* GetTexture() { return &m_Texture; } - - // set the given animation as the current animation on this model - bool SetAnimation(CSkeletonAnim* anim); - // get the currently playing animation, if any - CSkeletonAnim* GetAnimation() { return m_Anim; } - - // return the models bone matrices - const CMatrix3D* GetBoneMatrices() { return m_BoneMatrices; } - // return the models inverted bone matrices - const CMatrix3D* GetInvBoneMatrices() { return m_InvBoneMatrices; } - - // return a clone of this model - CModel* Clone() const; - -private: - // delete anything allocated by the model - void ReleaseData(); - - // texture used by model - CTexture m_Texture; - // pointer to the model's raw 3d data - CModelDef* m_pModelDef; - // animation currently playing on this model, if any - CSkeletonAnim* m_Anim; - // time (in MS) into the current animation - float m_AnimTime; - // current state of all bones on this model; null if associated modeldef isn't skeletal - CMatrix3D* m_BoneMatrices; - // inverse of all the above matrices - CMatrix3D* m_InvBoneMatrices; -}; - -#endif +/////////////////////////////////////////////////////////////////////////////// +// +// Name: Model.cpp +// Author: Rich Cross +// Contact: rich@wildfiregames.com +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _MODEL_H +#define _MODEL_H + +#include "Texture.h" +#include "ModelDef.h" +#include "RenderableObject.h" + + +/////////////////////////////////////////////////////////////////////////////// +// CModel: basically, a mesh object - holds the texturing and skinning +// information for a model in game +class CModel : public CRenderableObject +{ +public: + // constructor + CModel(); + // destructor + ~CModel(); + + // setup model from given geometry + bool InitModel(CModelDef *modeldef); + // calculate the world space bounds of this model + void CalcBounds(); + // update this model's state; 'time' is the time since the last update, in MS + void Update(float time); + + // get the model's geometry data + CModelDef *GetModelDef() { return m_pModelDef; } + + // set the model's texture + void SetTexture(const CTexture& tex) { m_Texture=tex; } + // get the model's texture + CTexture* GetTexture() { return &m_Texture; } + + // set the given animation as the current animation on this model + bool SetAnimation(CSkeletonAnim* anim); + // get the currently playing animation, if any + CSkeletonAnim* GetAnimation() { return m_Anim; } + + // return the models bone matrices + const CMatrix3D* GetBoneMatrices() { return m_BoneMatrices; } + // return the models inverted bone matrices + const CMatrix3D* GetInvBoneMatrices() { return m_InvBoneMatrices; } + + // return a clone of this model + CModel* Clone() const; + +private: + // delete anything allocated by the model + void ReleaseData(); + + // texture used by model + CTexture m_Texture; + // pointer to the model's raw 3d data + CModelDef* m_pModelDef; + // animation currently playing on this model, if any + CSkeletonAnim* m_Anim; + // time (in MS) into the current animation + float m_AnimTime; + // current state of all bones on this model; null if associated modeldef isn't skeletal + CMatrix3D* m_BoneMatrices; + // inverse of all the above matrices + CMatrix3D* m_InvBoneMatrices; +}; + +#endif diff --git a/source/terrain/ModelDef.cpp b/source/terrain/ModelDef.cpp index 71de8bf14e..8336d0ce05 100755 --- a/source/terrain/ModelDef.cpp +++ b/source/terrain/ModelDef.cpp @@ -1,90 +1,90 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Name: ModelDef.cpp -// Author: Rich Cross -// Contact: rich@wildfiregames.com -// -/////////////////////////////////////////////////////////////////////////////// - -#include "ModelDef.h" -#include "FilePacker.h" -#include "FileUnpacker.h" - -/////////////////////////////////////////////////////////////////////////////// -// CModelDef Constructor -CModelDef::CModelDef() - : m_pVertices(0), m_NumVertices(0), m_pFaces(0), m_NumFaces(0), m_Bones(0), m_NumBones(0) -{ -} - -/////////////////////////////////////////////////////////////////////////////// -// CModelDef Destructor -CModelDef::~CModelDef() -{ - delete[] m_pVertices; - delete[] m_pFaces; - delete[] m_Bones; -} - - -/////////////////////////////////////////////////////////////////////////////// -// Load: read and return a new CModelDef initialised with data from given file -CModelDef* CModelDef::Load(const char* filename) -{ - CFileUnpacker unpacker; - - // read everything in from file - unpacker.Read(filename,"PSMD"); - - // check version - if (unpacker.GetVersion()m_NumVertices,sizeof(mdef->m_NumVertices)); - mdef->m_pVertices=new SModelVertex[mdef->m_NumVertices]; - unpacker.UnpackRaw(mdef->m_pVertices,sizeof(SModelVertex)*mdef->m_NumVertices); - - unpacker.UnpackRaw(&mdef->m_NumFaces,sizeof(mdef->m_NumFaces)); - mdef->m_pFaces=new SModelFace[mdef->m_NumFaces]; - unpacker.UnpackRaw(mdef->m_pFaces,sizeof(SModelFace)*mdef->m_NumFaces); - - unpacker.UnpackRaw(&mdef->m_NumBones,sizeof(mdef->m_NumBones)); - if (mdef->m_NumBones) { - mdef->m_Bones=new CBoneState[mdef->m_NumBones]; - unpacker.UnpackRaw(mdef->m_Bones,mdef->m_NumBones*sizeof(CBoneState)); - } - } catch (...) { - delete mdef; - throw CFileUnpacker::CFileEOFError(); - } - - return mdef; -} - -/////////////////////////////////////////////////////////////////////////////// -// Save: write the given CModelDef to the given file -void CModelDef::Save(const char* filename,const CModelDef* mdef) -{ - CFilePacker packer; - - // pack everything up - u32 numVertices=mdef->GetNumVertices(); - packer.PackRaw(&numVertices,sizeof(numVertices)); - packer.PackRaw(mdef->GetVertices(),sizeof(SModelVertex)*numVertices); - - u32 numFaces=mdef->GetNumFaces(); - packer.PackRaw(&numFaces,sizeof(numFaces)); - packer.PackRaw(mdef->GetFaces(),sizeof(SModelFace)*numFaces); - - packer.PackRaw(&mdef->m_NumBones,sizeof(mdef->m_NumBones)); - if (mdef->m_NumBones) { - packer.PackRaw(mdef->m_Bones,sizeof(CBoneState)*mdef->m_NumBones); - } - - // flush everything out to file - packer.Write(filename,FILE_VERSION,"PSMD"); -} +/////////////////////////////////////////////////////////////////////////////// +// +// Name: ModelDef.cpp +// Author: Rich Cross +// Contact: rich@wildfiregames.com +// +/////////////////////////////////////////////////////////////////////////////// + +#include "ModelDef.h" +#include "FilePacker.h" +#include "FileUnpacker.h" + +/////////////////////////////////////////////////////////////////////////////// +// CModelDef Constructor +CModelDef::CModelDef() + : m_pVertices(0), m_NumVertices(0), m_pFaces(0), m_NumFaces(0), m_Bones(0), m_NumBones(0) +{ +} + +/////////////////////////////////////////////////////////////////////////////// +// CModelDef Destructor +CModelDef::~CModelDef() +{ + delete[] m_pVertices; + delete[] m_pFaces; + delete[] m_Bones; +} + + +/////////////////////////////////////////////////////////////////////////////// +// Load: read and return a new CModelDef initialised with data from given file +CModelDef* CModelDef::Load(const char* filename) +{ + CFileUnpacker unpacker; + + // read everything in from file + unpacker.Read(filename,"PSMD"); + + // check version + if (unpacker.GetVersion()m_NumVertices,sizeof(mdef->m_NumVertices)); + mdef->m_pVertices=new SModelVertex[mdef->m_NumVertices]; + unpacker.UnpackRaw(mdef->m_pVertices,sizeof(SModelVertex)*mdef->m_NumVertices); + + unpacker.UnpackRaw(&mdef->m_NumFaces,sizeof(mdef->m_NumFaces)); + mdef->m_pFaces=new SModelFace[mdef->m_NumFaces]; + unpacker.UnpackRaw(mdef->m_pFaces,sizeof(SModelFace)*mdef->m_NumFaces); + + unpacker.UnpackRaw(&mdef->m_NumBones,sizeof(mdef->m_NumBones)); + if (mdef->m_NumBones) { + mdef->m_Bones=new CBoneState[mdef->m_NumBones]; + unpacker.UnpackRaw(mdef->m_Bones,mdef->m_NumBones*sizeof(CBoneState)); + } + } catch (...) { + delete mdef; + throw CFileUnpacker::CFileEOFError(); + } + + return mdef; +} + +/////////////////////////////////////////////////////////////////////////////// +// Save: write the given CModelDef to the given file +void CModelDef::Save(const char* filename,const CModelDef* mdef) +{ + CFilePacker packer; + + // pack everything up + u32 numVertices=mdef->GetNumVertices(); + packer.PackRaw(&numVertices,sizeof(numVertices)); + packer.PackRaw(mdef->GetVertices(),sizeof(SModelVertex)*numVertices); + + u32 numFaces=mdef->GetNumFaces(); + packer.PackRaw(&numFaces,sizeof(numFaces)); + packer.PackRaw(mdef->GetFaces(),sizeof(SModelFace)*numFaces); + + packer.PackRaw(&mdef->m_NumBones,sizeof(mdef->m_NumBones)); + if (mdef->m_NumBones) { + packer.PackRaw(mdef->m_Bones,sizeof(CBoneState)*mdef->m_NumBones); + } + + // flush everything out to file + packer.Write(filename,FILE_VERSION,"PSMD"); +} diff --git a/source/terrain/ModelDef.h b/source/terrain/ModelDef.h index e8d1f0b654..c6cf66db3b 100755 --- a/source/terrain/ModelDef.h +++ b/source/terrain/ModelDef.h @@ -1,109 +1,109 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Name: ModelDef.h -// Author: Rich Cross -// Contact: rich@wildfiregames.com -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef _MODELDEF_H -#define _MODELDEF_H - -/////////////////////////////////////////////////////////////////////////////// -// TODO,RC 11/03/04: get rid of all the m_Name[MAX_NAME_LENGTH] - use CStr -// - problem: conflicts with CStr in MAX's SDK; can't compile PMDExp if -// ps\CStr.h included here -/////////////////////////////////////////////////////////////////////////////// - -#include "res/res.h" -#include "Vector3D.h" -#include "SkeletonAnim.h" - -#ifndef MAX_NAME_LENGTH -#define MAX_NAME_LENGTH (128) -#endif - -/////////////////////////////////////////////////////////////////////////////// -// SVertexBlend: structure containing the necessary data for blending vertices -// with multiple bones -struct SVertexBlend -{ - enum { SIZE = 4 }; - // index of the influencing bone, or 0xff if none - u8 m_Bone[SIZE]; - // weight of the influence; all weights sum to 1 - float m_Weight[SIZE]; -}; - -/////////////////////////////////////////////////////////////////////////////// -// SModelVertex: structure containing per-vertex data -struct SModelVertex -{ - // vertex position - CVector3D m_Coords; - // vertex normal - CVector3D m_Norm; - // vertex UVs - float m_U, m_V; - // vertex blend data - SVertexBlend m_Blend; -}; - - -/////////////////////////////////////////////////////////////////////////////// -// SModelFace: structure containing per-face data -struct SModelFace -{ - // indices of the 3 vertices on this face - u16 m_Verts[3]; -}; - - -//////////////////////////////////////////////////////////////////////////////////////// -// CModelDef: a raw 3D model; describes the vertices, faces, skinning and skeletal -// information of a model -class CModelDef -{ -public: - // current file version given to saved animations - enum { FILE_VERSION = 1 }; - // supported file read version - files with a version less than this will be rejected - enum { FILE_READ_VERSION = 1 }; - - -public: - // constructor - CModelDef(); - // destructor - virtual ~CModelDef(); - - // model I/O functions - static CModelDef* Load(const char* filename); - static void Save(const char* filename,const CModelDef* mdef); - -public: - // accessor: get vertex data - int GetNumVertices() const { return m_NumVertices; } - SModelVertex *GetVertices() const { return m_pVertices; } - - // accessor: get face data - int GetNumFaces() const { return m_NumFaces; } - SModelFace *GetFaces() const { return m_pFaces; } - - // accessor: get bone data - int GetNumBones() const { return m_NumBones; } - CBoneState *GetBones() const { return m_Bones; } - -public: - // vertex data - u32 m_NumVertices; - SModelVertex* m_pVertices; - // face data - u32 m_NumFaces; - SModelFace* m_pFaces; - // bone data - default model pose - u32 m_NumBones; - CBoneState* m_Bones; -}; - -#endif +/////////////////////////////////////////////////////////////////////////////// +// +// Name: ModelDef.h +// Author: Rich Cross +// Contact: rich@wildfiregames.com +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _MODELDEF_H +#define _MODELDEF_H + +/////////////////////////////////////////////////////////////////////////////// +// TODO,RC 11/03/04: get rid of all the m_Name[MAX_NAME_LENGTH] - use CStr +// - problem: conflicts with CStr in MAX's SDK; can't compile PMDExp if +// ps\CStr.h included here +/////////////////////////////////////////////////////////////////////////////// + +#include "res/res.h" +#include "Vector3D.h" +#include "SkeletonAnim.h" + +#ifndef MAX_NAME_LENGTH +#define MAX_NAME_LENGTH (128) +#endif + +/////////////////////////////////////////////////////////////////////////////// +// SVertexBlend: structure containing the necessary data for blending vertices +// with multiple bones +struct SVertexBlend +{ + enum { SIZE = 4 }; + // index of the influencing bone, or 0xff if none + u8 m_Bone[SIZE]; + // weight of the influence; all weights sum to 1 + float m_Weight[SIZE]; +}; + +/////////////////////////////////////////////////////////////////////////////// +// SModelVertex: structure containing per-vertex data +struct SModelVertex +{ + // vertex position + CVector3D m_Coords; + // vertex normal + CVector3D m_Norm; + // vertex UVs + float m_U, m_V; + // vertex blend data + SVertexBlend m_Blend; +}; + + +/////////////////////////////////////////////////////////////////////////////// +// SModelFace: structure containing per-face data +struct SModelFace +{ + // indices of the 3 vertices on this face + u16 m_Verts[3]; +}; + + +//////////////////////////////////////////////////////////////////////////////////////// +// CModelDef: a raw 3D model; describes the vertices, faces, skinning and skeletal +// information of a model +class CModelDef +{ +public: + // current file version given to saved animations + enum { FILE_VERSION = 1 }; + // supported file read version - files with a version less than this will be rejected + enum { FILE_READ_VERSION = 1 }; + + +public: + // constructor + CModelDef(); + // destructor + virtual ~CModelDef(); + + // model I/O functions + static CModelDef* Load(const char* filename); + static void Save(const char* filename,const CModelDef* mdef); + +public: + // accessor: get vertex data + int GetNumVertices() const { return m_NumVertices; } + SModelVertex *GetVertices() const { return m_pVertices; } + + // accessor: get face data + int GetNumFaces() const { return m_NumFaces; } + SModelFace *GetFaces() const { return m_pFaces; } + + // accessor: get bone data + int GetNumBones() const { return m_NumBones; } + CBoneState *GetBones() const { return m_Bones; } + +public: + // vertex data + u32 m_NumVertices; + SModelVertex* m_pVertices; + // face data + u32 m_NumFaces; + SModelFace* m_pFaces; + // bone data - default model pose + u32 m_NumBones; + CBoneState* m_Bones; +}; + +#endif diff --git a/source/terrain/ModelRData.cpp b/source/terrain/ModelRData.cpp index 1f2003ce40..40914025cd 100755 --- a/source/terrain/ModelRData.cpp +++ b/source/terrain/ModelRData.cpp @@ -1,257 +1,257 @@ -#include -#include -#include "res/tex.h" -#include "Renderer.h" -#include "TransparencyRenderer.h" -#include "ModelRData.h" -#include "terrain/Model.h" - - -CModelRData::CModelRData(CModel* model) : m_Model(model), m_Vertices(0), m_Normals(0), m_Indices(0), m_VB(0) -{ - assert(model); - // build all data now - Build(); -} - -CModelRData::~CModelRData() -{ -} - -void CModelRData::Build() -{ - BuildVertices(); - BuildIndices(); -} - -void CModelRData::BuildIndices() -{ - CModelDef* mdef=m_Model->GetModelDef(); - - // allocate indices if we haven't got any already - if (!m_Indices) { - m_Indices=new u16[mdef->GetNumFaces()*3]; - } - - // build indices - u32 indices=0; - SModelFace* faces=mdef->GetFaces(); - for (int j=0; jGetNumFaces(); j++) { - SModelFace& face=faces[j]; - m_Indices[indices++]=face.m_Verts[0]; - m_Indices[indices++]=face.m_Verts[1]; - m_Indices[indices++]=face.m_Verts[2]; - } -} - -inline int clamp(int x,int min,int max) -{ - if (xmax) return max; - else return x; -} - -static SColor4ub ConvertColor(const RGBColor& src) -{ - SColor4ub result; - result.R=clamp(int(src.X*255),0,255); - result.G=clamp(int(src.Y*255),0,255); - result.B=clamp(int(src.Z*255),0,255); - result.A=0xff; - return result; -} - -static CVector3D SkinPoint(const SModelVertex& vertex,const CMatrix3D* matrices) -{ - CVector3D result(0,0,0),tmp; - - for (u32 i=0;vertex.m_Blend.m_Bone[i]!=0xff && iGetModelDef(); - - // allocate vertices if we haven't got any already - if (!m_Vertices) { - m_Vertices=new SVertex[mdef->GetNumVertices()]; - m_Normals=new CVector3D[mdef->GetNumVertices()]; - } - - // build vertices - u32 numVertices=mdef->GetNumVertices(); - SModelVertex* vertices=mdef->GetVertices(); - if (m_Model->GetBoneMatrices()) { - // boned model - calculate skinned vertex positions/normals - for (uint j=0; jGetBoneMatrices()); - m_Normals[j]=SkinNormal(vertices[j],m_Model->GetInvBoneMatrices()); - } - } else { - // just copy regular positions - for (uint j=0; jGetNumVertices()*sizeof(SVertex),0,mdef->GetNumBones() ? GL_DYNAMIC_DRAW_ARB : GL_STATIC_DRAW_ARB); - } - glBindBufferARB(GL_ARRAY_BUFFER_ARB,m_VB); - glBufferSubDataARB(GL_ARRAY_BUFFER_ARB,0,mdef->GetNumVertices()*sizeof(SVertex),m_Vertices); - } -} - - -void CModelRData::RenderStreams(u32 streamflags,const CMatrix3D& transform,bool transparentPass) -{ - // ignore transparent passes - if (!transparentPass && g_Renderer.IsTextureTransparent(m_Model->GetTexture())) { - return; - } - - CModelDef* mdldef=(CModelDef*) m_Model->GetModelDef(); - - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - - CMatrix3D tmp; - glMultMatrixf(&transform._11); - - if (streamflags & STREAM_UV0) g_Renderer.SetTexture(0,m_Model->GetTexture(),GL_CLAMP_TO_EDGE); - - u8* base; - if (g_Renderer.m_Caps.m_VBO) { - glBindBufferARB(GL_ARRAY_BUFFER_ARB,m_VB); - base=0; - } else { - base=(u8*) &m_Vertices[0]; - } - - // set vertex pointers - u32 stride=sizeof(SVertex); - glVertexPointer(3,GL_FLOAT,stride,base+offsetof(SVertex,m_Position)); - if (streamflags & STREAM_COLOR) glColorPointer(4,GL_UNSIGNED_BYTE,stride,base+offsetof(SVertex,m_Color)); - if (streamflags & STREAM_UV0) glTexCoordPointer(2,GL_FLOAT,stride,base+offsetof(SVertex,m_UVs)); - - // render the lot - u32 numFaces=mdldef->GetNumFaces(); - glDrawElements(GL_TRIANGLES,numFaces*3,GL_UNSIGNED_SHORT,m_Indices); - - // bump stats - g_Renderer.m_Stats.m_DrawCalls++; - if (transparentPass) { - g_Renderer.m_Stats.m_TransparentTris+=numFaces; - } else { - g_Renderer.m_Stats.m_ModelTris+=numFaces; - } - - glPopMatrix(); -} - - -void CModelRData::Update() -{ - if (m_UpdateFlags!=0) { - // renderdata changed : rebuild necessary portions - if (m_UpdateFlags & RENDERDATA_UPDATE_VERTICES) { - BuildVertices(); - } - if (m_UpdateFlags & RENDERDATA_UPDATE_INDICES) { - BuildIndices(); - } - - m_UpdateFlags=0; - } -} - -typedef std::pair IntFloatPair; -static std::vector IndexSorter; - -struct SortFacesByDist { - bool operator()(const IntFloatPair& lhs,const IntFloatPair& rhs) { - return lhs.second>rhs.second ? true : false; - } -}; - -float CModelRData::BackToFrontIndexSort(CMatrix3D& objToCam) -{ - float mindist=1.0e30f; - CVector3D osvtx,csvtx; - - CModelDef* mdldef=(CModelDef*) m_Model->GetModelDef(); - - SModelVertex* vtxs=mdldef->GetVertices(); - - u32 numFaces=mdldef->GetNumFaces(); - SModelFace* faces=mdldef->GetFaces(); - - IndexSorter.reserve(numFaces); - - SModelFace* facePtr=faces; - u32 i; - for (i=0;im_Verts[0]].m_Coords; - osvtx+=vtxs[facePtr->m_Verts[1]].m_Coords; - osvtx+=vtxs[facePtr->m_Verts[2]].m_Coords; - osvtx*=1.0f/3.0f; - - csvtx=objToCam.Transform(osvtx); - float distsqrd=SQR(csvtx.X)+SQR(csvtx.Y)+SQR(csvtx.Z); - if (distsqrd +#include +#include "res/tex.h" +#include "Renderer.h" +#include "TransparencyRenderer.h" +#include "ModelRData.h" +#include "terrain/Model.h" + + +CModelRData::CModelRData(CModel* model) : m_Model(model), m_Vertices(0), m_Normals(0), m_Indices(0), m_VB(0) +{ + assert(model); + // build all data now + Build(); +} + +CModelRData::~CModelRData() +{ +} + +void CModelRData::Build() +{ + BuildVertices(); + BuildIndices(); +} + +void CModelRData::BuildIndices() +{ + CModelDef* mdef=m_Model->GetModelDef(); + + // allocate indices if we haven't got any already + if (!m_Indices) { + m_Indices=new u16[mdef->GetNumFaces()*3]; + } + + // build indices + u32 indices=0; + SModelFace* faces=mdef->GetFaces(); + for (int j=0; jGetNumFaces(); j++) { + SModelFace& face=faces[j]; + m_Indices[indices++]=face.m_Verts[0]; + m_Indices[indices++]=face.m_Verts[1]; + m_Indices[indices++]=face.m_Verts[2]; + } +} + +inline int clamp(int x,int min,int max) +{ + if (xmax) return max; + else return x; +} + +static SColor4ub ConvertColor(const RGBColor& src) +{ + SColor4ub result; + result.R=clamp(int(src.X*255),0,255); + result.G=clamp(int(src.Y*255),0,255); + result.B=clamp(int(src.Z*255),0,255); + result.A=0xff; + return result; +} + +static CVector3D SkinPoint(const SModelVertex& vertex,const CMatrix3D* matrices) +{ + CVector3D result(0,0,0),tmp; + + for (u32 i=0;vertex.m_Blend.m_Bone[i]!=0xff && iGetModelDef(); + + // allocate vertices if we haven't got any already + if (!m_Vertices) { + m_Vertices=new SVertex[mdef->GetNumVertices()]; + m_Normals=new CVector3D[mdef->GetNumVertices()]; + } + + // build vertices + u32 numVertices=mdef->GetNumVertices(); + SModelVertex* vertices=mdef->GetVertices(); + if (m_Model->GetBoneMatrices()) { + // boned model - calculate skinned vertex positions/normals + for (uint j=0; jGetBoneMatrices()); + m_Normals[j]=SkinNormal(vertices[j],m_Model->GetInvBoneMatrices()); + } + } else { + // just copy regular positions + for (uint j=0; jGetNumVertices()*sizeof(SVertex),0,mdef->GetNumBones() ? GL_DYNAMIC_DRAW_ARB : GL_STATIC_DRAW_ARB); + } + glBindBufferARB(GL_ARRAY_BUFFER_ARB,m_VB); + glBufferSubDataARB(GL_ARRAY_BUFFER_ARB,0,mdef->GetNumVertices()*sizeof(SVertex),m_Vertices); + } +} + + +void CModelRData::RenderStreams(u32 streamflags,const CMatrix3D& transform,bool transparentPass) +{ + // ignore transparent passes + if (!transparentPass && g_Renderer.IsTextureTransparent(m_Model->GetTexture())) { + return; + } + + CModelDef* mdldef=(CModelDef*) m_Model->GetModelDef(); + + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + + CMatrix3D tmp; + glMultMatrixf(&transform._11); + + if (streamflags & STREAM_UV0) g_Renderer.SetTexture(0,m_Model->GetTexture(),GL_CLAMP_TO_EDGE); + + u8* base; + if (g_Renderer.m_Caps.m_VBO) { + glBindBufferARB(GL_ARRAY_BUFFER_ARB,m_VB); + base=0; + } else { + base=(u8*) &m_Vertices[0]; + } + + // set vertex pointers + u32 stride=sizeof(SVertex); + glVertexPointer(3,GL_FLOAT,stride,base+offsetof(SVertex,m_Position)); + if (streamflags & STREAM_COLOR) glColorPointer(4,GL_UNSIGNED_BYTE,stride,base+offsetof(SVertex,m_Color)); + if (streamflags & STREAM_UV0) glTexCoordPointer(2,GL_FLOAT,stride,base+offsetof(SVertex,m_UVs)); + + // render the lot + u32 numFaces=mdldef->GetNumFaces(); + glDrawElements(GL_TRIANGLES,numFaces*3,GL_UNSIGNED_SHORT,m_Indices); + + // bump stats + g_Renderer.m_Stats.m_DrawCalls++; + if (transparentPass) { + g_Renderer.m_Stats.m_TransparentTris+=numFaces; + } else { + g_Renderer.m_Stats.m_ModelTris+=numFaces; + } + + glPopMatrix(); +} + + +void CModelRData::Update() +{ + if (m_UpdateFlags!=0) { + // renderdata changed : rebuild necessary portions + if (m_UpdateFlags & RENDERDATA_UPDATE_VERTICES) { + BuildVertices(); + } + if (m_UpdateFlags & RENDERDATA_UPDATE_INDICES) { + BuildIndices(); + } + + m_UpdateFlags=0; + } +} + +typedef std::pair IntFloatPair; +static std::vector IndexSorter; + +struct SortFacesByDist { + bool operator()(const IntFloatPair& lhs,const IntFloatPair& rhs) { + return lhs.second>rhs.second ? true : false; + } +}; + +float CModelRData::BackToFrontIndexSort(CMatrix3D& objToCam) +{ + float mindist=1.0e30f; + CVector3D osvtx,csvtx; + + CModelDef* mdldef=(CModelDef*) m_Model->GetModelDef(); + + SModelVertex* vtxs=mdldef->GetVertices(); + + u32 numFaces=mdldef->GetNumFaces(); + SModelFace* faces=mdldef->GetFaces(); + + IndexSorter.reserve(numFaces); + + SModelFace* facePtr=faces; + u32 i; + for (i=0;im_Verts[0]].m_Coords; + osvtx+=vtxs[facePtr->m_Verts[1]].m_Coords; + osvtx+=vtxs[facePtr->m_Verts[2]].m_Coords; + osvtx*=1.0f/3.0f; + + csvtx=objToCam.Transform(osvtx); + float distsqrd=SQR(csvtx.X)+SQR(csvtx.Y)+SQR(csvtx.Z); + if (distsqrd -#include "res/res.h" -#include "Vector3D.h" -#include "RenderableObject.h" - -class CModel; - -class CModelRData : public CRenderData -{ -public: - CModelRData(CModel* model); - ~CModelRData(); - - void Update(); - void RenderStreams(u32 streamflags,const CMatrix3D& transform,bool transparentPass=false); - - // sort indices of this object from back to front according to given - // object to camera space transform; return sqrd distance to centre of nearest triangle - float BackToFrontIndexSort(CMatrix3D& objToCam); - -private: - // build this renderdata object - void Build(); - - void BuildVertices(); - void BuildIndices(); - - - struct SVertex { - // vertex position - CVector3D m_Position; - // vertex uvs for base texture - float m_UVs[2]; - // vertex color - SColor4ub m_Color; - }; - - // owner model - CModel* m_Model; - // handle to models vertex buffer - u32 m_VB; - // model render vertices - SVertex* m_Vertices; - // transformed vertex normals - required for recalculating lighting on skinned models - CVector3D* m_Normals; - // model render indices - u16* m_Indices; -}; - - -#endif +#ifndef _MODELRDATA_H +#define _MODELRDATA_H + +#include +#include "res/res.h" +#include "Vector3D.h" +#include "RenderableObject.h" + +class CModel; + +class CModelRData : public CRenderData +{ +public: + CModelRData(CModel* model); + ~CModelRData(); + + void Update(); + void RenderStreams(u32 streamflags,const CMatrix3D& transform,bool transparentPass=false); + + // sort indices of this object from back to front according to given + // object to camera space transform; return sqrd distance to centre of nearest triangle + float BackToFrontIndexSort(CMatrix3D& objToCam); + +private: + // build this renderdata object + void Build(); + + void BuildVertices(); + void BuildIndices(); + + + struct SVertex { + // vertex position + CVector3D m_Position; + // vertex uvs for base texture + float m_UVs[2]; + // vertex color + SColor4ub m_Color; + }; + + // owner model + CModel* m_Model; + // handle to models vertex buffer + u32 m_VB; + // model render vertices + SVertex* m_Vertices; + // transformed vertex normals - required for recalculating lighting on skinned models + CVector3D* m_Normals; + // model render indices + u16* m_Indices; +}; + + +#endif diff --git a/source/terrain/ObjectEntry.cpp b/source/terrain/ObjectEntry.cpp index a79ca2f366..84dc8e6d4a 100755 --- a/source/terrain/ObjectEntry.cpp +++ b/source/terrain/ObjectEntry.cpp @@ -1,233 +1,223 @@ -#include "ObjectEntry.h" -#include "ObjectManager.h" -#include "terrain/Model.h" -#include "terrain/ModelDef.h" - -#include "UnitManager.h" - -// xerces XML stuff -#include -#include -#include -#include -#include - -// Gee's custom error handler -#include - -// automatically use namespace .. -XERCES_CPP_NAMESPACE_USE - - -CObjectEntry::CObjectEntry(int type) : m_Model(0), m_Type(type) -{ -} - -CObjectEntry::~CObjectEntry() -{ - delete m_Model; -} - -bool CObjectEntry::BuildModel() -{ - // check we've enough data to consider building the object - if (m_ModelName.Length()==0 || m_TextureName.Length()==0) { - return false; - } - - // get the root directory of this object - CStr dirname=g_ObjMan.m_ObjectTypes[m_Type].m_Name; - - // remember the old model so we can replace any models using it later on - CModelDef* oldmodel=m_Model ? m_Model->GetModelDef() : 0; - - // build filename - CStr modelfilename("mods\\official\\"); - modelfilename+=m_ModelName; - - // try and create a model - CModelDef* modeldef; - - try { - modeldef=CModelDef::Load((const char*) modelfilename); - } catch (...) { - return false; - } - - // create new Model - m_Model=new CModel; - m_Model->InitModel(modeldef); - - CStr texturefilename(m_TextureName); - - m_Model->SetTexture(CTexture((const char*) texturefilename)); - - // animations? - if (m_Animations.size()) { - // yes; iterate through and load each one - for (uint i=0;i0) { - CStr animfilename("mods\\official\\"); - animfilename+=m_Animations[i].m_FileName; - - try { - m_Animations[i].m_AnimData=CSkeletonAnim::Load((const char*) animfilename); - } catch (...) { - m_Animations[i].m_AnimData=0; - } - } - } - - // set the first valid animation found as current - for (uint i=0;iSetAnimation(m_Animations[i].m_AnimData); - break; - } - } - } - - // rebuild model bounds - m_Model->CalcBounds(); - - // replace any units using old model to now use new model - const std::vector& units=g_UnitMan.GetUnits(); - for (uint i=0;im_Model->GetModelDef()==oldmodel) { - units[i]->m_Model->InitModel(m_Model->GetModelDef()); - - CSkeletonAnim* anim=m_Model->GetAnimation(); - if (anim) { - units[i]->m_Model->SetAnimation(anim); - } - } - } - - // and were done with the old model .. - delete oldmodel; - - return true; -} - -bool CObjectEntry::Load(const char* filename) -{ - bool parseOK = false; - - // Initialize XML library - XMLPlatformUtils::Initialize(); - { - // Create parser instance - XercesDOMParser *parser = new XercesDOMParser(); - - // Setup parser - parser->setValidationScheme(XercesDOMParser::Val_Auto); - parser->setDoNamespaces(false); - parser->setDoSchema(false); - parser->setCreateEntityReferenceNodes(false); - - // Set customized error handler - CXercesErrorHandler *errorHandler = new CXercesErrorHandler(); - parser->setErrorHandler(errorHandler); - - // Push the CLogger to mark it's reading this file. - - // Get main node - LocalFileInputSource source( XMLString::transcode(filename) ); - - // Parse file - parser->parse(source); - - // Check how many errors - parseOK = parser->getErrorCount() == 0; - - if (parseOK) { - // parsed successfully - grab our data - DOMDocument *doc = parser->getDocument(); - DOMElement *element = doc->getDocumentElement(); - - // root_name should be Object - CStr root_name = XMLString::transcode( element->getNodeName() ); - - // should have at least 3 children - Name, ModelName and TextureName - DOMNodeList *children = element->getChildNodes(); - int numChildren=children->getLength(); - for (int i=0; iitem(i); - - // A child element - if (child->getNodeType() == DOMNode::ELEMENT_NODE) - { - // First get element and not node - DOMElement *child_element = (DOMElement*)child; - - CStr element_name = XMLString::transcode( child_element->getNodeName() ); - DOMNode *value_node= child_element->getChildNodes()->item(0); - CStr element_value=value_node ? XMLString::transcode(value_node->getNodeValue()) : ""; - - if (element_name==CStr("Name")) { - m_Name=element_value; - } else if (element_name==CStr("ModelName")) { - m_ModelName=element_value; - } else if (element_name==CStr("TextureName")) { - m_TextureName=element_value; - } else if (element_name==CStr("Animations")) { - DOMNodeList* animations=(DOMNodeList*) child_element->getChildNodes(); - - for (uint j=0; jgetLength(); ++j) { - DOMElement *anim_element = (DOMElement*) animations->item(j); - CStr element_name = XMLString::transcode( anim_element->getNodeName() ); - DOMNamedNodeMap* attributes=anim_element->getAttributes(); - if (attributes) { - Anim anim; - - DOMNode *nameattr=attributes->getNamedItem(XMLString::transcode("name")); - anim.m_AnimName=XMLString::transcode(nameattr->getChildNodes()->item(0)->getNodeValue()); - DOMNode *fileattr=attributes->getNamedItem(XMLString::transcode("file")); - anim.m_FileName=XMLString::transcode(fileattr->getChildNodes()->item(0)->getNodeValue()); - - m_Animations.push_back(anim); - } - } - } - } - } - - // try and build the model - BuildModel(); - } - - delete parser; - } - XMLPlatformUtils::Terminate(); - - return parseOK; -} - -bool CObjectEntry::Save(const char* filename) -{ - FILE* fp=fopen(filename,"w"); - if (!fp) return false; - - // write XML header - fprintf(fp,"\n\n"); - fprintf(fp,"\n\n"); - - // write the object itself - fprintf(fp,"\n"); - fprintf(fp,"\n"); - fprintf(fp,"\t%s\n",(const char*) m_Name); - fprintf(fp,"\t%s\n",(const char*) m_ModelName); - fprintf(fp,"\t%s\n",(const char*) m_TextureName); - if (m_Animations.size()>0) { - fprintf(fp,"\t\n"); - for (uint i=0;i \n",(const char*) m_Animations[i].m_AnimName,(const char*) m_Animations[i].m_FileName); - } - fprintf(fp,"\t\n"); - } - fprintf(fp,"\n"); - fclose(fp); - - return true; -} +#include "ObjectEntry.h" +#include "ObjectManager.h" +#include "terrain/Model.h" +#include "terrain/ModelDef.h" + +#include "UnitManager.h" + +// xerces XML stuff +#include +#include +#include +#include +#include + +// Gee's custom error handler +#include + +// automatically use namespace .. +XERCES_CPP_NAMESPACE_USE + + +CObjectEntry::CObjectEntry(int type) : m_Model(0), m_Type(type) +{ +} + +CObjectEntry::~CObjectEntry() +{ + delete m_Model; +} + +bool CObjectEntry::BuildModel() +{ + // check we've enough data to consider building the object + if (m_ModelName.Length()==0 || m_TextureName.Length()==0) { + return false; + } + + // get the root directory of this object + CStr dirname=g_ObjMan.m_ObjectTypes[m_Type].m_Name; + + // remember the old model so we can replace any models using it later on + CModelDef* oldmodel=m_Model ? m_Model->GetModelDef() : 0; + + // build filename + CStr modelfilename("mods\\official\\"); + modelfilename+=m_ModelName; + + // try and create a model + CModelDef* modeldef; + + try { + modeldef=CModelDef::Load((const char*) modelfilename); + } catch (...) { + return false; + } + + // create new Model + m_Model=new CModel; + m_Model->InitModel(modeldef); + + CStr texturefilename(m_TextureName); + + m_Model->SetTexture(CTexture((const char*) texturefilename)); + for( int t = 0; t < m_Animations.size(); t++ ) { if( m_Animations[t].m_FileName.Length() > 0 ) { CStr animfilename( "mods\\official\\" ); animfilename += m_Animations[t].m_FileName; try { m_Animations[t].m_AnimData = CSkeletonAnim::Load( animfilename ); } catch( ... ) { m_Animations[t].m_AnimData = NULL; } if( m_Animations[t].m_AnimName.LowerCase() == CStr( "idle" ) ) m_IdleAnim = m_Animations[t].m_AnimData; if( m_Animations[t].m_AnimName.LowerCase() == CStr( "walk" ) ) m_WalkAnim = m_Animations[t].m_AnimData; } } m_Model->SetAnimation( m_IdleAnim ); /* + if (m_Animations.size()) { + if (m_Animations[0].m_FileName.Length()>0) { + CStr animfilename("mods\\official\\"); + animfilename+=m_Animations[0].m_FileName; + + try { + CSkeletonAnim* anim=CSkeletonAnim::Load((const char*) animfilename); + m_Model->SetAnimation(anim); + } catch (...) { + m_Model->SetAnimation(0); + } + } + } + */ + // rebuild model bounds + m_Model->CalcBounds(); + + // replace any units using old model to now use new model + const std::vector& units=g_UnitMan.GetUnits(); + for (uint i=0;im_Model->GetModelDef()==oldmodel) { + units[i]->m_Model->InitModel(m_Model->GetModelDef()); + /* + CSkeletonAnim* anim=m_Model->GetAnimation(); + + if (anim) { + units[i]->m_Model->SetAnimation(anim); + } */ + } + } + + // and were done with the old model .. + delete oldmodel; + + return true; +} +CSkeletonAnim* CObjectEntry::GetNamedAnimation( CStr animationName ) { for( int t = 0; t < m_Animations.size(); t++ ) { if( m_Animations[t].m_AnimName == animationName ) return( m_Animations[t].m_AnimData ); } return( NULL ); } +bool CObjectEntry::Load(const char* filename) +{ + bool parseOK = false; + + // Initialize XML library + XMLPlatformUtils::Initialize(); + { + // Create parser instance + XercesDOMParser *parser = new XercesDOMParser(); + + // Setup parser + parser->setValidationScheme(XercesDOMParser::Val_Auto); + parser->setDoNamespaces(false); + parser->setDoSchema(false); + parser->setCreateEntityReferenceNodes(false); + + // Set customized error handler + CXercesErrorHandler *errorHandler = new CXercesErrorHandler(); + parser->setErrorHandler(errorHandler); + + // Push the CLogger to mark it's reading this file. + + // Get main node + LocalFileInputSource source( XMLString::transcode(filename) ); + + // Parse file + parser->parse(source); + + // Check how many errors + parseOK = parser->getErrorCount() == 0; + + if (parseOK) { + // parsed successfully - grab our data + DOMDocument *doc = parser->getDocument(); + DOMElement *element = doc->getDocumentElement(); + + // root_name should be Object + CStr root_name = XMLString::transcode( element->getNodeName() ); + + // should have at least 3 children - Name, ModelName and TextureName + DOMNodeList *children = element->getChildNodes(); + int numChildren=children->getLength(); + for (int i=0; iitem(i); + + // A child element + if (child->getNodeType() == DOMNode::ELEMENT_NODE) + { + // First get element and not node + DOMElement *child_element = (DOMElement*)child; + + CStr element_name = XMLString::transcode( child_element->getNodeName() ); + DOMNode *value_node= child_element->getChildNodes()->item(0); + CStr element_value=value_node ? XMLString::transcode(value_node->getNodeValue()) : ""; + + if (element_name==CStr("Name")) { + m_Name=element_value; + } else if (element_name==CStr("ModelName")) { + m_ModelName=element_value; + } else if (element_name==CStr("TextureName")) { + m_TextureName=element_value; + } else if (element_name==CStr("Animations")) { + DOMNodeList* animations=(DOMNodeList*) child_element->getChildNodes(); + + for (uint j=0; jgetLength(); ++j) { + DOMElement *anim_element = (DOMElement*) animations->item(j); + CStr element_name = XMLString::transcode( anim_element->getNodeName() ); + DOMNamedNodeMap* attributes=anim_element->getAttributes(); + if (attributes) { + Anim anim; + + DOMNode *nameattr=attributes->getNamedItem(XMLString::transcode("name")); + anim.m_AnimName=XMLString::transcode(nameattr->getChildNodes()->item(0)->getNodeValue()); + DOMNode *fileattr=attributes->getNamedItem(XMLString::transcode("file")); + anim.m_FileName=XMLString::transcode(fileattr->getChildNodes()->item(0)->getNodeValue()); + + m_Animations.push_back(anim); + } + } + } + } + } + + // try and build the model + BuildModel(); + } + + delete parser; + } + XMLPlatformUtils::Terminate(); + + return parseOK; +} + +bool CObjectEntry::Save(const char* filename) +{ + FILE* fp=fopen(filename,"w"); + if (!fp) return false; + + // write XML header + fprintf(fp,"\n\n"); + fprintf(fp,"\n\n"); + + // write the object itself + fprintf(fp,"\n"); + fprintf(fp,"\n"); + fprintf(fp,"\t%s\n",(const char*) m_Name); + fprintf(fp,"\t%s\n",(const char*) m_ModelName); + fprintf(fp,"\t%s\n",(const char*) m_TextureName); + if (m_Animations.size()>0) { + fprintf(fp,"\t\n"); + for (uint i=0;i \n",(const char*) m_Animations[i].m_AnimName,(const char*) m_Animations[i].m_FileName); + } + fprintf(fp,"\t\n"); + } + fprintf(fp,"\n"); + fclose(fp); + + return true; +} diff --git a/source/terrain/ObjectEntry.h b/source/terrain/ObjectEntry.h index 19bf776a62..443fe41e45 100755 --- a/source/terrain/ObjectEntry.h +++ b/source/terrain/ObjectEntry.h @@ -1,47 +1,46 @@ -#ifndef _OBJECTENTRY_H -#define _OBJECTENTRY_H - -class CModel; -class CSkeletonAnim; - -#include -#include "CStr.h" -#include "terrain/Bound.h" - - -class CObjectEntry -{ -public: - struct Anim { - CStr m_AnimName; - CStr m_FileName; - CSkeletonAnim* m_AnimData; - }; - -public: - CObjectEntry(int type); - ~CObjectEntry(); - - bool BuildModel(); - - bool Load(const char* filename); - bool Save(const char* filename); - - // object name - CStr m_Name; - // texture name - CStr m_TextureName; - // model name - CStr m_ModelName; - // list of valid animations for this object - std::vector m_Animations; - // object space bounds of model -// CBound m_Bound; - // corresponding model - CModel* m_Model; - // type of object; index into object managers types array - int m_Type; -}; - - -#endif +#ifndef _OBJECTENTRY_H +#define _OBJECTENTRY_H + +class CModel; + +#include +#include "CStr.h" +#include "terrain/Bound.h" +#include "terrain/ModelDef.h" + +class CObjectEntry +{ +public: + struct Anim { + CStr m_AnimName; + CStr m_FileName; CSkeletonAnim* m_AnimData; //Pending + }; + +public: + CObjectEntry(int type); + ~CObjectEntry(); + + bool BuildModel(); + + bool Load(const char* filename); + bool Save(const char* filename); + + // object name + CStr m_Name; + // texture name + CStr m_TextureName; + // model name + CStr m_ModelName; + // animations + std::vector m_Animations; CSkeletonAnim* m_IdleAnim; CSkeletonAnim* m_WalkAnim; CSkeletonAnim* m_DeathAnim; CSkeletonAnim* m_MeleeAnim; CSkeletonAnim* m_RangedAnim; CSkeletonAnim* GetNamedAnimation( CStr animationName ); + // object space bounds of model +// CBound m_Bound; + // corresponding model + CModel* m_Model; + // type of object; index into object managers types array + int m_Type; +}; + + +#endif + diff --git a/source/terrain/ObjectManager.cpp b/source/terrain/ObjectManager.cpp index 814f532a9a..b5d2caabbf 100755 --- a/source/terrain/ObjectManager.cpp +++ b/source/terrain/ObjectManager.cpp @@ -1,132 +1,128 @@ -#include "ObjectManager.h" -#include -#include - -CObjectManager g_ObjMan; - -CObjectManager::CObjectManager() : m_SelectedObject(0) -{ - m_ObjectTypes.reserve(32); -} - - -CObjectEntry* CObjectManager::FindObject(const char* objectname) -{ - for (uint k=0;k& objects=m_ObjectTypes[k].m_Objects; - - for (uint i=0;im_Name)==0) { - return objects[i]; - } - } - } - - return 0; -} - -void CObjectManager::AddObjectType(const char* name) -{ - m_ObjectTypes.resize(m_ObjectTypes.size()+1); - SObjectType& type=m_ObjectTypes.back(); - type.m_Name=name; - type.m_Index=m_ObjectTypes.size()-1; -} - -void CObjectManager::AddObject(CObjectEntry* object,int type) -{ - assert((uint)typeBuildModel()) { - m_ObjectTypes[type].m_Objects.push_back(object); - } -} - -void CObjectManager::DeleteObject(CObjectEntry* entry) -{ - std::vector& objects=m_ObjectTypes[entry->m_Type].m_Objects; - - typedef std::vector::iterator Iter; - Iter i=std::find(objects.begin(),objects.end(),entry); - if (i!=objects.end()) { - objects.erase(i); - } - delete entry; -} - -void CObjectManager::LoadObjects() -{ - // find all the object types by directory name - BuildObjectTypes(); - - // now iterate through terrain types loading all textures of that type - for (uint i=0;iLoad((const char*) filename)) { - delete object; - } else { - AddObject(object,type); - } - - // Find the rest of the matching files - while( _findnext(handle,&file)==0) { - CObjectEntry* object=new CObjectEntry(type); - CStr filename(pathname); - filename+=file.name; - if (!object->Load((const char*) filename)) { - delete object; - } else { - AddObject(object,type); - } - } - - _findclose(handle); - } -} - - +#include "ObjectManager.h" +#include +#include + +CObjectManager g_ObjMan; + +CObjectManager::CObjectManager() : m_SelectedObject(0) +{ + m_ObjectTypes.reserve(32); +} + + +CObjectEntry* CObjectManager::FindObject(const char* objectname) +{ + for (uint k=0;k& objects=m_ObjectTypes[k].m_Objects; + + for (uint i=0;im_Name)==0) { + return objects[i]; + } + } + } + + return 0; +} + +void CObjectManager::AddObjectType(const char* name) +{ + m_ObjectTypes.resize(m_ObjectTypes.size()+1); + SObjectType& type=m_ObjectTypes.back(); + type.m_Name=name; + type.m_Index=m_ObjectTypes.size()-1; +} + +void CObjectManager::AddObject(CObjectEntry* object,int type) +{ + assert((uint)typeBuildModel() ) + m_ObjectTypes[type].m_Objects.push_back(object); +} + +void CObjectManager::DeleteObject(CObjectEntry* entry) +{ + std::vector& objects=m_ObjectTypes[entry->m_Type].m_Objects; + + typedef std::vector::iterator Iter; + Iter i=std::find(objects.begin(),objects.end(),entry); + if (i!=objects.end()) { + objects.erase(i); + } + delete entry; +} + +void CObjectManager::LoadObjects() +{ + // find all the object types by directory name + BuildObjectTypes(); + + // now iterate through terrain types loading all textures of that type + for (uint i=0;iLoad((const char*) filename)) { + delete object; + } else { + AddObject(object,type); + } + + // Find the rest of the matching files + while( _findnext(handle,&file)==0) { + CObjectEntry* object=new CObjectEntry(type); + CStr filename(pathname); + filename+=file.name; + if (!object->Load((const char*) filename)) { + delete object; + } else { + AddObject(object,type); + } + } + + _findclose(handle); + } +} diff --git a/source/terrain/ObjectManager.h b/source/terrain/ObjectManager.h index 1dd343eb8a..b8d4f4c59b 100755 --- a/source/terrain/ObjectManager.h +++ b/source/terrain/ObjectManager.h @@ -1,47 +1,47 @@ -#ifndef _OBJECTMANAGER_H -#define _OBJECTMANAGER_H - -#include -#include "ObjectEntry.h" - -class CObjectManager -{ -public: - struct SObjectType - { - // name of this object type (derived from directory name) - CStr m_Name; - // index in parent array - int m_Index; - // list of objects of this type (found from the objects directory) - std::vector m_Objects; - }; - -public: - CObjectManager(); - - void LoadObjects(); - - - void AddObjectType(const char* name); - - CObjectEntry* FindObject(const char* objname); - void AddObject(CObjectEntry* entry,int type); - void DeleteObject(CObjectEntry* entry); - - CObjectEntry* GetSelectedObject() const { return m_SelectedObject; } - void SetSelectedObject(CObjectEntry* obj) { m_SelectedObject=obj; } - - std::vector m_ObjectTypes; - -private: - void BuildObjectTypes(); - void LoadObjects(int type); - - CObjectEntry* m_SelectedObject; -}; - -extern CObjectManager g_ObjMan; - - +#ifndef _OBJECTMANAGER_H +#define _OBJECTMANAGER_H + +#include +#include "ObjectEntry.h" + +class CObjectManager +{ +public: + struct SObjectType + { + // name of this object type (derived from directory name) + CStr m_Name; + // index in parent array + int m_Index; + // list of objects of this type (found from the objects directory) + std::vector m_Objects; + }; + +public: + CObjectManager(); + + void LoadObjects(); + + + void AddObjectType(const char* name); + + CObjectEntry* FindObject(const char* objname); + void AddObject(CObjectEntry* entry,int type); + void DeleteObject(CObjectEntry* entry); + + CObjectEntry* GetSelectedObject() const { return m_SelectedObject; } + void SetSelectedObject(CObjectEntry* obj) { m_SelectedObject=obj; } + + std::vector m_ObjectTypes; + +private: + void BuildObjectTypes(); + void LoadObjects(int type); + + CObjectEntry* m_SelectedObject; +}; + +extern CObjectManager g_ObjMan; + + #endif \ No newline at end of file diff --git a/source/terrain/Patch.cpp b/source/terrain/Patch.cpp index 3e6aa3d3fe..90a752a750 100755 --- a/source/terrain/Patch.cpp +++ b/source/terrain/Patch.cpp @@ -1,60 +1,60 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Name: ModelDef.cpp -// Author: Rich Cross -// Contact: rich@wildfiregames.com -// -/////////////////////////////////////////////////////////////////////////////// - -#include "Patch.h" -#include "Terrain.h" - - -/////////////////////////////////////////////////////////////////////////////// -// CPatch constructor -CPatch::CPatch() : m_Parent(0) -{ -} - -/////////////////////////////////////////////////////////////////////////////// -// CPatch destructor -CPatch::~CPatch() -{ -} - -/////////////////////////////////////////////////////////////////////////////// -// Initialize: setup patch data -void CPatch::Initialize(CTerrain* parent,u32 x,u32 z) -{ - delete m_RenderData; - m_RenderData=0; - - m_Parent=parent; - m_X=x; - m_Z=z; - - // set parent of each patch - for (int j=0;j<16;j++) { - for (int i=0;i<16;i++) { - m_MiniPatches[j][i].m_Parent=this; - } - } - - CalcBounds(); -} - -/////////////////////////////////////////////////////////////////////////////// -// CalcBounds: calculating the bounds of this patch -void CPatch::CalcBounds() -{ - m_Bounds.SetEmpty(); - - for (int j=0;jCalcPosition(m_X*PATCH_SIZE+i,m_Z*PATCH_SIZE+j,pos); - m_Bounds+=pos; - } - } -} - +/////////////////////////////////////////////////////////////////////////////// +// +// Name: ModelDef.cpp +// Author: Rich Cross +// Contact: rich@wildfiregames.com +// +/////////////////////////////////////////////////////////////////////////////// + +#include "Patch.h" +#include "Terrain.h" + + +/////////////////////////////////////////////////////////////////////////////// +// CPatch constructor +CPatch::CPatch() : m_Parent(0) +{ +} + +/////////////////////////////////////////////////////////////////////////////// +// CPatch destructor +CPatch::~CPatch() +{ +} + +/////////////////////////////////////////////////////////////////////////////// +// Initialize: setup patch data +void CPatch::Initialize(CTerrain* parent,u32 x,u32 z) +{ + delete m_RenderData; + m_RenderData=0; + + m_Parent=parent; + m_X=x; + m_Z=z; + + // set parent of each patch + for (int j=0;j<16;j++) { + for (int i=0;i<16;i++) { + m_MiniPatches[j][i].m_Parent=this; + } + } + + CalcBounds(); +} + +/////////////////////////////////////////////////////////////////////////////// +// CalcBounds: calculating the bounds of this patch +void CPatch::CalcBounds() +{ + m_Bounds.SetEmpty(); + + for (int j=0;jCalcPosition(m_X*PATCH_SIZE+i,m_Z*PATCH_SIZE+j,pos); + m_Bounds+=pos; + } + } +} + diff --git a/source/terrain/Patch.h b/source/terrain/Patch.h index ba23c3c88b..d6e735bfdf 100755 --- a/source/terrain/Patch.h +++ b/source/terrain/Patch.h @@ -1,42 +1,42 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Name: Patch.h -// Author: Rich Cross -// Contact: rich@wildfiregames.com -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef _PATCH_H -#define _PATCH_H - -#include "MiniPatch.h" -#include "RenderableObject.h" - -class CTerrain; - -/////////////////////////////////////////////////////////////////////////////// -// CPatch: a single terrain patch, 16 tiles square -class CPatch : public CRenderableObject -{ -public: - // constructor - CPatch(); - // destructor - ~CPatch(); - - // initialize the patch - void Initialize(CTerrain* parent,u32 x,u32 z); - // calculate and store bounds of this patch - void CalcBounds(); - -public: - // minipatches (tiles) making up the patch - CMiniPatch m_MiniPatches[16][16]; - // position of patch in parent terrain grid - u32 m_X,m_Z; - // parent terrain - CTerrain* m_Parent; -}; - - -#endif +/////////////////////////////////////////////////////////////////////////////// +// +// Name: Patch.h +// Author: Rich Cross +// Contact: rich@wildfiregames.com +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _PATCH_H +#define _PATCH_H + +#include "MiniPatch.h" +#include "RenderableObject.h" + +class CTerrain; + +/////////////////////////////////////////////////////////////////////////////// +// CPatch: a single terrain patch, 16 tiles square +class CPatch : public CRenderableObject +{ +public: + // constructor + CPatch(); + // destructor + ~CPatch(); + + // initialize the patch + void Initialize(CTerrain* parent,u32 x,u32 z); + // calculate and store bounds of this patch + void CalcBounds(); + +public: + // minipatches (tiles) making up the patch + CMiniPatch m_MiniPatches[16][16]; + // position of patch in parent terrain grid + u32 m_X,m_Z; + // parent terrain + CTerrain* m_Parent; +}; + + +#endif diff --git a/source/terrain/PatchRData.cpp b/source/terrain/PatchRData.cpp index 54349bda12..2828e8923e 100755 --- a/source/terrain/PatchRData.cpp +++ b/source/terrain/PatchRData.cpp @@ -1,553 +1,553 @@ -#pragma warning(disable:4786) - -#include -#include -#include -#include "res/tex.h" -#include "Renderer.h" -#include "PatchRData.h" -#include "AlphaMapCalculator.h" - -const int BlendOffsets[8][2] = { - { 0, -1 }, - { -1, -1 }, - { -1, 0 }, - { -1, 1 }, - { 0, 1 }, - { 1, 1 }, - { 1, 0 }, - { 1, -1 } -}; - - -CPatchRData::CPatchRData(CPatch* patch) : m_Patch(patch), m_Vertices(0), m_VBBase(0), m_VBBlends(0) -{ - assert(patch); - Build(); -} - -CPatchRData::~CPatchRData() -{ - delete[] m_Vertices; -} - - -static Handle GetTerrainTileTexture(CTerrain* terrain,int gx,int gz) -{ - CMiniPatch* mp=terrain->GetTile(gx,gz); - return mp ? mp->Tex1 : 0; -} - -bool QueryAdjacency(int x,int y,Handle h,Handle* texgrid) -{ - for (int j=y-1;j<=y+1;j++) { - for (int i=x-1;i<=x+1;i++) { - if (i<0 || i>PATCH_SIZE+1 || j<0 || j>PATCH_SIZE+1) { - continue; - } - - if (texgrid[j*(PATCH_SIZE+2)+i]==h) { - return true; - } - } - } - return false; -} - -struct STmpSplat { - Handle m_Texture; - u16 m_Indices[4]; -}; - -void CPatchRData::BuildBlends() -{ - m_BlendIndices.clear(); - m_BlendSplats.clear(); - m_BlendVertices.clear(); - - // get index of this patch - int px=m_Patch->m_X; - int pz=m_Patch->m_Z; - - CTerrain* terrain=m_Patch->m_Parent; - - // temporary list of splats - std::vector splats; - // set of textures used for splats - std::set splatTextures; - - // for each tile in patch .. - for (int j=0;jm_MiniPatches[j][i]; - mp->GetTileIndex(gx,gz); - - // build list of textures of higher priority than current tile that are used by neighbouring tiles - std::vector neighbourTextures; - for (int m=-1;m<=1;m++) { - for (int k=-1;k<=1;k++) { - CMiniPatch* nmp=terrain->GetTile(gx+k,gz+m); - if (nmp) { - if (nmp->Tex1Priority>mp->Tex1Priority || (nmp->Tex1Priority==mp->Tex1Priority && nmp->Tex1>mp->Tex1)) { - STex tex; - tex.m_Handle=nmp->Tex1; - tex.m_Priority=nmp->Tex1Priority; - if (std::find(neighbourTextures.begin(),neighbourTextures.end(),tex)==neighbourTextures.end()) { - neighbourTextures.push_back(tex); - } - } - } - } - } - if (neighbourTextures.size()>0) { - u32 count=neighbourTextures.size(); - // sort textures from lowest to highest priority - std::sort(neighbourTextures.begin(),neighbourTextures.end()); - - // for each of the neighbouring textures .. - for (uint k=0;k::iterator iter=splatTextures.begin(); - for (;iter!=splatTextures.end();++iter) { - Handle tex=*iter; - - SSplat& splat=m_BlendSplats[splatCount]; - splat.m_IndexStart=m_BlendIndices.size(); - splat.m_Texture=tex; - - for (uint k=0;k textures; - Handle texgrid[PATCH_SIZE][PATCH_SIZE]; - for (int j=0;jm_MiniPatches[j][i].Tex1; - texgrid[j][i]=h; - if (std::find(textures.begin(),textures.end(),h)==textures.end()) { - textures.push_back(h); - } - } - } - - // now build base splats from interior textures - m_Splats.resize(textures.size()); - - for (uint i=0;imax) return max; - else return x; -} - -static SColor4ub ConvertColor(const RGBColor& src) -{ - SColor4ub result; - result.R=clamp(int(src.X*255),0,255); - result.G=clamp(int(src.Y*255),0,255); - result.B=clamp(int(src.Z*255),0,255); - result.A=0xff; - return result; -} - -static void BuildHeightmapNormals(int size,u16 *heightmap,CVector3D* normals) -{ - int x, y; - int sm=size-1; - - for(y = 0;y < size; y++) - for(x = 0; x < size; x++) { - - // Access current normalmap grid point - CVector3D* N = &normals[y*size+x]; - - // Compute normal by using the height differential - u16 h1=(x==sm) ? heightmap[y*size+x] : heightmap[y*size+x+1]; - u16 h2=(y==sm) ? heightmap[y*size+x] : heightmap[(y+1)*size+x]; - u16 h3=(x==0) ? heightmap[y*size+x] : heightmap[y*size+x-1]; - u16 h4=(y==0) ? heightmap[y*size+x] : heightmap[(y-1)*size+x+1]; - N->X = (h3-h1)*HEIGHT_SCALE; - N->Y = CELL_SIZE; - N->Z = (h4-h2)*HEIGHT_SCALE; - - // Normalize it - float len=N->GetLength(); - if (len>0) { - (*N)*=1.0f/len; - } else { - *N=CVector3D(0,0,0); - } - } -} - -void CPatchRData::BuildVertices() -{ - // number of vertices in each direction in each patch - int vsize=PATCH_SIZE+1; - - if (!m_Vertices) { - m_Vertices=new SBaseVertex[vsize*vsize]; - } - SBaseVertex* vertices=m_Vertices; - - - // get index of this patch - u32 px=m_Patch->m_X; - u32 pz=m_Patch->m_Z; - - CTerrain* terrain=m_Patch->m_Parent; - u32 mapSize=terrain->GetVerticesPerSide(); - - // build vertices - for (int j=0; jCalcPosition(ix,iz,pos); - terrain->CalcNormal(ix,iz,normal); - - RGBColor c; - g_Renderer.m_SHCoeffsTerrain.Evaluate(normal,c); - - int v=(j*vsize)+i; - vertices[v].m_UVs[0]=i*0.125f; - vertices[v].m_UVs[1]=j*0.125f; - vertices[v].m_Color=ConvertColor(c); - vertices[v].m_Position=pos; - } - } - - if (g_Renderer.m_Caps.m_VBO) { - if (!m_VBBase) { - glGenBuffersARB(1,(GLuint*) &m_VBBase); - glBindBufferARB(GL_ARRAY_BUFFER_ARB,m_VBBase); - glBufferDataARB(GL_ARRAY_BUFFER_ARB,vsize*vsize*sizeof(SBaseVertex),0,GL_STATIC_DRAW_ARB); - } - glBindBufferARB(GL_ARRAY_BUFFER_ARB,m_VBBase); - glBufferSubDataARB(GL_ARRAY_BUFFER_ARB,0,vsize*vsize*sizeof(SBaseVertex),m_Vertices); - } -} - -void CPatchRData::Build() -{ - BuildVertices(); - BuildIndices(); - BuildBlends(); -} - -void CPatchRData::Update() -{ - if (m_UpdateFlags!=0) { - // TODO,RC 11/04/04 - need to only rebuild necessary bits of renderdata rather - // than everything; it's complicated slightly because the blends are dependent - // on both vertex and index data - BuildVertices(); - BuildIndices(); - BuildBlends(); - - m_UpdateFlags=0; - } -} - -void CPatchRData::RenderBase() -{ - assert(m_UpdateFlags==0); - - u8* base; - if (g_Renderer.m_Caps.m_VBO) { - glBindBufferARB(GL_ARRAY_BUFFER_ARB,m_VBBase); - base=0; - } else { - base=(u8*) &m_Vertices[0]; - } - - // setup data pointers - u32 stride=sizeof(SBaseVertex); - glVertexPointer(3,GL_FLOAT,stride,base+offsetof(SBaseVertex,m_Position)); - glColorPointer(4,GL_UNSIGNED_BYTE,stride,base+offsetof(SBaseVertex,m_Color)); - glTexCoordPointer(2,GL_FLOAT,stride,base+offsetof(SBaseVertex,m_UVs[0])); - - // render each splat - for (uint i=0;i +#include +#include +#include "res/tex.h" +#include "Renderer.h" +#include "PatchRData.h" +#include "AlphaMapCalculator.h" + +const int BlendOffsets[8][2] = { + { 0, -1 }, + { -1, -1 }, + { -1, 0 }, + { -1, 1 }, + { 0, 1 }, + { 1, 1 }, + { 1, 0 }, + { 1, -1 } +}; + + +CPatchRData::CPatchRData(CPatch* patch) : m_Patch(patch), m_Vertices(0), m_VBBase(0), m_VBBlends(0) +{ + assert(patch); + Build(); +} + +CPatchRData::~CPatchRData() +{ + delete[] m_Vertices; +} + + +static Handle GetTerrainTileTexture(CTerrain* terrain,int gx,int gz) +{ + CMiniPatch* mp=terrain->GetTile(gx,gz); + return mp ? mp->Tex1 : 0; +} + +bool QueryAdjacency(int x,int y,Handle h,Handle* texgrid) +{ + for (int j=y-1;j<=y+1;j++) { + for (int i=x-1;i<=x+1;i++) { + if (i<0 || i>PATCH_SIZE+1 || j<0 || j>PATCH_SIZE+1) { + continue; + } + + if (texgrid[j*(PATCH_SIZE+2)+i]==h) { + return true; + } + } + } + return false; +} + +struct STmpSplat { + Handle m_Texture; + u16 m_Indices[4]; +}; + +void CPatchRData::BuildBlends() +{ + m_BlendIndices.clear(); + m_BlendSplats.clear(); + m_BlendVertices.clear(); + + // get index of this patch + int px=m_Patch->m_X; + int pz=m_Patch->m_Z; + + CTerrain* terrain=m_Patch->m_Parent; + + // temporary list of splats + std::vector splats; + // set of textures used for splats + std::set splatTextures; + + // for each tile in patch .. + for (int j=0;jm_MiniPatches[j][i]; + mp->GetTileIndex(gx,gz); + + // build list of textures of higher priority than current tile that are used by neighbouring tiles + std::vector neighbourTextures; + for (int m=-1;m<=1;m++) { + for (int k=-1;k<=1;k++) { + CMiniPatch* nmp=terrain->GetTile(gx+k,gz+m); + if (nmp) { + if (nmp->Tex1Priority>mp->Tex1Priority || (nmp->Tex1Priority==mp->Tex1Priority && nmp->Tex1>mp->Tex1)) { + STex tex; + tex.m_Handle=nmp->Tex1; + tex.m_Priority=nmp->Tex1Priority; + if (std::find(neighbourTextures.begin(),neighbourTextures.end(),tex)==neighbourTextures.end()) { + neighbourTextures.push_back(tex); + } + } + } + } + } + if (neighbourTextures.size()>0) { + u32 count=neighbourTextures.size(); + // sort textures from lowest to highest priority + std::sort(neighbourTextures.begin(),neighbourTextures.end()); + + // for each of the neighbouring textures .. + for (uint k=0;k::iterator iter=splatTextures.begin(); + for (;iter!=splatTextures.end();++iter) { + Handle tex=*iter; + + SSplat& splat=m_BlendSplats[splatCount]; + splat.m_IndexStart=m_BlendIndices.size(); + splat.m_Texture=tex; + + for (uint k=0;k textures; + Handle texgrid[PATCH_SIZE][PATCH_SIZE]; + for (int j=0;jm_MiniPatches[j][i].Tex1; + texgrid[j][i]=h; + if (std::find(textures.begin(),textures.end(),h)==textures.end()) { + textures.push_back(h); + } + } + } + + // now build base splats from interior textures + m_Splats.resize(textures.size()); + + for (uint i=0;imax) return max; + else return x; +} + +static SColor4ub ConvertColor(const RGBColor& src) +{ + SColor4ub result; + result.R=clamp(int(src.X*255),0,255); + result.G=clamp(int(src.Y*255),0,255); + result.B=clamp(int(src.Z*255),0,255); + result.A=0xff; + return result; +} + +static void BuildHeightmapNormals(int size,u16 *heightmap,CVector3D* normals) +{ + int x, y; + int sm=size-1; + + for(y = 0;y < size; y++) + for(x = 0; x < size; x++) { + + // Access current normalmap grid point + CVector3D* N = &normals[y*size+x]; + + // Compute normal by using the height differential + u16 h1=(x==sm) ? heightmap[y*size+x] : heightmap[y*size+x+1]; + u16 h2=(y==sm) ? heightmap[y*size+x] : heightmap[(y+1)*size+x]; + u16 h3=(x==0) ? heightmap[y*size+x] : heightmap[y*size+x-1]; + u16 h4=(y==0) ? heightmap[y*size+x] : heightmap[(y-1)*size+x+1]; + N->X = (h3-h1)*HEIGHT_SCALE; + N->Y = CELL_SIZE; + N->Z = (h4-h2)*HEIGHT_SCALE; + + // Normalize it + float len=N->GetLength(); + if (len>0) { + (*N)*=1.0f/len; + } else { + *N=CVector3D(0,0,0); + } + } +} + +void CPatchRData::BuildVertices() +{ + // number of vertices in each direction in each patch + int vsize=PATCH_SIZE+1; + + if (!m_Vertices) { + m_Vertices=new SBaseVertex[vsize*vsize]; + } + SBaseVertex* vertices=m_Vertices; + + + // get index of this patch + u32 px=m_Patch->m_X; + u32 pz=m_Patch->m_Z; + + CTerrain* terrain=m_Patch->m_Parent; + u32 mapSize=terrain->GetVerticesPerSide(); + + // build vertices + for (int j=0; jCalcPosition(ix,iz,pos); + terrain->CalcNormal(ix,iz,normal); + + RGBColor c; + g_Renderer.m_SHCoeffsTerrain.Evaluate(normal,c); + + int v=(j*vsize)+i; + vertices[v].m_UVs[0]=i*0.125f; + vertices[v].m_UVs[1]=j*0.125f; + vertices[v].m_Color=ConvertColor(c); + vertices[v].m_Position=pos; + } + } + + if (g_Renderer.m_Caps.m_VBO) { + if (!m_VBBase) { + glGenBuffersARB(1,(GLuint*) &m_VBBase); + glBindBufferARB(GL_ARRAY_BUFFER_ARB,m_VBBase); + glBufferDataARB(GL_ARRAY_BUFFER_ARB,vsize*vsize*sizeof(SBaseVertex),0,GL_STATIC_DRAW_ARB); + } + glBindBufferARB(GL_ARRAY_BUFFER_ARB,m_VBBase); + glBufferSubDataARB(GL_ARRAY_BUFFER_ARB,0,vsize*vsize*sizeof(SBaseVertex),m_Vertices); + } +} + +void CPatchRData::Build() +{ + BuildVertices(); + BuildIndices(); + BuildBlends(); +} + +void CPatchRData::Update() +{ + if (m_UpdateFlags!=0) { + // TODO,RC 11/04/04 - need to only rebuild necessary bits of renderdata rather + // than everything; it's complicated slightly because the blends are dependent + // on both vertex and index data + BuildVertices(); + BuildIndices(); + BuildBlends(); + + m_UpdateFlags=0; + } +} + +void CPatchRData::RenderBase() +{ + assert(m_UpdateFlags==0); + + u8* base; + if (g_Renderer.m_Caps.m_VBO) { + glBindBufferARB(GL_ARRAY_BUFFER_ARB,m_VBBase); + base=0; + } else { + base=(u8*) &m_Vertices[0]; + } + + // setup data pointers + u32 stride=sizeof(SBaseVertex); + glVertexPointer(3,GL_FLOAT,stride,base+offsetof(SBaseVertex,m_Position)); + glColorPointer(4,GL_UNSIGNED_BYTE,stride,base+offsetof(SBaseVertex,m_Color)); + glTexCoordPointer(2,GL_FLOAT,stride,base+offsetof(SBaseVertex,m_UVs[0])); + + // render each splat + for (uint i=0;i -#include "res/res.h" -#include "Color.h" -#include "Vector3D.h" -#include "RenderableObject.h" - -class CPatch; - -class CPatchRData : public CRenderData -{ -public: - CPatchRData(CPatch* patch); - ~CPatchRData(); - - void Update(); - void RenderBase(); - void RenderBlends(); - void RenderOutline(); - void RenderStreams(u32 streamflags); - -private: - // build this renderdata object - void Build(); - - void BuildBlends(); - void BuildIndices(); - void BuildVertices(); - - struct SSplat { - SSplat() : m_Texture(0), m_IndexCount(0) {} - - // handle of texture to apply during splat - Handle m_Texture; - // offset into the index array for this patch where splat starts - u32 m_IndexStart; - // number of indices used by splat - u32 m_IndexCount; - }; - - struct SBaseVertex { - // vertex position - CVector3D m_Position; - // vertex color - SColor4ub m_Color; - // vertex uvs for base texture - float m_UVs[2]; - }; - - struct SBlendVertex { - // vertex position - CVector3D m_Position; - // vertex color - SColor4ub m_Color; - // vertex uvs for base texture - float m_UVs[2]; - // vertex uvs for alpha texture - float m_AlphaUVs[2]; - }; - - struct STex { - bool operator==(const STex& rhs) const { return m_Handle==rhs.m_Handle; } - bool operator<(const STex& rhs) const { return m_Priority m_Indices; - // list of base splats to apply to this patch - std::vector m_Splats; - // vertices to use for blending transition texture passes - std::vector m_BlendVertices; - // indices into blend vertices for the blend splats - std::vector m_BlendIndices; - // splats used in blend pass - std::vector m_BlendSplats; -}; - - -#endif +#ifndef _PATCHRDATA_H +#define _PATCHRDATA_H + +#include +#include "res/res.h" +#include "Color.h" +#include "Vector3D.h" +#include "RenderableObject.h" + +class CPatch; + +class CPatchRData : public CRenderData +{ +public: + CPatchRData(CPatch* patch); + ~CPatchRData(); + + void Update(); + void RenderBase(); + void RenderBlends(); + void RenderOutline(); + void RenderStreams(u32 streamflags); + +private: + // build this renderdata object + void Build(); + + void BuildBlends(); + void BuildIndices(); + void BuildVertices(); + + struct SSplat { + SSplat() : m_Texture(0), m_IndexCount(0) {} + + // handle of texture to apply during splat + Handle m_Texture; + // offset into the index array for this patch where splat starts + u32 m_IndexStart; + // number of indices used by splat + u32 m_IndexCount; + }; + + struct SBaseVertex { + // vertex position + CVector3D m_Position; + // vertex color + SColor4ub m_Color; + // vertex uvs for base texture + float m_UVs[2]; + }; + + struct SBlendVertex { + // vertex position + CVector3D m_Position; + // vertex color + SColor4ub m_Color; + // vertex uvs for base texture + float m_UVs[2]; + // vertex uvs for alpha texture + float m_AlphaUVs[2]; + }; + + struct STex { + bool operator==(const STex& rhs) const { return m_Handle==rhs.m_Handle; } + bool operator<(const STex& rhs) const { return m_Priority m_Indices; + // list of base splats to apply to this patch + std::vector m_Splats; + // vertices to use for blending transition texture passes + std::vector m_BlendVertices; + // indices into blend vertices for the blend splats + std::vector m_BlendIndices; + // splats used in blend pass + std::vector m_BlendSplats; +}; + + +#endif diff --git a/source/terrain/Quaternion.cpp b/source/terrain/Quaternion.cpp index e81625cb62..f9e7cb0424 100755 --- a/source/terrain/Quaternion.cpp +++ b/source/terrain/Quaternion.cpp @@ -1,189 +1,189 @@ -/************************************************************ - * - * File Name: Quaternion.Cpp - * - * Description: - * - ************************************************************/ - -#include "Quaternion.h" - -const float EPSILON=0.0001f; - - -CQuaternion::CQuaternion() -{ - m_V.Clear (); - m_W = 0; -} - -//quaternion addition -CQuaternion CQuaternion::operator + (CQuaternion &quat) -{ - CQuaternion Temp; - - Temp.m_W = m_W + quat.m_W; - Temp.m_V = m_V + quat.m_V; - - return Temp; -} - -//quaternion addition/assignment -CQuaternion &CQuaternion::operator += (CQuaternion &quat) -{ - m_W += quat.m_W; - m_V += quat.m_V; - - return (*this); -} - -//quaternion multiplication -CQuaternion CQuaternion::operator * (CQuaternion &quat) -{ - CQuaternion Temp; - - Temp.m_W = (m_W * quat.m_W) - (m_V.Dot(quat.m_V)); - Temp.m_V = (m_V.Cross(quat.m_V)) + (quat.m_V * m_W) + (m_V * quat.m_W); - - return Temp; -} - -//quaternion multiplication/assignment -CQuaternion &CQuaternion::operator *= (CQuaternion &quat) -{ - (*this) = (*this) * quat; - - return (*this); -} - - -void CQuaternion::FromEularAngles (float x, float y, float z) -{ - float cr, cp, cy; - float sr, sp, sy; - - CQuaternion QRoll, QPitch, QYaw; - - cr = cosf(x * 0.5f); - cp = cosf(y * 0.5f); - cy = cosf(z * 0.5f); - - sr = sinf(x * 0.5f); - sp = sinf(y * 0.5f); - sy = sinf(z * 0.5f); - - QRoll.m_V.Set (sr,0,0); - QRoll.m_W = cr; - - QPitch.m_V.Set (0,sp,0); - QPitch.m_W = cp; - - QYaw.m_V.Set (0,0,sy); - QYaw.m_W = cy; - - (*this) = QYaw * QPitch * QRoll; -} - -CMatrix3D CQuaternion::ToMatrix () const -{ - CMatrix3D result; - ToMatrix(result); - return result; -} - -void CQuaternion::ToMatrix(CMatrix3D& result) const -{ - float x2, y2, z2; - float wx, wy, wz, xx, xy, xz, yy, yz, zz; - - // calculate coefficients - x2 = m_V.X + m_V.X; - y2 = m_V.Y + m_V.Y; - z2 = m_V.Z + m_V.Z; - - xx = m_V.X * x2; - xy = m_V.X * y2; - xz = m_V.X * z2; - - yy = m_V.Y * y2; - yz = m_V.Y * z2; - - zz = m_V.Z * z2; - - wx = m_W * x2; - wy = m_W * y2; - wz = m_W * z2; - - result._11 = 1.0f - (yy + zz); - result._12 = xy - wz; - result._13 = xz + wy; - result._14 = 0; - - result._21 = xy + wz; - result._22 = 1.0f - (xx + zz); - result._23 = yz - wx; - result._24 = 0; - - result._31 = xz - wy; - result._32 = yz + wx; - result._33 = 1.0f - (xx + yy); - result._34 = 0; - - result._41 = 0; - result._42 = 0; - result._43 = 0; - result._44 = 1; -} - -void CQuaternion::Slerp(const CQuaternion& from,const CQuaternion& to, float ratio) -{ - float to1[4]; - float omega, cosom, sinom, scale0, scale1; - - // calc cosine - cosom = from.m_V.X * to.m_V.X + - from.m_V.Y * to.m_V.Y + - from.m_V.Z * to.m_V.Z + - from.m_W * to.m_W; - - - // adjust signs (if necessary) - if (cosom < 0.0) - { - cosom = -cosom; - to1[0] = -to.m_V.X; - to1[1] = -to.m_V.Y; - to1[2] = -to.m_V.Z; - to1[3] = -to.m_W; - } - else - { - to1[0] = to.m_V.X; - to1[1] = to.m_V.Y; - to1[2] = to.m_V.Z; - to1[3] = to.m_W; - } - - // calculate coefficients - if ((1.0f - cosom) > EPSILON) - { - // standard case (slerp) - omega = acosf(cosom); - sinom = sinf(omega); - scale0 = sinf((1.0f - ratio) * omega) / sinom; - scale1 = sinf(ratio * omega) / sinom; - } - else - { - // "from" and "to" quaternions are very close - // ... so we can do a linear interpolation - scale0 = 1.0f - ratio; - scale1 = ratio; - } - - // calculate final values - m_V.X = scale0 * from.m_V.X + scale1 * to1[0]; - m_V.Y = scale0 * from.m_V.Y + scale1 * to1[1]; - m_V.Z = scale0 * from.m_V.Z + scale1 * to1[2]; - m_W = scale0 * from.m_W + scale1 * to1[3]; -} +/************************************************************ + * + * File Name: Quaternion.Cpp + * + * Description: + * + ************************************************************/ + +#include "Quaternion.h" + +const float EPSILON=0.0001f; + + +CQuaternion::CQuaternion() +{ + m_V.Clear (); + m_W = 0; +} + +//quaternion addition +CQuaternion CQuaternion::operator + (CQuaternion &quat) +{ + CQuaternion Temp; + + Temp.m_W = m_W + quat.m_W; + Temp.m_V = m_V + quat.m_V; + + return Temp; +} + +//quaternion addition/assignment +CQuaternion &CQuaternion::operator += (CQuaternion &quat) +{ + m_W += quat.m_W; + m_V += quat.m_V; + + return (*this); +} + +//quaternion multiplication +CQuaternion CQuaternion::operator * (CQuaternion &quat) +{ + CQuaternion Temp; + + Temp.m_W = (m_W * quat.m_W) - (m_V.Dot(quat.m_V)); + Temp.m_V = (m_V.Cross(quat.m_V)) + (quat.m_V * m_W) + (m_V * quat.m_W); + + return Temp; +} + +//quaternion multiplication/assignment +CQuaternion &CQuaternion::operator *= (CQuaternion &quat) +{ + (*this) = (*this) * quat; + + return (*this); +} + + +void CQuaternion::FromEularAngles (float x, float y, float z) +{ + float cr, cp, cy; + float sr, sp, sy; + + CQuaternion QRoll, QPitch, QYaw; + + cr = cosf(x * 0.5f); + cp = cosf(y * 0.5f); + cy = cosf(z * 0.5f); + + sr = sinf(x * 0.5f); + sp = sinf(y * 0.5f); + sy = sinf(z * 0.5f); + + QRoll.m_V.Set (sr,0,0); + QRoll.m_W = cr; + + QPitch.m_V.Set (0,sp,0); + QPitch.m_W = cp; + + QYaw.m_V.Set (0,0,sy); + QYaw.m_W = cy; + + (*this) = QYaw * QPitch * QRoll; +} + +CMatrix3D CQuaternion::ToMatrix () const +{ + CMatrix3D result; + ToMatrix(result); + return result; +} + +void CQuaternion::ToMatrix(CMatrix3D& result) const +{ + float x2, y2, z2; + float wx, wy, wz, xx, xy, xz, yy, yz, zz; + + // calculate coefficients + x2 = m_V.X + m_V.X; + y2 = m_V.Y + m_V.Y; + z2 = m_V.Z + m_V.Z; + + xx = m_V.X * x2; + xy = m_V.X * y2; + xz = m_V.X * z2; + + yy = m_V.Y * y2; + yz = m_V.Y * z2; + + zz = m_V.Z * z2; + + wx = m_W * x2; + wy = m_W * y2; + wz = m_W * z2; + + result._11 = 1.0f - (yy + zz); + result._12 = xy - wz; + result._13 = xz + wy; + result._14 = 0; + + result._21 = xy + wz; + result._22 = 1.0f - (xx + zz); + result._23 = yz - wx; + result._24 = 0; + + result._31 = xz - wy; + result._32 = yz + wx; + result._33 = 1.0f - (xx + yy); + result._34 = 0; + + result._41 = 0; + result._42 = 0; + result._43 = 0; + result._44 = 1; +} + +void CQuaternion::Slerp(const CQuaternion& from,const CQuaternion& to, float ratio) +{ + float to1[4]; + float omega, cosom, sinom, scale0, scale1; + + // calc cosine + cosom = from.m_V.X * to.m_V.X + + from.m_V.Y * to.m_V.Y + + from.m_V.Z * to.m_V.Z + + from.m_W * to.m_W; + + + // adjust signs (if necessary) + if (cosom < 0.0) + { + cosom = -cosom; + to1[0] = -to.m_V.X; + to1[1] = -to.m_V.Y; + to1[2] = -to.m_V.Z; + to1[3] = -to.m_W; + } + else + { + to1[0] = to.m_V.X; + to1[1] = to.m_V.Y; + to1[2] = to.m_V.Z; + to1[3] = to.m_W; + } + + // calculate coefficients + if ((1.0f - cosom) > EPSILON) + { + // standard case (slerp) + omega = acosf(cosom); + sinom = sinf(omega); + scale0 = sinf((1.0f - ratio) * omega) / sinom; + scale1 = sinf(ratio * omega) / sinom; + } + else + { + // "from" and "to" quaternions are very close + // ... so we can do a linear interpolation + scale0 = 1.0f - ratio; + scale1 = ratio; + } + + // calculate final values + m_V.X = scale0 * from.m_V.X + scale1 * to1[0]; + m_V.Y = scale0 * from.m_V.Y + scale1 * to1[1]; + m_V.Z = scale0 * from.m_V.Z + scale1 * to1[2]; + m_W = scale0 * from.m_W + scale1 * to1[3]; +} diff --git a/source/terrain/Quaternion.h b/source/terrain/Quaternion.h index d2df6e7a1c..d45b6fa7dd 100755 --- a/source/terrain/Quaternion.h +++ b/source/terrain/Quaternion.h @@ -1,43 +1,43 @@ -/************************************************************ - * - * File Name: Quaternion.H - * - * Description: - * - ************************************************************/ - -#ifndef QUATERNION_H -#define QUATERNION_H - -#include "Matrix3D.h" - -class CQuaternion -{ - public: - CVector3D m_V; - float m_W; - - public: - CQuaternion(); - - //quaternion addition - CQuaternion operator + (CQuaternion &quat); - //quaternion addition/assignment - CQuaternion &operator += (CQuaternion &quat); - - //quaternion multiplication - CQuaternion operator * (CQuaternion &quat); - //quaternion multiplication/assignment - CQuaternion &operator *= (CQuaternion &quat); - - void FromEularAngles (float x, float y, float z); - - //convert the quaternion to matrix - CMatrix3D ToMatrix() const; - void ToMatrix(CMatrix3D& result) const; - - //sphere interpolation - void Slerp(const CQuaternion& from,const CQuaternion& to, float ratio); -}; - -#endif +/************************************************************ + * + * File Name: Quaternion.H + * + * Description: + * + ************************************************************/ + +#ifndef QUATERNION_H +#define QUATERNION_H + +#include "Matrix3D.h" + +class CQuaternion +{ + public: + CVector3D m_V; + float m_W; + + public: + CQuaternion(); + + //quaternion addition + CQuaternion operator + (CQuaternion &quat); + //quaternion addition/assignment + CQuaternion &operator += (CQuaternion &quat); + + //quaternion multiplication + CQuaternion operator * (CQuaternion &quat); + //quaternion multiplication/assignment + CQuaternion &operator *= (CQuaternion &quat); + + void FromEularAngles (float x, float y, float z); + + //convert the quaternion to matrix + CMatrix3D ToMatrix() const; + void ToMatrix(CMatrix3D& result) const; + + //sphere interpolation + void Slerp(const CQuaternion& from,const CQuaternion& to, float ratio); +}; + +#endif diff --git a/source/terrain/RenderableObject.h b/source/terrain/RenderableObject.h index 4b4e5969f7..4fa31025b8 100755 --- a/source/terrain/RenderableObject.h +++ b/source/terrain/RenderableObject.h @@ -1,94 +1,94 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Name: RenderableObject.h -// Author: Rich Cross -// Contact: rich@wildfiregames.com -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef _RENDERABLEOBJECT_H -#define _RENDERABLEOBJECT_H - -#include -#include "res/res.h" -#include "terrain/Bound.h" -#include "terrain/Matrix3D.h" - - -// dirty flags - used as notification to the renderer that some bit of data -// need updating -#define RENDERDATA_UPDATE_VERTICES (1<<1) -#define RENDERDATA_UPDATE_INDICES (1<<2) - - -/////////////////////////////////////////////////////////////////////////////// -// CRenderData: base class of all the renderer's renderdata classes - the -// derived class stores necessary information for rendering an object of a -// particular type -class CRenderData -{ -public: - CRenderData() : m_UpdateFlags(0) {} - virtual ~CRenderData() {} - - u32 m_UpdateFlags; -}; - -/////////////////////////////////////////////////////////////////////////////// -// CRenderableObject: base class of all renderable objects - patches, models, -// sprites, etc; stores position and bound information, and a pointer to -// some renderdata necessary for the renderer to actually render it -class CRenderableObject -{ -public: - // constructor - CRenderableObject() : m_RenderData(0) { - m_Transform.SetIdentity(); - } - // destructor - virtual ~CRenderableObject() { delete m_RenderData; } - - // set object transform - void SetTransform(const CMatrix3D& transform) { - m_Transform=transform; - CalcBounds(); - } - // get object transform - const CMatrix3D& GetTransform() const { return m_Transform; } - - // mark some part of the renderdata as dirty, and requiring - // an update on next render - void SetDirty(u32 dirtyflags) { - if (m_RenderData) m_RenderData->m_UpdateFlags|=dirtyflags; - } - - // calculate (and store in m_Bounds) the world space bounds of this object - // - must be implemented by all concrete subclasses - virtual void CalcBounds() = 0; - - // return world space bounds of this object - const CBound& GetBounds() const { return m_Bounds; } - - // set the object renderdata - // TODO,RC 10/04/04 - need to delete existing renderdata here, or can we - // assume the renderer won't set renderdata when an object already has it? - // - just assert we've no renderdata at the minute - void SetRenderData(CRenderData* renderdata) { - assert(m_RenderData==0); - m_RenderData=renderdata; - } - - // return object renderdata - can be null if renderer hasn't yet - // created the renderdata - CRenderData* GetRenderData() { return m_RenderData; } - -protected: - // object bounds - CBound m_Bounds; - // local->world space transform - CMatrix3D m_Transform; - // object renderdata - CRenderData* m_RenderData; -}; - -#endif +/////////////////////////////////////////////////////////////////////////////// +// +// Name: RenderableObject.h +// Author: Rich Cross +// Contact: rich@wildfiregames.com +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _RENDERABLEOBJECT_H +#define _RENDERABLEOBJECT_H + +#include +#include "res/res.h" +#include "terrain/Bound.h" +#include "terrain/Matrix3D.h" + + +// dirty flags - used as notification to the renderer that some bit of data +// need updating +#define RENDERDATA_UPDATE_VERTICES (1<<1) +#define RENDERDATA_UPDATE_INDICES (1<<2) + + +/////////////////////////////////////////////////////////////////////////////// +// CRenderData: base class of all the renderer's renderdata classes - the +// derived class stores necessary information for rendering an object of a +// particular type +class CRenderData +{ +public: + CRenderData() : m_UpdateFlags(0) {} + virtual ~CRenderData() {} + + u32 m_UpdateFlags; +}; + +/////////////////////////////////////////////////////////////////////////////// +// CRenderableObject: base class of all renderable objects - patches, models, +// sprites, etc; stores position and bound information, and a pointer to +// some renderdata necessary for the renderer to actually render it +class CRenderableObject +{ +public: + // constructor + CRenderableObject() : m_RenderData(0) { + m_Transform.SetIdentity(); + } + // destructor + virtual ~CRenderableObject() { delete m_RenderData; } + + // set object transform + void SetTransform(const CMatrix3D& transform) { + m_Transform=transform; + CalcBounds(); + } + // get object transform + const CMatrix3D& GetTransform() const { return m_Transform; } + + // mark some part of the renderdata as dirty, and requiring + // an update on next render + void SetDirty(u32 dirtyflags) { + if (m_RenderData) m_RenderData->m_UpdateFlags|=dirtyflags; + } + + // calculate (and store in m_Bounds) the world space bounds of this object + // - must be implemented by all concrete subclasses + virtual void CalcBounds() = 0; + + // return world space bounds of this object + const CBound& GetBounds() const { return m_Bounds; } + + // set the object renderdata + // TODO,RC 10/04/04 - need to delete existing renderdata here, or can we + // assume the renderer won't set renderdata when an object already has it? + // - just assert we've no renderdata at the minute + void SetRenderData(CRenderData* renderdata) { + assert(m_RenderData==0); + m_RenderData=renderdata; + } + + // return object renderdata - can be null if renderer hasn't yet + // created the renderdata + CRenderData* GetRenderData() { return m_RenderData; } + +protected: + // object bounds + CBound m_Bounds; + // local->world space transform + CMatrix3D m_Transform; + // object renderdata + CRenderData* m_RenderData; +}; + +#endif diff --git a/source/terrain/Renderer.cpp b/source/terrain/Renderer.cpp index 2f1da7df0b..8f8c688d6b 100755 --- a/source/terrain/Renderer.cpp +++ b/source/terrain/Renderer.cpp @@ -1,755 +1,755 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Name: Renderer.cpp -// Author: Rich Cross -// Contact: rich@wildfiregames.com -// -// Description: OpenGL renderer class; a higher level interface -// on top of OpenGL to handle rendering the basic visual games -// types - terrain, models, sprites, particles etc -// -/////////////////////////////////////////////////////////////////////////////// - - -#include -#include -#include -#include "Renderer.h" -#include "TransparencyRenderer.h" -#include "Terrain.h" -#include "Matrix3D.h" -#include "Camera.h" -#include "PatchRData.h" -#include "Texture.h" -#include "LightEnv.h" - -#include "Model.h" -#include "ModelDef.h" - -#include "ogl.h" -#include "res/mem.h" -#include "res/tex.h" - -struct TGAHeader { - // header stuff - unsigned char iif_size; - unsigned char cmap_type; - unsigned char image_type; - unsigned char pad[5]; - - // origin : unused - unsigned short d_x_origin; - unsigned short d_y_origin; - - // dimensions - unsigned short width; - unsigned short height; - - // bits per pixel : 16, 24 or 32 - unsigned char bpp; - - // image descriptor : Bits 3-0: size of alpha channel - // Bit 4: must be 0 (reserved) - // Bit 5: should be 0 (origin) - // Bits 6-7: should be 0 (interleaving) - unsigned char image_descriptor; -}; - -static bool saveTGA(const char* filename,int width,int height,unsigned char* data) -{ - FILE* fp=fopen(filename,"wb"); - if (!fp) return false; - - // fill file header - TGAHeader header; - header.iif_size=0; - header.cmap_type=0; - header.image_type=2; - memset(header.pad,0,sizeof(header.pad)); - header.d_x_origin=0; - header.d_y_origin=0; - header.width=width; - header.height=height; - header.bpp=24; - header.image_descriptor=0; - - if (fwrite(&header,sizeof(TGAHeader),1,fp)!=1) { - fclose(fp); - return false; - } - - // write data - if (fwrite(data,width*height*3,1,fp)!=1) { - fclose(fp); - return false; - } - - // return success .. - fclose(fp); - return true; -} - -extern CTerrain g_Terrain; - - -CRenderer::CRenderer () -{ - m_Width=0; - m_Height=0; - m_Depth=0; - m_FrameCounter=0; - m_TerrainRenderMode=SOLID; - m_ModelRenderMode=SOLID; - m_ClearColor[0]=m_ClearColor[1]=m_ClearColor[2]=m_ClearColor[3]=0; - m_OptNOVBO=false; -} - -CRenderer::~CRenderer () -{ -} - - -/////////////////////////////////////////////////////////////////////////////////// -// EnumCaps: build card cap bits -void CRenderer::EnumCaps() -{ - // assume support for nothing - m_Caps.m_VBO=false; - - // now start querying extensions - if (!m_OptNOVBO) { - if (oglExtAvail("GL_ARB_vertex_buffer_object")) { - m_Caps.m_VBO=true; - } - } -} - -bool CRenderer::Open(int width, int height, int depth) -{ - m_Width = width; - m_Height = height; - m_Depth = depth; - - // set packing parameters - glPixelStorei(GL_PACK_ALIGNMENT,1); - glPixelStorei(GL_UNPACK_ALIGNMENT,1); - - // setup default state - glDepthFunc(GL_LEQUAL); - glEnable(GL_DEPTH_TEST); - glCullFace(GL_BACK); - glFrontFace(GL_CCW); - glEnable(GL_CULL_FACE); - glClearColor(0.0f,0.0f,0.0f,0.0f); - - // query card capabilities - EnumCaps(); - - return true; -} - -void CRenderer::Close() -{ -} - -// resize renderer view -void CRenderer::Resize(int width,int height) -{ - m_Width = width; - m_Height = height; -} - -////////////////////////////////////////////////////////////////////////////////////////// -// SetOption: set boolean renderer option -void CRenderer::SetOption(enum Option opt,bool value) -{ - switch (opt) { - case OPT_NOVBO: - m_OptNOVBO=value; - } -} - -////////////////////////////////////////////////////////////////////////////////////////// -// BeginFrame: signal frame start -void CRenderer::BeginFrame() -{ - // bump frame counter - m_FrameCounter++; - - // zero out all the per-frame stats - m_Stats.Reset(); - - // calculate coefficients for terrain and unit lighting - m_SHCoeffsUnits.Clear(); - m_SHCoeffsTerrain.Clear(); - - if (m_LightEnv) { - CVector3D dirlight; - m_LightEnv->GetSunDirection(dirlight); - m_SHCoeffsUnits.AddDirectionalLight(dirlight,m_LightEnv->m_SunColor); - m_SHCoeffsTerrain.AddDirectionalLight(dirlight,m_LightEnv->m_SunColor); - - m_SHCoeffsUnits.AddAmbientLight(m_LightEnv->m_UnitsAmbientColor); - m_SHCoeffsTerrain.AddAmbientLight(m_LightEnv->m_TerrainAmbientColor); - } - - // clear buffers - glClearColor(m_ClearColor[0],m_ClearColor[1],m_ClearColor[2],m_ClearColor[3]); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); -} - -////////////////////////////////////////////////////////////////////////////////////////// -// SetClearColor: set color used to clear screen in BeginFrame() -void CRenderer::SetClearColor(u32 color) -{ - m_ClearColor[0]=float(color & 0xff)/255.0f; - m_ClearColor[1]=float((color>>8) & 0xff)/255.0f; - m_ClearColor[2]=float((color>>16) & 0xff)/255.0f; - m_ClearColor[3]=float((color>>24) & 0xff)/255.0f; -} - -static int RoundUpToPowerOf2(int x) -{ - if ((x & (x-1))==0) return x; - int d=x; - while (d & (d-1)) { - d&=(d-1); - } - return d<<1; -} - - -void CRenderer::RenderPatches() -{ - // switch on wireframe if we need it - if (m_TerrainRenderMode==WIREFRAME) { - glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); - } - - // render all the patches, including blend pass - RenderPatchSubmissions(); - - if (m_TerrainRenderMode==WIREFRAME) { - // switch wireframe off again - glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); - } else if (m_TerrainRenderMode==EDGED_FACES) { - // edged faces: need to make a second pass over the data: - // first switch on wireframe - glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); - - // setup some renderstate .. - glDepthMask(0); - SetTexture(0,0); - glColor4f(1,1,1,0.35f); - glLineWidth(2.0f); - - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); - - // .. and some client states - glEnableClientState(GL_VERTEX_ARRAY); - - uint i; - - // render each patch in wireframe - for (i=0;iGetRenderData(); - patchdata->RenderStreams(STREAM_POS); - } - - // set color for outline - glColor3f(0,0,1); - glLineWidth(4.0f); - - // render outline of each patch - for (i=0;iGetRenderData(); - patchdata->RenderOutline(); - } - - // .. and switch off the client states - glDisableClientState(GL_VERTEX_ARRAY); - - // .. and restore the renderstates - glDisable(GL_BLEND); - glDepthMask(1); - - // restore fill mode, and we're done - glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); - } -} - -void CRenderer::RenderModelSubmissions() -{ - uint i; - - // build up transparent passes - for (i=0;iGetRenderData(); - modeldata->RenderStreams(STREAM_POS|STREAM_COLOR|STREAM_UV0,model->GetTransform()); - } - - // switch off client states - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); -} - -void CRenderer::RenderModels() -{ - // switch on wireframe if we need it - if (m_ModelRenderMode==WIREFRAME) { - glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); - } - - // render all the models - RenderModelSubmissions(); - - if (m_ModelRenderMode==WIREFRAME) { - // switch wireframe off again - glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); - } else if (m_ModelRenderMode==EDGED_FACES) { - // edged faces: need to make a second pass over the data: - // first switch on wireframe - glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); - - // setup some renderstate .. - glDepthMask(0); - SetTexture(0,0); - glColor4f(1,1,1,0.75f); - glLineWidth(1.0f); - - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); - - // .. and some client states - glEnableClientState(GL_VERTEX_ARRAY); - - // render each model - for (uint i=0;iGetRenderData(); - modeldata->RenderStreams(STREAM_POS,model->GetTransform()); - } - - // .. and switch off the client states - glDisableClientState(GL_VERTEX_ARRAY); - - // .. and restore the renderstates - glDisable(GL_BLEND); - glDepthMask(1); - - // restore fill mode, and we're done - glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); - } -} - -/////////////////////////////////////////////////////////////////////////////////////////////////// -// FlushFrame: force rendering of any batched objects -void CRenderer::FlushFrame() -{ - // update renderdata of everything submitted - UpdateSubmittedObjectData(); - - // render submitted patches and models - RenderPatches(); - RenderModels(); - - // call on the transparency renderer to render all the transparent stuff - g_TransparencyRenderer.Render(); - - // empty lists - m_TerrainPatches.clear(); - m_Models.clear(); -} - -// signal frame end : implicitly flushes batched objects -void CRenderer::EndFrame() -{ - FlushFrame(); -} - -void CRenderer::SetCamera(CCamera& camera) -{ - CMatrix3D view; - camera.m_Orientation.GetInverse(view); - CMatrix3D proj = camera.GetProjection(); - - float gl_view[16] = {view._11, view._21, view._31, view._41, - view._12, view._22, view._32, view._42, - view._13, view._23, view._33, view._43, - view._14, view._24, view._34, view._44}; - - float gl_proj[16] = {proj._11, proj._21, proj._31, proj._41, - proj._12, proj._22, proj._32, proj._42, - proj._13, proj._23, proj._33, proj._43, - proj._14, proj._24, proj._34, proj._44}; - - - glMatrixMode (GL_PROJECTION); - glLoadMatrixf (gl_proj); - - glMatrixMode (GL_MODELVIEW); - glLoadMatrixf (gl_view); - - const SViewPort& vp = camera.GetViewPort(); - glViewport (vp.m_X, vp.m_Y, vp.m_Width, vp.m_Height); - - m_Camera=camera; -} - -void CRenderer::Submit(CPatch* patch) -{ - m_TerrainPatches.push_back(patch); -} - -void CRenderer::Submit(CModel* model) -{ - m_Models.push_back(model); -} - -void CRenderer::Submit(CSprite* sprite) -{ -} - -void CRenderer::Submit(CParticleSys* psys) -{ -} - -void CRenderer::Submit(COverlay* overlay) -{ -} - -void CRenderer::RenderPatchSubmissions() -{ - uint i; - - // set up client states for base pass - glClientActiveTexture(GL_TEXTURE0); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_COLOR_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - - // set up texture environment for base pass - glActiveTexture(GL_TEXTURE0); - glEnable(GL_TEXTURE_2D); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); - glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE); - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR); - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PRIMARY_COLOR); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR); - - glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE); - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_ZERO); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_ONE_MINUS_SRC_ALPHA); - - // render base passes for each patch - for (i=0;iGetRenderData(); - patchdata->RenderBase(); - } - - // switch on the composite alpha map texture - glActiveTexture(GL_TEXTURE1); - glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D,m_CompositeAlphaMap); - - // setup additional texenv required by blend pass - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); - glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_REPLACE); - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR); - glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE); - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_ONE_MINUS_SRC_ALPHA); - - // switch on blending - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); - - // no need to write to the depth buffer a second time - glDepthMask(0); - - glClientActiveTexture(GL_TEXTURE1); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - - // render blend passes for each patch - for (i=0;iGetRenderData(); - patchdata->RenderBlends(); - } - - glClientActiveTexture(GL_TEXTURE1); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - - // restore depth writes - glDepthMask(1); - - // restore default state: switch off blending - glDisable(GL_BLEND); - - // switch off texture unit 1, make unit 0 active texture - glActiveTexture(GL_TEXTURE1); - glDisable(GL_TEXTURE_2D); - glActiveTexture(GL_TEXTURE0); - - // switch off all client states - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); - glClientActiveTexture(GL_TEXTURE0); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); -} - - - -// try and load the given texture -bool CRenderer::LoadTexture(CTexture* texture) -{ - Handle h=texture->GetHandle(); - if (h) { - // already tried to load this texture, nothing to do here - just return success according - // to whether this is a valid handle or not - return h==0xfffffff ? true : false; - } else { - h=tex_load(texture->GetName()); - if (!h) { - texture->SetHandle(0xffffffff); - return false; - } else { - tex_upload(h); - - tex_bind(h); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - - texture->SetHandle(h); - return true; - } - } -} - -// set the given unit to reference the given texture; pass a null texture to disable texturing on any unit -void CRenderer::SetTexture(int unit,CTexture* texture,u32 wrapflags) -{ - glActiveTexture(GL_TEXTURE0+unit); - if (texture) { - Handle h=texture->GetHandle(); - if (!h) { - LoadTexture(texture); - h=texture->GetHandle(); - - if (wrapflags) { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapflags); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapflags); - } - } - - // disable texturing if invalid handle - if (h==0xffffffff) { - glDisable(GL_TEXTURE_2D); - } else { - tex_bind(h); - glEnable(GL_TEXTURE_2D); - } - } else { - // switch off texturing on this unit - glDisable(GL_TEXTURE_2D); - } -} - -bool CRenderer::IsTextureTransparent(CTexture* texture) -{ - if (texture) { - Handle h=texture->GetHandle(); - if (!h) { - LoadTexture(texture); - h=texture->GetHandle(); - } - if (h!=0xffffffff && h) { - int fmt; - int bpp; - - tex_info(h, NULL, NULL, &fmt, &bpp, NULL); - if (bpp==24 || fmt == GL_COMPRESSED_RGB_S3TC_DXT1_EXT) - { - return false; - } - return true; - } else { - return false; - } - } else { - return false; - } -} - - - - -inline void CopyTriple(unsigned char* dst,const unsigned char* src) -{ - dst[0]=src[0]; - dst[1]=src[1]; - dst[2]=src[2]; -} - -// LoadAlphaMaps: load the 14 default alpha maps, pack them into one composite texture and -// calculate the coordinate of each alphamap within this packed texture .. need to add -// validation that all maps are the same size -bool CRenderer::LoadAlphaMaps(const char* fnames[]) -{ - glActiveTexture(GL_TEXTURE0_ARB); - - Handle textures[NumAlphaMaps]; - - int i; - - for (i=0;iGetTexture())) { - // ok, no transparency on this model .. ignore it here - return; - } - - // add this visual to the transparency renderer for later processing - g_TransparencyRenderer.Add(model); -} - - -///////////////////////////////////////////////////////////////////////////////////////////////////// -// UpdateSubmittedObjectData: ensure all submitted objects have renderdata and that it is up to date -// - call once before doing anything with any objects -void CRenderer::UpdateSubmittedObjectData() -{ - uint i; - - // ensure all patches have up to date renderdata built for them - for (i=0;iGetRenderData(); - if (data==0) { - // no renderdata for patch, create it now - data=new CPatchRData(patch); - patch->SetRenderData(data); - } else { - data->Update(); - } - } - - // ensure all models have up to date renderdata built for them - for (i=0;iGetRenderData(); - if (data==0) { - // no renderdata for model, create it now - data=new CModelRData(model); - model->SetRenderData(data); - } else { - data->Update(); - } - } -} - +/////////////////////////////////////////////////////////////////////////////// +// +// Name: Renderer.cpp +// Author: Rich Cross +// Contact: rich@wildfiregames.com +// +// Description: OpenGL renderer class; a higher level interface +// on top of OpenGL to handle rendering the basic visual games +// types - terrain, models, sprites, particles etc +// +/////////////////////////////////////////////////////////////////////////////// + + +#include +#include +#include +#include "Renderer.h" +#include "TransparencyRenderer.h" +#include "Terrain.h" +#include "Matrix3D.h" +#include "Camera.h" +#include "PatchRData.h" +#include "Texture.h" +#include "LightEnv.h" + +#include "Model.h" +#include "ModelDef.h" + +#include "ogl.h" +#include "res/mem.h" +#include "res/tex.h" + +struct TGAHeader { + // header stuff + unsigned char iif_size; + unsigned char cmap_type; + unsigned char image_type; + unsigned char pad[5]; + + // origin : unused + unsigned short d_x_origin; + unsigned short d_y_origin; + + // dimensions + unsigned short width; + unsigned short height; + + // bits per pixel : 16, 24 or 32 + unsigned char bpp; + + // image descriptor : Bits 3-0: size of alpha channel + // Bit 4: must be 0 (reserved) + // Bit 5: should be 0 (origin) + // Bits 6-7: should be 0 (interleaving) + unsigned char image_descriptor; +}; + +static bool saveTGA(const char* filename,int width,int height,unsigned char* data) +{ + FILE* fp=fopen(filename,"wb"); + if (!fp) return false; + + // fill file header + TGAHeader header; + header.iif_size=0; + header.cmap_type=0; + header.image_type=2; + memset(header.pad,0,sizeof(header.pad)); + header.d_x_origin=0; + header.d_y_origin=0; + header.width=width; + header.height=height; + header.bpp=24; + header.image_descriptor=0; + + if (fwrite(&header,sizeof(TGAHeader),1,fp)!=1) { + fclose(fp); + return false; + } + + // write data + if (fwrite(data,width*height*3,1,fp)!=1) { + fclose(fp); + return false; + } + + // return success .. + fclose(fp); + return true; +} + +extern CTerrain g_Terrain; + + +CRenderer::CRenderer () +{ + m_Width=0; + m_Height=0; + m_Depth=0; + m_FrameCounter=0; + m_TerrainRenderMode=SOLID; + m_ModelRenderMode=SOLID; + m_ClearColor[0]=m_ClearColor[1]=m_ClearColor[2]=m_ClearColor[3]=0; + m_OptNOVBO=false; +} + +CRenderer::~CRenderer () +{ +} + + +/////////////////////////////////////////////////////////////////////////////////// +// EnumCaps: build card cap bits +void CRenderer::EnumCaps() +{ + // assume support for nothing + m_Caps.m_VBO=false; + + // now start querying extensions + if (!m_OptNOVBO) { + if (oglExtAvail("GL_ARB_vertex_buffer_object")) { + m_Caps.m_VBO=true; + } + } +} + +bool CRenderer::Open(int width, int height, int depth) +{ + m_Width = width; + m_Height = height; + m_Depth = depth; + + // set packing parameters + glPixelStorei(GL_PACK_ALIGNMENT,1); + glPixelStorei(GL_UNPACK_ALIGNMENT,1); + + // setup default state + glDepthFunc(GL_LEQUAL); + glEnable(GL_DEPTH_TEST); + glCullFace(GL_BACK); + glFrontFace(GL_CCW); + glEnable(GL_CULL_FACE); + glClearColor(0.0f,0.0f,0.0f,0.0f); + + // query card capabilities + EnumCaps(); + + return true; +} + +void CRenderer::Close() +{ +} + +// resize renderer view +void CRenderer::Resize(int width,int height) +{ + m_Width = width; + m_Height = height; +} + +////////////////////////////////////////////////////////////////////////////////////////// +// SetOption: set boolean renderer option +void CRenderer::SetOption(enum Option opt,bool value) +{ + switch (opt) { + case OPT_NOVBO: + m_OptNOVBO=value; + } +} + +////////////////////////////////////////////////////////////////////////////////////////// +// BeginFrame: signal frame start +void CRenderer::BeginFrame() +{ + // bump frame counter + m_FrameCounter++; + + // zero out all the per-frame stats + m_Stats.Reset(); + + // calculate coefficients for terrain and unit lighting + m_SHCoeffsUnits.Clear(); + m_SHCoeffsTerrain.Clear(); + + if (m_LightEnv) { + CVector3D dirlight; + m_LightEnv->GetSunDirection(dirlight); + m_SHCoeffsUnits.AddDirectionalLight(dirlight,m_LightEnv->m_SunColor); + m_SHCoeffsTerrain.AddDirectionalLight(dirlight,m_LightEnv->m_SunColor); + + m_SHCoeffsUnits.AddAmbientLight(m_LightEnv->m_UnitsAmbientColor); + m_SHCoeffsTerrain.AddAmbientLight(m_LightEnv->m_TerrainAmbientColor); + } + + // clear buffers + glClearColor(m_ClearColor[0],m_ClearColor[1],m_ClearColor[2],m_ClearColor[3]); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); +} + +////////////////////////////////////////////////////////////////////////////////////////// +// SetClearColor: set color used to clear screen in BeginFrame() +void CRenderer::SetClearColor(u32 color) +{ + m_ClearColor[0]=float(color & 0xff)/255.0f; + m_ClearColor[1]=float((color>>8) & 0xff)/255.0f; + m_ClearColor[2]=float((color>>16) & 0xff)/255.0f; + m_ClearColor[3]=float((color>>24) & 0xff)/255.0f; +} + +static int RoundUpToPowerOf2(int x) +{ + if ((x & (x-1))==0) return x; + int d=x; + while (d & (d-1)) { + d&=(d-1); + } + return d<<1; +} + + +void CRenderer::RenderPatches() +{ + // switch on wireframe if we need it + if (m_TerrainRenderMode==WIREFRAME) { + glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); + } + + // render all the patches, including blend pass + RenderPatchSubmissions(); + + if (m_TerrainRenderMode==WIREFRAME) { + // switch wireframe off again + glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); + } else if (m_TerrainRenderMode==EDGED_FACES) { + // edged faces: need to make a second pass over the data: + // first switch on wireframe + glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); + + // setup some renderstate .. + glDepthMask(0); + SetTexture(0,0); + glColor4f(1,1,1,0.35f); + glLineWidth(2.0f); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); + + // .. and some client states + glEnableClientState(GL_VERTEX_ARRAY); + + uint i; + + // render each patch in wireframe + for (i=0;iGetRenderData(); + patchdata->RenderStreams(STREAM_POS); + } + + // set color for outline + glColor3f(0,0,1); + glLineWidth(4.0f); + + // render outline of each patch + for (i=0;iGetRenderData(); + patchdata->RenderOutline(); + } + + // .. and switch off the client states + glDisableClientState(GL_VERTEX_ARRAY); + + // .. and restore the renderstates + glDisable(GL_BLEND); + glDepthMask(1); + + // restore fill mode, and we're done + glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); + } +} + +void CRenderer::RenderModelSubmissions() +{ + uint i; + + // build up transparent passes + for (i=0;iGetRenderData(); + modeldata->RenderStreams(STREAM_POS|STREAM_COLOR|STREAM_UV0,model->GetTransform()); + } + + // switch off client states + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); +} + +void CRenderer::RenderModels() +{ + // switch on wireframe if we need it + if (m_ModelRenderMode==WIREFRAME) { + glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); + } + + // render all the models + RenderModelSubmissions(); + + if (m_ModelRenderMode==WIREFRAME) { + // switch wireframe off again + glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); + } else if (m_ModelRenderMode==EDGED_FACES) { + // edged faces: need to make a second pass over the data: + // first switch on wireframe + glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); + + // setup some renderstate .. + glDepthMask(0); + SetTexture(0,0); + glColor4f(1,1,1,0.75f); + glLineWidth(1.0f); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); + + // .. and some client states + glEnableClientState(GL_VERTEX_ARRAY); + + // render each model + for (uint i=0;iGetRenderData(); + modeldata->RenderStreams(STREAM_POS,model->GetTransform()); + } + + // .. and switch off the client states + glDisableClientState(GL_VERTEX_ARRAY); + + // .. and restore the renderstates + glDisable(GL_BLEND); + glDepthMask(1); + + // restore fill mode, and we're done + glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// FlushFrame: force rendering of any batched objects +void CRenderer::FlushFrame() +{ + // update renderdata of everything submitted + UpdateSubmittedObjectData(); + + // render submitted patches and models + RenderPatches(); + RenderModels(); + + // call on the transparency renderer to render all the transparent stuff + g_TransparencyRenderer.Render(); + + // empty lists + m_TerrainPatches.clear(); + m_Models.clear(); +} + +// signal frame end : implicitly flushes batched objects +void CRenderer::EndFrame() +{ + FlushFrame(); +} + +void CRenderer::SetCamera(CCamera& camera) +{ + CMatrix3D view; + camera.m_Orientation.GetInverse(view); + CMatrix3D proj = camera.GetProjection(); + + float gl_view[16] = {view._11, view._21, view._31, view._41, + view._12, view._22, view._32, view._42, + view._13, view._23, view._33, view._43, + view._14, view._24, view._34, view._44}; + + float gl_proj[16] = {proj._11, proj._21, proj._31, proj._41, + proj._12, proj._22, proj._32, proj._42, + proj._13, proj._23, proj._33, proj._43, + proj._14, proj._24, proj._34, proj._44}; + + + glMatrixMode (GL_PROJECTION); + glLoadMatrixf (gl_proj); + + glMatrixMode (GL_MODELVIEW); + glLoadMatrixf (gl_view); + + const SViewPort& vp = camera.GetViewPort(); + glViewport (vp.m_X, vp.m_Y, vp.m_Width, vp.m_Height); + + m_Camera=camera; +} + +void CRenderer::Submit(CPatch* patch) +{ + m_TerrainPatches.push_back(patch); +} + +void CRenderer::Submit(CModel* model) +{ + m_Models.push_back(model); +} + +void CRenderer::Submit(CSprite* sprite) +{ +} + +void CRenderer::Submit(CParticleSys* psys) +{ +} + +void CRenderer::Submit(COverlay* overlay) +{ +} + +void CRenderer::RenderPatchSubmissions() +{ + uint i; + + // set up client states for base pass + glClientActiveTexture(GL_TEXTURE0); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + // set up texture environment for base pass + glActiveTexture(GL_TEXTURE0); + glEnable(GL_TEXTURE_2D); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PRIMARY_COLOR); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR); + + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_ZERO); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_ONE_MINUS_SRC_ALPHA); + + // render base passes for each patch + for (i=0;iGetRenderData(); + patchdata->RenderBase(); + } + + // switch on the composite alpha map texture + glActiveTexture(GL_TEXTURE1); + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D,m_CompositeAlphaMap); + + // setup additional texenv required by blend pass + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_REPLACE); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR); + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_ONE_MINUS_SRC_ALPHA); + + // switch on blending + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); + + // no need to write to the depth buffer a second time + glDepthMask(0); + + glClientActiveTexture(GL_TEXTURE1); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + // render blend passes for each patch + for (i=0;iGetRenderData(); + patchdata->RenderBlends(); + } + + glClientActiveTexture(GL_TEXTURE1); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + + // restore depth writes + glDepthMask(1); + + // restore default state: switch off blending + glDisable(GL_BLEND); + + // switch off texture unit 1, make unit 0 active texture + glActiveTexture(GL_TEXTURE1); + glDisable(GL_TEXTURE_2D); + glActiveTexture(GL_TEXTURE0); + + // switch off all client states + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); + glClientActiveTexture(GL_TEXTURE0); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); +} + + + +// try and load the given texture +bool CRenderer::LoadTexture(CTexture* texture) +{ + Handle h=texture->GetHandle(); + if (h) { + // already tried to load this texture, nothing to do here - just return success according + // to whether this is a valid handle or not + return h==0xfffffff ? true : false; + } else { + h=tex_load(texture->GetName()); + if (!h) { + texture->SetHandle(0xffffffff); + return false; + } else { + tex_upload(h); + + tex_bind(h); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + texture->SetHandle(h); + return true; + } + } +} + +// set the given unit to reference the given texture; pass a null texture to disable texturing on any unit +void CRenderer::SetTexture(int unit,CTexture* texture,u32 wrapflags) +{ + glActiveTexture(GL_TEXTURE0+unit); + if (texture) { + Handle h=texture->GetHandle(); + if (!h) { + LoadTexture(texture); + h=texture->GetHandle(); + + if (wrapflags) { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapflags); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapflags); + } + } + + // disable texturing if invalid handle + if (h==0xffffffff) { + glDisable(GL_TEXTURE_2D); + } else { + tex_bind(h); + glEnable(GL_TEXTURE_2D); + } + } else { + // switch off texturing on this unit + glDisable(GL_TEXTURE_2D); + } +} + +bool CRenderer::IsTextureTransparent(CTexture* texture) +{ + if (texture) { + Handle h=texture->GetHandle(); + if (!h) { + LoadTexture(texture); + h=texture->GetHandle(); + } + if (h!=0xffffffff && h) { + int fmt; + int bpp; + + tex_info(h, NULL, NULL, &fmt, &bpp, NULL); + if (bpp==24 || fmt == GL_COMPRESSED_RGB_S3TC_DXT1_EXT) + { + return false; + } + return true; + } else { + return false; + } + } else { + return false; + } +} + + + + +inline void CopyTriple(unsigned char* dst,const unsigned char* src) +{ + dst[0]=src[0]; + dst[1]=src[1]; + dst[2]=src[2]; +} + +// LoadAlphaMaps: load the 14 default alpha maps, pack them into one composite texture and +// calculate the coordinate of each alphamap within this packed texture .. need to add +// validation that all maps are the same size +bool CRenderer::LoadAlphaMaps(const char* fnames[]) +{ + glActiveTexture(GL_TEXTURE0_ARB); + + Handle textures[NumAlphaMaps]; + + int i; + + for (i=0;iGetTexture())) { + // ok, no transparency on this model .. ignore it here + return; + } + + // add this visual to the transparency renderer for later processing + g_TransparencyRenderer.Add(model); +} + + +///////////////////////////////////////////////////////////////////////////////////////////////////// +// UpdateSubmittedObjectData: ensure all submitted objects have renderdata and that it is up to date +// - call once before doing anything with any objects +void CRenderer::UpdateSubmittedObjectData() +{ + uint i; + + // ensure all patches have up to date renderdata built for them + for (i=0;iGetRenderData(); + if (data==0) { + // no renderdata for patch, create it now + data=new CPatchRData(patch); + patch->SetRenderData(data); + } else { + data->Update(); + } + } + + // ensure all models have up to date renderdata built for them + for (i=0;iGetRenderData(); + if (data==0) { + // no renderdata for model, create it now + data=new CModelRData(model); + model->SetRenderData(data); + } else { + data->Update(); + } + } +} + diff --git a/source/terrain/Renderer.h b/source/terrain/Renderer.h index aa6fdcae42..3750b0d60b 100755 --- a/source/terrain/Renderer.h +++ b/source/terrain/Renderer.h @@ -1,267 +1,267 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Name: Renderer.h -// Author: Rich Cross -// Contact: rich@wildfiregames.com -// -// Description: OpenGL renderer class; a higher level interface -// on top of OpenGL to handle rendering the basic visual games -// types - terrain, models, sprites, particles etc -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef RENDERER_H -#define RENDERER_H - -#include -#include "res/res.h" -#include "ogl.h" -#include "Camera.h" -#include "Frustum.h" -#include "PatchRData.h" -#include "ModelRData.h" -#include "SHCoeffs.h" -#include "Terrain.h" - -// necessary declarations -class CCamera; -class CPatch; -class CSprite; -class CParticleSys; -class COverlay; -class CMaterial; -class CLightEnv; -class CTexture; -class CTerrain; - - -// rendering modes -enum ERenderMode { WIREFRAME, SOLID, EDGED_FACES }; - -// stream flags -#define STREAM_POS 0x01 -#define STREAM_NORMAL 0x02 -#define STREAM_COLOR 0x04 -#define STREAM_UV0 0x08 -#define STREAM_UV1 0x10 -#define STREAM_UV2 0x20 -#define STREAM_UV3 0x40 - -////////////////////////////////////////////////////////////////////////////////////////// -// SVertex3D: simple 3D vertex declaration -struct SVertex3D -{ - float m_Position[3]; - float m_TexCoords[2]; - unsigned int m_Color; -}; - -////////////////////////////////////////////////////////////////////////////////////////// -// SVertex2D: simple 2D vertex declaration -struct SVertex2D -{ - float m_Position[2]; - float m_TexCoords[2]; - unsigned int m_Color; -}; - - -/////////////////////////////////////////////////////////////////////////////////////////// -// CRenderer: base renderer class - primary interface to the rendering engine -class CRenderer -{ -public: - // various enumerations and renderer related constants - enum { NumAlphaMaps=14 }; - enum Option { - OPT_NOVBO - }; - - // stats class - per frame counts of number of draw calls, poly counts etc - struct Stats { - // set all stats to zero - void Reset() { memset(this,0,sizeof(*this)); } - // add given stats to this stats - Stats& operator+=(const Stats& rhs) { - m_Counter++; - m_DrawCalls+=rhs.m_DrawCalls; - m_TerrainTris+=rhs.m_TerrainTris; - m_ModelTris+=rhs.m_ModelTris; - m_TransparentTris+=rhs.m_TransparentTris; - m_BlendSplats+=rhs.m_BlendSplats; - return *this; - } - // count of the number of stats added together - u32 m_Counter; - // number of draw calls per frame - total DrawElements + Begin/End immediate mode loops - u32 m_DrawCalls; - // number of terrain triangles drawn - u32 m_TerrainTris; - // number of (non-transparent) model triangles drawn - u32 m_ModelTris; - // number of transparent model triangles drawn - u32 m_TransparentTris; - // number of splat passes for alphamapping - u32 m_BlendSplats; - }; - -public: - // constructor, destructor - CRenderer(); - ~CRenderer(); - - // open up the renderer: performs any necessary initialisation - bool Open(int width,int height,int depth); - // shutdown the renderer: performs any necessary cleanup - void Close(); - - // resize renderer view - void Resize(int width,int height); - - // set boolean renderer option - void SetOption(enum Option opt,bool value); - - // return view width - int GetWidth() const { return m_Width; } - // return view height - int GetHeight() const { return m_Height; } - // return view aspect ratio - float GetAspect() const { return float(m_Width)/float(m_Height); } - - // signal frame start - void BeginFrame(); - // force rendering of any batched objects - void FlushFrame(); - // signal frame end : implicitly flushes batched objects - void EndFrame(); - - // set color used to clear screen in BeginFrame() - void SetClearColor(u32 color); - - // return current frame counter - int GetFrameCounter() const { return m_FrameCounter; } - - // set camera used for subsequent rendering operations; includes viewport, projection and modelview matrices - void SetCamera(CCamera& camera); - - // submission of objects for rendering; the passed matrix indicating the transform must be scoped such that it is valid beyond - // the call to frame end, as must the object itself - void Submit(CPatch* patch); - void Submit(CModel* model); - void Submit(CSprite* sprite); - void Submit(CParticleSys* psys); - void Submit(COverlay* overlay); - - // basic primitive rendering operations in 2 and 3D; handy for debugging stuff, but also useful in - // editor tools (eg for highlighting specific terrain patches) - // note: - // * all 3D vertices specified in world space - // * primitive operations rendered immediatedly, never batched - // * primitives rendered in current material (set via SetMaterial) - void RenderLine(const SVertex2D* vertices); - void RenderLineLoop(int len,const SVertex2D* vertices); - void RenderTri(const SVertex2D* vertices); - void RenderQuad(const SVertex2D* vertices); - void RenderLine(const SVertex3D* vertices); - void RenderLineLoop(int len,const SVertex3D* vertices); - void RenderTri(const SVertex3D* vertices); - void RenderQuad(const SVertex3D* vertices); - - // set the current lighting environment; (note: the passed pointer is just copied to a variable within the renderer, - // so the lightenv passed must be scoped such that it is not destructed until after the renderer is no longer rendering) - void SetLightEnv(CLightEnv* lightenv) { - m_LightEnv=lightenv; - } - - // set the mode to render subsequent terrain patches - void SetTerrainRenderMode(ERenderMode mode) { m_TerrainRenderMode=mode; } - // get the mode to render subsequent terrain patches - ERenderMode GetTerrainRenderMode() const { return m_TerrainRenderMode; } - - // set the mode to render subsequent models - void SetModelRenderMode(ERenderMode mode) { m_ModelRenderMode=mode; } - // get the mode to render subsequent models - ERenderMode GetModelRenderMode() const { return m_ModelRenderMode; } - - // try and load the given texture - bool LoadTexture(CTexture* texture); - // set the given unit to reference the given texture; pass a null texture to disable texturing on any unit - // note - active texture always set to given unit on exit - void SetTexture(int unit,CTexture* texture,u32 wrapflags=0); - // query transparency of given texture - bool IsTextureTransparent(CTexture* texture); - - // load the default set of alphamaps; return false if any alphamap fails to load, true otherwise - bool LoadAlphaMaps(const char* fnames[]); - - // return stats accumulated for current frame - const Stats& GetStats() { return m_Stats; } - -protected: - friend class CPatchRData; - friend class CModelRData; - friend class CTransparencyRenderer; - - // update renderdata of everything submitted - void UpdateSubmittedObjectData(); - - // patch rendering stuff - void RenderPatchSubmissions(); - void RenderPatches(); - - // model rendering stuff - void BuildTransparentPasses(CModel* model); - void RenderModelSubmissions(); - void RenderModels(); - - // RENDERER DATA: - // view width - int m_Width; - // view height - int m_Height; - // view depth (bpp) - int m_Depth; - // frame counter - int m_FrameCounter; - // current terrain rendering mode - ERenderMode m_TerrainRenderMode; - // current model rendering mode - ERenderMode m_ModelRenderMode; - // current view camera - CCamera m_Camera; - // color used to clear screen in BeginFrame - float m_ClearColor[4]; - // submitted object lists for batching - std::vector m_TerrainPatches; - std::vector m_Models; - std::vector m_Sprites; - std::vector m_ParticleSyses; - std::vector m_Overlays; - // current lighting setup - CLightEnv* m_LightEnv; - // current spherical harmonic coefficients (for unit lighting), derived from lightenv - CSHCoeffs m_SHCoeffsUnits; - // current spherical harmonic coefficients (for terrain lighting), derived from lightenv - CSHCoeffs m_SHCoeffsTerrain; - // handle of composite alpha map (all the alpha maps packed into one texture) - u32 m_CompositeAlphaMap; - // coordinates of each (untransformed) alpha map within the packed texture - struct { - float u0,u1,v0,v1; - } m_AlphaMapCoords[NumAlphaMaps]; - // renderer options - bool m_OptNOVBO; - // card capabilities - struct Caps { - bool m_VBO; - } m_Caps; - // build card cap bits - void EnumCaps(); - // per-frame renderer stats - Stats m_Stats; -}; - -// declaration of sole renderer object -extern CRenderer g_Renderer; - -#endif +/////////////////////////////////////////////////////////////////////////////// +// +// Name: Renderer.h +// Author: Rich Cross +// Contact: rich@wildfiregames.com +// +// Description: OpenGL renderer class; a higher level interface +// on top of OpenGL to handle rendering the basic visual games +// types - terrain, models, sprites, particles etc +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef RENDERER_H +#define RENDERER_H + +#include +#include "res/res.h" +#include "ogl.h" +#include "Camera.h" +#include "Frustum.h" +#include "PatchRData.h" +#include "ModelRData.h" +#include "SHCoeffs.h" +#include "Terrain.h" + +// necessary declarations +class CCamera; +class CPatch; +class CSprite; +class CParticleSys; +class COverlay; +class CMaterial; +class CLightEnv; +class CTexture; +class CTerrain; + + +// rendering modes +enum ERenderMode { WIREFRAME, SOLID, EDGED_FACES }; + +// stream flags +#define STREAM_POS 0x01 +#define STREAM_NORMAL 0x02 +#define STREAM_COLOR 0x04 +#define STREAM_UV0 0x08 +#define STREAM_UV1 0x10 +#define STREAM_UV2 0x20 +#define STREAM_UV3 0x40 + +////////////////////////////////////////////////////////////////////////////////////////// +// SVertex3D: simple 3D vertex declaration +struct SVertex3D +{ + float m_Position[3]; + float m_TexCoords[2]; + unsigned int m_Color; +}; + +////////////////////////////////////////////////////////////////////////////////////////// +// SVertex2D: simple 2D vertex declaration +struct SVertex2D +{ + float m_Position[2]; + float m_TexCoords[2]; + unsigned int m_Color; +}; + + +/////////////////////////////////////////////////////////////////////////////////////////// +// CRenderer: base renderer class - primary interface to the rendering engine +class CRenderer +{ +public: + // various enumerations and renderer related constants + enum { NumAlphaMaps=14 }; + enum Option { + OPT_NOVBO + }; + + // stats class - per frame counts of number of draw calls, poly counts etc + struct Stats { + // set all stats to zero + void Reset() { memset(this,0,sizeof(*this)); } + // add given stats to this stats + Stats& operator+=(const Stats& rhs) { + m_Counter++; + m_DrawCalls+=rhs.m_DrawCalls; + m_TerrainTris+=rhs.m_TerrainTris; + m_ModelTris+=rhs.m_ModelTris; + m_TransparentTris+=rhs.m_TransparentTris; + m_BlendSplats+=rhs.m_BlendSplats; + return *this; + } + // count of the number of stats added together + u32 m_Counter; + // number of draw calls per frame - total DrawElements + Begin/End immediate mode loops + u32 m_DrawCalls; + // number of terrain triangles drawn + u32 m_TerrainTris; + // number of (non-transparent) model triangles drawn + u32 m_ModelTris; + // number of transparent model triangles drawn + u32 m_TransparentTris; + // number of splat passes for alphamapping + u32 m_BlendSplats; + }; + +public: + // constructor, destructor + CRenderer(); + ~CRenderer(); + + // open up the renderer: performs any necessary initialisation + bool Open(int width,int height,int depth); + // shutdown the renderer: performs any necessary cleanup + void Close(); + + // resize renderer view + void Resize(int width,int height); + + // set boolean renderer option + void SetOption(enum Option opt,bool value); + + // return view width + int GetWidth() const { return m_Width; } + // return view height + int GetHeight() const { return m_Height; } + // return view aspect ratio + float GetAspect() const { return float(m_Width)/float(m_Height); } + + // signal frame start + void BeginFrame(); + // force rendering of any batched objects + void FlushFrame(); + // signal frame end : implicitly flushes batched objects + void EndFrame(); + + // set color used to clear screen in BeginFrame() + void SetClearColor(u32 color); + + // return current frame counter + int GetFrameCounter() const { return m_FrameCounter; } + + // set camera used for subsequent rendering operations; includes viewport, projection and modelview matrices + void SetCamera(CCamera& camera); + + // submission of objects for rendering; the passed matrix indicating the transform must be scoped such that it is valid beyond + // the call to frame end, as must the object itself + void Submit(CPatch* patch); + void Submit(CModel* model); + void Submit(CSprite* sprite); + void Submit(CParticleSys* psys); + void Submit(COverlay* overlay); + + // basic primitive rendering operations in 2 and 3D; handy for debugging stuff, but also useful in + // editor tools (eg for highlighting specific terrain patches) + // note: + // * all 3D vertices specified in world space + // * primitive operations rendered immediatedly, never batched + // * primitives rendered in current material (set via SetMaterial) + void RenderLine(const SVertex2D* vertices); + void RenderLineLoop(int len,const SVertex2D* vertices); + void RenderTri(const SVertex2D* vertices); + void RenderQuad(const SVertex2D* vertices); + void RenderLine(const SVertex3D* vertices); + void RenderLineLoop(int len,const SVertex3D* vertices); + void RenderTri(const SVertex3D* vertices); + void RenderQuad(const SVertex3D* vertices); + + // set the current lighting environment; (note: the passed pointer is just copied to a variable within the renderer, + // so the lightenv passed must be scoped such that it is not destructed until after the renderer is no longer rendering) + void SetLightEnv(CLightEnv* lightenv) { + m_LightEnv=lightenv; + } + + // set the mode to render subsequent terrain patches + void SetTerrainRenderMode(ERenderMode mode) { m_TerrainRenderMode=mode; } + // get the mode to render subsequent terrain patches + ERenderMode GetTerrainRenderMode() const { return m_TerrainRenderMode; } + + // set the mode to render subsequent models + void SetModelRenderMode(ERenderMode mode) { m_ModelRenderMode=mode; } + // get the mode to render subsequent models + ERenderMode GetModelRenderMode() const { return m_ModelRenderMode; } + + // try and load the given texture + bool LoadTexture(CTexture* texture); + // set the given unit to reference the given texture; pass a null texture to disable texturing on any unit + // note - active texture always set to given unit on exit + void SetTexture(int unit,CTexture* texture,u32 wrapflags=0); + // query transparency of given texture + bool IsTextureTransparent(CTexture* texture); + + // load the default set of alphamaps; return false if any alphamap fails to load, true otherwise + bool LoadAlphaMaps(const char* fnames[]); + + // return stats accumulated for current frame + const Stats& GetStats() { return m_Stats; } + +protected: + friend class CPatchRData; + friend class CModelRData; + friend class CTransparencyRenderer; + + // update renderdata of everything submitted + void UpdateSubmittedObjectData(); + + // patch rendering stuff + void RenderPatchSubmissions(); + void RenderPatches(); + + // model rendering stuff + void BuildTransparentPasses(CModel* model); + void RenderModelSubmissions(); + void RenderModels(); + + // RENDERER DATA: + // view width + int m_Width; + // view height + int m_Height; + // view depth (bpp) + int m_Depth; + // frame counter + int m_FrameCounter; + // current terrain rendering mode + ERenderMode m_TerrainRenderMode; + // current model rendering mode + ERenderMode m_ModelRenderMode; + // current view camera + CCamera m_Camera; + // color used to clear screen in BeginFrame + float m_ClearColor[4]; + // submitted object lists for batching + std::vector m_TerrainPatches; + std::vector m_Models; + std::vector m_Sprites; + std::vector m_ParticleSyses; + std::vector m_Overlays; + // current lighting setup + CLightEnv* m_LightEnv; + // current spherical harmonic coefficients (for unit lighting), derived from lightenv + CSHCoeffs m_SHCoeffsUnits; + // current spherical harmonic coefficients (for terrain lighting), derived from lightenv + CSHCoeffs m_SHCoeffsTerrain; + // handle of composite alpha map (all the alpha maps packed into one texture) + u32 m_CompositeAlphaMap; + // coordinates of each (untransformed) alpha map within the packed texture + struct { + float u0,u1,v0,v1; + } m_AlphaMapCoords[NumAlphaMaps]; + // renderer options + bool m_OptNOVBO; + // card capabilities + struct Caps { + bool m_VBO; + } m_Caps; + // build card cap bits + void EnumCaps(); + // per-frame renderer stats + Stats m_Stats; +}; + +// declaration of sole renderer object +extern CRenderer g_Renderer; + +#endif diff --git a/source/terrain/SHCoeffs.cpp b/source/terrain/SHCoeffs.cpp index 90f78c6268..108db82bd1 100755 --- a/source/terrain/SHCoeffs.cpp +++ b/source/terrain/SHCoeffs.cpp @@ -1,77 +1,77 @@ -//---------------------------------------------------------------- -// -// Name: SHCoeffs.h -// Last Update: 25/11/03 -// Author: Rich Cross -// Contact: rich@0ad.wildfiregames.com -// -// Description: implementation of 9 component spherical harmonic -// lighting -//---------------------------------------------------------------- - -#include "SHCoeffs.h" - -CSHCoeffs::CSHCoeffs() -{ - Clear(); -} - -void CSHCoeffs::Clear() -{ - for (int i=0;i<9;i++) { - _data[i].Clear(); - } -} - -void CSHCoeffs::AddAmbientLight(const RGBColor& color) -{ - _data[0]+=color; -} - -void CSHCoeffs::AddDirectionalLight(const CVector3D& lightDir,const RGBColor& lightColor) -{ - CVector3D dirToLight(-lightDir.X,-lightDir.Y,-lightDir.Z); - - const float normalisation = PI*16/17; - const float c1 = SQR(0.282095f) * normalisation * 1.0f; - const float c2 = SQR(0.488603f) * normalisation * (2.0f/3.0f); - const float c3 = SQR(1.092548f) * normalisation * (1.0f/4.0f); - const float c4 = SQR(0.315392f) * normalisation * (1.0f/4.0f); - const float c5 = SQR(0.546274f) * normalisation * (1.0f/4.0f); - - _data[0]+=lightColor*c1; - _data[1]+=lightColor*c2*dirToLight.X; - _data[2]+=lightColor*c2*dirToLight.Y; - _data[3]+=lightColor*c2*dirToLight.Z; - _data[4]+=lightColor*c3*dirToLight.X*dirToLight.Z; - _data[5]+=lightColor*c3*dirToLight.Z*dirToLight.Y; - _data[6]+=lightColor*c3*dirToLight.Y*dirToLight.X; - _data[7]+=lightColor*c4*(3.0f*SQR(dirToLight.Z)-1.0f); - _data[8]+=lightColor*c5*(SQR(dirToLight.X)-SQR(dirToLight.Y)); -} - -void CSHCoeffs::Evaluate(const CVector3D& normal,RGBColor& color) const -{ -#if 1 - float c4=normal.X*normal.Z; - float c5=normal.Z*normal.Y; - float c6=normal.Y*normal.X; - float c7=(3*SQR(normal.Z)-1.0f); - float c8=(SQR(normal.X)-SQR(normal.Y)); - - for (int i=0;i<3;i++) { - color[i]=_data[0][i]; - color[i]+=_data[1][i]*normal.X; - color[i]+=_data[2][i]*normal.Y; - color[i]+=_data[3][i]*normal.Z; - color[i]+=_data[4][i]*c4; - color[i]+=_data[5][i]*c5; - color[i]+=_data[6][i]*c6; - color[i]+=_data[7][i]*c7; - color[i]+=_data[8][i]*c8; - } -#else - // debug aid: output quantised normal - color=RGBColor((normal.X+1)*0.5,(normal.Y+1)*0.5,(normal.Z+1)*0.5); -#endif -} +//---------------------------------------------------------------- +// +// Name: SHCoeffs.h +// Last Update: 25/11/03 +// Author: Rich Cross +// Contact: rich@0ad.wildfiregames.com +// +// Description: implementation of 9 component spherical harmonic +// lighting +//---------------------------------------------------------------- + +#include "SHCoeffs.h" + +CSHCoeffs::CSHCoeffs() +{ + Clear(); +} + +void CSHCoeffs::Clear() +{ + for (int i=0;i<9;i++) { + _data[i].Clear(); + } +} + +void CSHCoeffs::AddAmbientLight(const RGBColor& color) +{ + _data[0]+=color; +} + +void CSHCoeffs::AddDirectionalLight(const CVector3D& lightDir,const RGBColor& lightColor) +{ + CVector3D dirToLight(-lightDir.X,-lightDir.Y,-lightDir.Z); + + const float normalisation = PI*16/17; + const float c1 = SQR(0.282095f) * normalisation * 1.0f; + const float c2 = SQR(0.488603f) * normalisation * (2.0f/3.0f); + const float c3 = SQR(1.092548f) * normalisation * (1.0f/4.0f); + const float c4 = SQR(0.315392f) * normalisation * (1.0f/4.0f); + const float c5 = SQR(0.546274f) * normalisation * (1.0f/4.0f); + + _data[0]+=lightColor*c1; + _data[1]+=lightColor*c2*dirToLight.X; + _data[2]+=lightColor*c2*dirToLight.Y; + _data[3]+=lightColor*c2*dirToLight.Z; + _data[4]+=lightColor*c3*dirToLight.X*dirToLight.Z; + _data[5]+=lightColor*c3*dirToLight.Z*dirToLight.Y; + _data[6]+=lightColor*c3*dirToLight.Y*dirToLight.X; + _data[7]+=lightColor*c4*(3.0f*SQR(dirToLight.Z)-1.0f); + _data[8]+=lightColor*c5*(SQR(dirToLight.X)-SQR(dirToLight.Y)); +} + +void CSHCoeffs::Evaluate(const CVector3D& normal,RGBColor& color) const +{ +#if 1 + float c4=normal.X*normal.Z; + float c5=normal.Z*normal.Y; + float c6=normal.Y*normal.X; + float c7=(3*SQR(normal.Z)-1.0f); + float c8=(SQR(normal.X)-SQR(normal.Y)); + + for (int i=0;i<3;i++) { + color[i]=_data[0][i]; + color[i]+=_data[1][i]*normal.X; + color[i]+=_data[2][i]*normal.Y; + color[i]+=_data[3][i]*normal.Z; + color[i]+=_data[4][i]*c4; + color[i]+=_data[5][i]*c5; + color[i]+=_data[6][i]*c6; + color[i]+=_data[7][i]*c7; + color[i]+=_data[8][i]*c8; + } +#else + // debug aid: output quantised normal + color=RGBColor((normal.X+1)*0.5,(normal.Y+1)*0.5,(normal.Z+1)*0.5); +#endif +} diff --git a/source/terrain/SkeletonAnim.cpp b/source/terrain/SkeletonAnim.cpp index 41d8041046..985c743ef0 100755 --- a/source/terrain/SkeletonAnim.cpp +++ b/source/terrain/SkeletonAnim.cpp @@ -1,105 +1,105 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Name: SkeletonAnim.cpp -// Author: Rich Cross -// Contact: rich@wildfiregames.com -// -/////////////////////////////////////////////////////////////////////////////// - -#include "SkeletonAnim.h" -#include "FilePacker.h" -#include "FileUnpacker.h" - - -/////////////////////////////////////////////////////////////////////////////////////////// -// CSkeletonAnim constructor -CSkeletonAnim::CSkeletonAnim() : m_Keys(0), m_NumKeys(0), m_NumFrames(0), m_FrameTime(0) -{ - m_Name[0]='\0'; -} - -/////////////////////////////////////////////////////////////////////////////////////////// -// CSkeletonAnim destructor -CSkeletonAnim::~CSkeletonAnim() -{ - delete[] m_Keys; -} - -/////////////////////////////////////////////////////////////////////////////////////////// -// BuildBoneMatrices: build matrices for all bones at the given time (in MS) in this -// animation -void CSkeletonAnim::BuildBoneMatrices(float time,CMatrix3D* matrices) const -{ - float fstartframe=time/m_FrameTime; - u32 startframe=u32(time/m_FrameTime); - float deltatime=fstartframe-startframe; - - startframe%=m_NumFrames; - - u32 endframe=startframe+1; - endframe%=m_NumFrames; - - u32 i; - for (i=0;im_Name,(const char*) str); - - unpacker.UnpackRaw(&anim->m_FrameTime,sizeof(anim->m_FrameTime)); - unpacker.UnpackRaw(&anim->m_NumKeys,sizeof(anim->m_NumKeys)); - unpacker.UnpackRaw(&anim->m_NumFrames,sizeof(anim->m_NumFrames)); - anim->m_Keys=new Key[anim->m_NumKeys*anim->m_NumFrames]; - unpacker.UnpackRaw(anim->m_Keys,anim->m_NumKeys*anim->m_NumFrames*sizeof(Key)); - } catch (...) { - delete anim; - throw CFileUnpacker::CFileEOFError(); - } - - return anim; -} - -/////////////////////////////////////////////////////////////////////////////////////////// -// Save: try to save anim to file -void CSkeletonAnim::Save(const char* filename,const CSkeletonAnim* anim) -{ - CFilePacker packer; - - // pack up all the data - packer.PackString(CStr(anim->m_Name)); - packer.PackRaw(&anim->m_FrameTime,sizeof(anim->m_FrameTime)); - packer.PackRaw(&anim->m_NumKeys,sizeof(anim->m_NumKeys)); - packer.PackRaw(&anim->m_NumFrames,sizeof(anim->m_NumFrames)); - packer.PackRaw(anim->m_Keys,anim->m_NumKeys*anim->m_NumFrames*sizeof(Key)); - - // now write it - packer.Write(filename,FILE_VERSION,"PSSA"); -} - +/////////////////////////////////////////////////////////////////////////////// +// +// Name: SkeletonAnim.cpp +// Author: Rich Cross +// Contact: rich@wildfiregames.com +// +/////////////////////////////////////////////////////////////////////////////// + +#include "SkeletonAnim.h" +#include "FilePacker.h" +#include "FileUnpacker.h" + + +/////////////////////////////////////////////////////////////////////////////////////////// +// CSkeletonAnim constructor +CSkeletonAnim::CSkeletonAnim() : m_Keys(0), m_NumKeys(0), m_NumFrames(0), m_FrameTime(0) +{ + m_Name[0]='\0'; +} + +/////////////////////////////////////////////////////////////////////////////////////////// +// CSkeletonAnim destructor +CSkeletonAnim::~CSkeletonAnim() +{ + delete[] m_Keys; +} + +/////////////////////////////////////////////////////////////////////////////////////////// +// BuildBoneMatrices: build matrices for all bones at the given time (in MS) in this +// animation +void CSkeletonAnim::BuildBoneMatrices(float time,CMatrix3D* matrices) const +{ + float fstartframe=time/m_FrameTime; + u32 startframe=u32(time/m_FrameTime); + float deltatime=fstartframe-startframe; + + startframe%=m_NumFrames; + + u32 endframe=startframe+1; + endframe%=m_NumFrames; + + u32 i; + for (i=0;im_Name,(const char*) str); + + unpacker.UnpackRaw(&anim->m_FrameTime,sizeof(anim->m_FrameTime)); + unpacker.UnpackRaw(&anim->m_NumKeys,sizeof(anim->m_NumKeys)); + unpacker.UnpackRaw(&anim->m_NumFrames,sizeof(anim->m_NumFrames)); + anim->m_Keys=new Key[anim->m_NumKeys*anim->m_NumFrames]; + unpacker.UnpackRaw(anim->m_Keys,anim->m_NumKeys*anim->m_NumFrames*sizeof(Key)); + } catch (...) { + delete anim; + throw CFileUnpacker::CFileEOFError(); + } + + return anim; +} + +/////////////////////////////////////////////////////////////////////////////////////////// +// Save: try to save anim to file +void CSkeletonAnim::Save(const char* filename,const CSkeletonAnim* anim) +{ + CFilePacker packer; + + // pack up all the data + packer.PackString(CStr(anim->m_Name)); + packer.PackRaw(&anim->m_FrameTime,sizeof(anim->m_FrameTime)); + packer.PackRaw(&anim->m_NumKeys,sizeof(anim->m_NumKeys)); + packer.PackRaw(&anim->m_NumFrames,sizeof(anim->m_NumFrames)); + packer.PackRaw(anim->m_Keys,anim->m_NumKeys*anim->m_NumFrames*sizeof(Key)); + + // now write it + packer.Write(filename,FILE_VERSION,"PSSA"); +} + diff --git a/source/terrain/SkeletonAnim.h b/source/terrain/SkeletonAnim.h index 1558a4c195..2381fbde7c 100755 --- a/source/terrain/SkeletonAnim.h +++ b/source/terrain/SkeletonAnim.h @@ -1,83 +1,82 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Name: SkeletonAnim.h -// Author: Rich Cross -// Contact: rich@wildfiregames.com -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef _SKELETONANIM_H -#define _SKELETONANIM_H - -#include "res/res.h" -#include "Vector3D.h" -#include "Quaternion.h" - -// TODO, RC: ugh - remove; use CStr -#ifndef MAX_NAME_LENGTH -#define MAX_NAME_LENGTH 128 -#endif - -//////////////////////////////////////////////////////////////////////////////////////// -// CBoneState: structure describing state of a bone at some point -class CBoneState -{ -public: - // translation of bone relative to root - CVector3D m_Translation; - // rotation of bone relative to root - CQuaternion m_Rotation; -}; - - -//////////////////////////////////////////////////////////////////////////////////////// -// CSkeletonAnim: description of an animation that plays upon a skeleton -class CSkeletonAnim -{ -public: - // current file version given to saved animations - enum { FILE_VERSION = 1 }; - // supported file read version - files with a version less than this will be rejected - enum { FILE_READ_VERSION = 1 }; - - -public: - // Key: description of a single key in a skeleton animation - typedef CBoneState Key; - -public: - // CSkeletonAnim constructor + destructor - CSkeletonAnim(); - ~CSkeletonAnim(); - - // return the number of keys in this animation - u32 GetNumKeys() const { return m_NumKeys; } - - // accessors: get a key for given bone at given time - Key& GetKey(u32 frame,u32 bone) { return m_Keys[frame*m_NumKeys+bone]; } - const Key& GetKey(u32 frame,u32 bone) const { return m_Keys[frame*m_NumKeys+bone]; } - - // get duration of this anim, in ms - float GetDuration() const { return m_NumFrames*m_FrameTime; } - - // build matrices for all bones at the given time (in MS) in this animation - void BuildBoneMatrices(float time,CMatrix3D* matrices) const; - - // anim I/O functions - static CSkeletonAnim* Load(const char* filename); - static void Save(const char* filename,const CSkeletonAnim* anim); - -public: - // name of the animation - char m_Name[MAX_NAME_LENGTH]; - // frame time - time between successive frames, in ms - float m_FrameTime; - // number of keys in each frame - should match number of bones in the skeleton - u32 m_NumKeys; - // number of frames in the animation - u32 m_NumFrames; - // animation data - m_NumKeys*m_NumFrames total keys - Key* m_Keys; -}; - +/////////////////////////////////////////////////////////////////////////////// +// +// Name: SkeletonAnim.h +// Author: Rich Cross +// Contact: rich@wildfiregames.com +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _SKELETONANIM_H +#define _SKELETONANIM_H + +#include "res/res.h" +#include "Vector3D.h" +#include "Quaternion.h" + +#ifndef MAX_NAME_LENGTH +#define MAX_NAME_LENGTH 128 +#endif + +//////////////////////////////////////////////////////////////////////////////////////// +// CBoneState: structure describing state of a bone at some point +class CBoneState +{ +public: + // translation of bone relative to root + CVector3D m_Translation; + // rotation of bone relative to root + CQuaternion m_Rotation; +}; + + +//////////////////////////////////////////////////////////////////////////////////////// +// CSkeletonAnim: description of an animation that plays upon a skeleton +class CSkeletonAnim +{ +public: + // current file version given to saved animations + enum { FILE_VERSION = 1 }; + // supported file read version - files with a version less than this will be rejected + enum { FILE_READ_VERSION = 1 }; + + +public: + // Key: description of a single key in a skeleton animation + typedef CBoneState Key; + +public: + // CSkeletonAnim constructor + destructor + CSkeletonAnim(); + ~CSkeletonAnim(); + + // return the number of keys in this animation + u32 GetNumKeys() const { return m_NumKeys; } + + // accessors: get a key for given bone at given time + Key& GetKey(u32 frame,u32 bone) { return m_Keys[frame*m_NumKeys+bone]; } + const Key& GetKey(u32 frame,u32 bone) const { return m_Keys[frame*m_NumKeys+bone]; } + + // get duration of this anim, in ms + float GetDuration() const { return m_NumFrames*m_FrameTime; } + + // build matrices for all bones at the given time (in MS) in this animation + void BuildBoneMatrices(float time,CMatrix3D* matrices) const; + + // anim I/O functions + static CSkeletonAnim* Load(const char* filename); + static void Save(const char* filename,const CSkeletonAnim* anim); + +public: + // name of the animation + char m_Name[MAX_NAME_LENGTH]; + // frame time - time between successive frames, in ms + float m_FrameTime; + // number of keys in each frame - should match number of bones in the skeleton + u32 m_NumKeys; + // number of frames in the animation + u32 m_NumFrames; + // animation data - m_NumKeys*m_NumFrames total keys + Key* m_Keys; +}; + #endif \ No newline at end of file diff --git a/source/terrain/Terrain.cpp b/source/terrain/Terrain.cpp index 0ef71ce764..a73061162e 100755 --- a/source/terrain/Terrain.cpp +++ b/source/terrain/Terrain.cpp @@ -1,292 +1,292 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Name: Terrain.cpp -// Author: Rich Cross -// Contact: rich@wildfiregames.com -// -/////////////////////////////////////////////////////////////////////////////// - -#include "res/tex.h" -#include "res/mem.h" - -#include -#include "Terrain.h" - - -/////////////////////////////////////////////////////////////////////////////// -// CTerrain constructor -CTerrain::CTerrain() : m_Heightmap(0), m_Patches(0), m_MapSize(0), m_MapSizePatches(0) -{ -} - -/////////////////////////////////////////////////////////////////////////////// -// CTerrain constructor -CTerrain::~CTerrain() -{ - ReleaseData(); -} - - -/////////////////////////////////////////////////////////////////////////////// -// ReleaseData: delete any data allocated by this terrain -void CTerrain::ReleaseData() -{ - delete[] m_Heightmap; - delete[] m_Patches; -} - - -/////////////////////////////////////////////////////////////////////////////// -// Initialise: initialise this terrain to the given size (in patches per side); -// using given heightmap to setup elevation data -bool CTerrain::Initialize(u32 size,const u16* data) -{ - // clean up any previous terrain - ReleaseData(); - - // store terrain size - m_MapSize=(size*PATCH_SIZE)+1; - m_MapSizePatches=size; - - // allocate data for new terrain - m_Heightmap=new u16[m_MapSize*m_MapSize]; - m_Patches=new CPatch[m_MapSizePatches*m_MapSizePatches]; - - // given a heightmap? - if (data) { - // yes; keep a copy of it - memcpy(m_Heightmap,data,m_MapSize*m_MapSize*sizeof(u16)); - } else { - // build a flat terrain - memset(m_Heightmap,0,m_MapSize*m_MapSize*sizeof(u16)); - } - - // setup patch parents, indices etc - InitialisePatches(); - - return true; -} - -/////////////////////////////////////////////////////////////////////////////// -// CalcPosition: calculate the world space position of the vertex at (i,j) -void CTerrain::CalcPosition(u32 i,u32 j,CVector3D& pos) -{ - u16 height=m_Heightmap[j*m_MapSize + i]; - pos.X = float(i)*CELL_SIZE; - pos.Y = float(height)*HEIGHT_SCALE; - pos.Z = float(j)*CELL_SIZE; -} - - -/////////////////////////////////////////////////////////////////////////////// -// CalcNormal: calculate the world space normal of the vertex at (i,j) -void CTerrain::CalcNormal(u32 i,u32 j,CVector3D& normal) -{ - CVector3D left, right, up, down; - - left.Clear(); - right.Clear(); - up.Clear(); - down.Clear(); - - // get position of vertex where normal is being evaluated - CVector3D basepos; - CalcPosition(i,j,basepos); - - CVector3D tmp; - if (i>0) { - CalcPosition(i-1,j,tmp); - left=tmp-basepos; - } - - if (i0) { - CalcPosition(i,j-1,tmp); - up=tmp-basepos; - } - - if (j0.00001f) normal*=1.0f/nlen; -} - - -/////////////////////////////////////////////////////////////////////////////// -// GetPatch: return the patch at (x,z) in patch space, or null if the patch is -// out of bounds -CPatch* CTerrain::GetPatch(int32 x,int32 z) -{ - if (x<0 || x>=int32(m_MapSizePatches)) return 0; - if (z<0 || z>=int32(m_MapSizePatches)) return 0; - return &m_Patches[(z*m_MapSizePatches)+x]; -} - - -/////////////////////////////////////////////////////////////////////////////// -// GetPatch: return the tile at (x,z) in tile space, or null if the tile is out -// of bounds -CMiniPatch* CTerrain::GetTile(int32 x,int32 z) -{ - if (x<0 || x>=int32(m_MapSize)-1) return 0; - if (z<0 || z>=int32(m_MapSize)-1) return 0; - - CPatch* patch=GetPatch(x/16,z/16); - return &patch->m_MiniPatches[z%16][x%16]; -} - - -/////////////////////////////////////////////////////////////////////////////// -// Resize: resize this terrain to the given size (in patches per side) -void CTerrain::Resize(u32 size) -{ - if (size==m_MapSizePatches) { - // inexplicable request to resize terrain to the same size .. ignore it - return; - } - - if (!m_Heightmap) { - // not yet created a terrain; build a default terrain of the given size now - Initialize(size,0); - return; - } - - // allocate data for new terrain - u32 newMapSize=(size*PATCH_SIZE)+1; - u16* newHeightmap=new u16[newMapSize*newMapSize]; - CPatch* newPatches=new CPatch[size*size]; - - if (size>m_MapSizePatches) { - // new map is bigger than old one - zero the heightmap so we don't get uninitialised - // height data along the expanded edges - memset(newHeightmap,0,newMapSize*newMapSize); - } - - // now copy over rows of data - u32 j; - u16* src=m_Heightmap; - u16* dst=newHeightmap; - u32 copysize=newMapSize>m_MapSize ? m_MapSize : newMapSize; - for (j=0;jm_MapSize) { - // entend the last height to the end of the row - for (u32 i=0;im_MapSize) { - // copy over heights of the last row to any remaining rows - src=newHeightmap+((m_MapSize-1)*newMapSize); - dst=src+newMapSize; - for (u32 i=0;im_MapSizePatches) { - // copy over the last tile from each column - for (u32 n=0;nm_MapSizePatches) { - // copy over the last tile from each column - CPatch* srcpatch=&newPatches[(m_MapSizePatches-1)*size]; - CPatch* dstpatch=srcpatch+size; - for (u32 p=0;pm_MiniPatches[15][k]; - CMiniPatch& dst=dstpatch->m_MiniPatches[m][k]; - dst.Tex1=src.Tex1; - dst.Tex1Priority=src.Tex1Priority; - } - } - srcpatch++; - dstpatch++; - } - } - } - - - // release all the original data - ReleaseData(); - - // store new data - m_Heightmap=newHeightmap; - m_Patches=newPatches; - m_MapSize=newMapSize; - m_MapSizePatches=size; - - // initialise all the new patches - InitialisePatches(); -} - -/////////////////////////////////////////////////////////////////////////////// -// InitialisePatches: initialise patch data -void CTerrain::InitialisePatches() -{ - for (u32 j=0;jInitialize(this,i,j); - } - } -} - -/////////////////////////////////////////////////////////////////////////////// -// SetHeightMap: set up a new heightmap from 16-bit source data; -// assumes heightmap matches current terrain size -void CTerrain::SetHeightMap(u16* heightmap) -{ - // keep a copy of the given heightmap - memcpy(m_Heightmap,heightmap,m_MapSize*m_MapSize*sizeof(u16)); - - // recalculate patch bounds, invalidate vertices - for (u32 j=0;jCalcBounds(); - patch->SetDirty(RENDERDATA_UPDATE_VERTICES); - } - } -} +/////////////////////////////////////////////////////////////////////////////// +// +// Name: Terrain.cpp +// Author: Rich Cross +// Contact: rich@wildfiregames.com +// +/////////////////////////////////////////////////////////////////////////////// + +#include "res/tex.h" +#include "res/mem.h" + +#include +#include "Terrain.h" + + +/////////////////////////////////////////////////////////////////////////////// +// CTerrain constructor +CTerrain::CTerrain() : m_Heightmap(0), m_Patches(0), m_MapSize(0), m_MapSizePatches(0) +{ +} + +/////////////////////////////////////////////////////////////////////////////// +// CTerrain constructor +CTerrain::~CTerrain() +{ + ReleaseData(); +} + + +/////////////////////////////////////////////////////////////////////////////// +// ReleaseData: delete any data allocated by this terrain +void CTerrain::ReleaseData() +{ + delete[] m_Heightmap; + delete[] m_Patches; +} + + +/////////////////////////////////////////////////////////////////////////////// +// Initialise: initialise this terrain to the given size (in patches per side); +// using given heightmap to setup elevation data +bool CTerrain::Initialize(u32 size,const u16* data) +{ + // clean up any previous terrain + ReleaseData(); + + // store terrain size + m_MapSize=(size*PATCH_SIZE)+1; + m_MapSizePatches=size; + + // allocate data for new terrain + m_Heightmap=new u16[m_MapSize*m_MapSize]; + m_Patches=new CPatch[m_MapSizePatches*m_MapSizePatches]; + + // given a heightmap? + if (data) { + // yes; keep a copy of it + memcpy(m_Heightmap,data,m_MapSize*m_MapSize*sizeof(u16)); + } else { + // build a flat terrain + memset(m_Heightmap,0,m_MapSize*m_MapSize*sizeof(u16)); + } + + // setup patch parents, indices etc + InitialisePatches(); + + return true; +} + +/////////////////////////////////////////////////////////////////////////////// +// CalcPosition: calculate the world space position of the vertex at (i,j) +void CTerrain::CalcPosition(u32 i,u32 j,CVector3D& pos) +{ + u16 height=m_Heightmap[j*m_MapSize + i]; + pos.X = float(i)*CELL_SIZE; + pos.Y = float(height)*HEIGHT_SCALE; + pos.Z = float(j)*CELL_SIZE; +} + + +/////////////////////////////////////////////////////////////////////////////// +// CalcNormal: calculate the world space normal of the vertex at (i,j) +void CTerrain::CalcNormal(u32 i,u32 j,CVector3D& normal) +{ + CVector3D left, right, up, down; + + left.Clear(); + right.Clear(); + up.Clear(); + down.Clear(); + + // get position of vertex where normal is being evaluated + CVector3D basepos; + CalcPosition(i,j,basepos); + + CVector3D tmp; + if (i>0) { + CalcPosition(i-1,j,tmp); + left=tmp-basepos; + } + + if (i0) { + CalcPosition(i,j-1,tmp); + up=tmp-basepos; + } + + if (j0.00001f) normal*=1.0f/nlen; +} + + +/////////////////////////////////////////////////////////////////////////////// +// GetPatch: return the patch at (x,z) in patch space, or null if the patch is +// out of bounds +CPatch* CTerrain::GetPatch(int32 x,int32 z) +{ + if (x<0 || x>=int32(m_MapSizePatches)) return 0; + if (z<0 || z>=int32(m_MapSizePatches)) return 0; + return &m_Patches[(z*m_MapSizePatches)+x]; +} + + +/////////////////////////////////////////////////////////////////////////////// +// GetPatch: return the tile at (x,z) in tile space, or null if the tile is out +// of bounds +CMiniPatch* CTerrain::GetTile(int32 x,int32 z) +{ + if (x<0 || x>=int32(m_MapSize)-1) return 0; + if (z<0 || z>=int32(m_MapSize)-1) return 0; + + CPatch* patch=GetPatch(x/16,z/16); + return &patch->m_MiniPatches[z%16][x%16]; +} + + +/////////////////////////////////////////////////////////////////////////////// +// Resize: resize this terrain to the given size (in patches per side) +void CTerrain::Resize(u32 size) +{ + if (size==m_MapSizePatches) { + // inexplicable request to resize terrain to the same size .. ignore it + return; + } + + if (!m_Heightmap) { + // not yet created a terrain; build a default terrain of the given size now + Initialize(size,0); + return; + } + + // allocate data for new terrain + u32 newMapSize=(size*PATCH_SIZE)+1; + u16* newHeightmap=new u16[newMapSize*newMapSize]; + CPatch* newPatches=new CPatch[size*size]; + + if (size>m_MapSizePatches) { + // new map is bigger than old one - zero the heightmap so we don't get uninitialised + // height data along the expanded edges + memset(newHeightmap,0,newMapSize*newMapSize); + } + + // now copy over rows of data + u32 j; + u16* src=m_Heightmap; + u16* dst=newHeightmap; + u32 copysize=newMapSize>m_MapSize ? m_MapSize : newMapSize; + for (j=0;jm_MapSize) { + // entend the last height to the end of the row + for (u32 i=0;im_MapSize) { + // copy over heights of the last row to any remaining rows + src=newHeightmap+((m_MapSize-1)*newMapSize); + dst=src+newMapSize; + for (u32 i=0;im_MapSizePatches) { + // copy over the last tile from each column + for (u32 n=0;nm_MapSizePatches) { + // copy over the last tile from each column + CPatch* srcpatch=&newPatches[(m_MapSizePatches-1)*size]; + CPatch* dstpatch=srcpatch+size; + for (u32 p=0;pm_MiniPatches[15][k]; + CMiniPatch& dst=dstpatch->m_MiniPatches[m][k]; + dst.Tex1=src.Tex1; + dst.Tex1Priority=src.Tex1Priority; + } + } + srcpatch++; + dstpatch++; + } + } + } + + + // release all the original data + ReleaseData(); + + // store new data + m_Heightmap=newHeightmap; + m_Patches=newPatches; + m_MapSize=newMapSize; + m_MapSizePatches=size; + + // initialise all the new patches + InitialisePatches(); +} + +/////////////////////////////////////////////////////////////////////////////// +// InitialisePatches: initialise patch data +void CTerrain::InitialisePatches() +{ + for (u32 j=0;jInitialize(this,i,j); + } + } +} + +/////////////////////////////////////////////////////////////////////////////// +// SetHeightMap: set up a new heightmap from 16-bit source data; +// assumes heightmap matches current terrain size +void CTerrain::SetHeightMap(u16* heightmap) +{ + // keep a copy of the given heightmap + memcpy(m_Heightmap,heightmap,m_MapSize*m_MapSize*sizeof(u16)); + + // recalculate patch bounds, invalidate vertices + for (u32 j=0;jCalcBounds(); + patch->SetDirty(RENDERDATA_UPDATE_VERTICES); + } + } +} diff --git a/source/terrain/Terrain.h b/source/terrain/Terrain.h index c1a259ac07..65ceb72cf9 100755 --- a/source/terrain/Terrain.h +++ b/source/terrain/Terrain.h @@ -1,82 +1,82 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Name: Terrain.h -// Author: Rich Cross -// Contact: rich@wildfiregames.com -// -/////////////////////////////////////////////////////////////////////////////// - - -#ifndef _TERRAIN_H -#define _TERRAIN_H - -#include "Patch.h" -#include "Vector3D.h" - -/////////////////////////////////////////////////////////////////////////////// -// Terrain Constants: -// -// PATCH_SIZE: number of tiles in each patch -const int PATCH_SIZE = 16; -// CELL_SIZE: size of each tile in x and z -const int CELL_SIZE = 4; -// HEIGHT_SCALE: vertical scale of terrain - terrain has a coordinate range of -// 0 to 65536*HEIGHT_SCALE -const float HEIGHT_SCALE = 0.35f/256.0f; - - -/////////////////////////////////////////////////////////////////////////////// -// CTerrain: main terrain class; contains the heightmap describing elevation -// data, and the smaller subpatches that form the terrain -class CTerrain -{ -public: - CTerrain(); - ~CTerrain(); - - bool Initialize(u32 size,const u16* ptr); - - // return number of vertices along edge of the terrain - u32 GetVerticesPerSide() { return m_MapSize; } - // return number of patches along edge of the terrain - u32 GetPatchesPerSide() { return m_MapSizePatches; } - - // resize this terrain such that each side has given number of patches - void Resize(u32 size); - - // set up a new heightmap from 16 bit data; assumes heightmap matches current terrain size - void SetHeightMap(u16* heightmap); - // return a pointer to the heightmap - u16* GetHeightMap() const { return m_Heightmap; } - - // get patch at given coordinates, expressed in patch-space; return 0 if - // coordinates represent patch off the edge of the map - CPatch* GetPatch(int32 x,int32 z); - // get tile at given coordinates, expressed in tile-space; return 0 if - // coordinates represent tile off the edge of the map - CMiniPatch* GetTile(int32 x,int32 z); - - // calculate the position of a given vertex - void CalcPosition(u32 i,u32 j,CVector3D& pos); - // calculate the normal at a given vertex - void CalcNormal(u32 i,u32 j,CVector3D& normal); - -private: - // delete any data allocated by this terrain - void ReleaseData(); - // setup patch pointers etc - void InitialisePatches(); - - // size of this map in each direction, in vertices; ie. total tiles = sqr(m_MapSize-1) - u32 m_MapSize; - // size of this map in each direction, in patches; total patches = sqr(m_MapSizePatches) - u32 m_MapSizePatches; - // the patches comprising this terrain - CPatch* m_Patches; - // 16-bit heightmap data - u16* m_Heightmap; -}; - -extern CTerrain g_Terrain; - -#endif +/////////////////////////////////////////////////////////////////////////////// +// +// Name: Terrain.h +// Author: Rich Cross +// Contact: rich@wildfiregames.com +// +/////////////////////////////////////////////////////////////////////////////// + + +#ifndef _TERRAIN_H +#define _TERRAIN_H + +#include "Patch.h" +#include "Vector3D.h" + +/////////////////////////////////////////////////////////////////////////////// +// Terrain Constants: +// +// PATCH_SIZE: number of tiles in each patch +const int PATCH_SIZE = 16; +// CELL_SIZE: size of each tile in x and z +const int CELL_SIZE = 4; +// HEIGHT_SCALE: vertical scale of terrain - terrain has a coordinate range of +// 0 to 65536*HEIGHT_SCALE +const float HEIGHT_SCALE = 0.35f/256.0f; + + +/////////////////////////////////////////////////////////////////////////////// +// CTerrain: main terrain class; contains the heightmap describing elevation +// data, and the smaller subpatches that form the terrain +class CTerrain +{ +public: + CTerrain(); + ~CTerrain(); + + bool Initialize(u32 size,const u16* ptr); + + // return number of vertices along edge of the terrain + u32 GetVerticesPerSide() { return m_MapSize; } + // return number of patches along edge of the terrain + u32 GetPatchesPerSide() { return m_MapSizePatches; } + + // resize this terrain such that each side has given number of patches + void Resize(u32 size); + + // set up a new heightmap from 16 bit data; assumes heightmap matches current terrain size + void SetHeightMap(u16* heightmap); + // return a pointer to the heightmap + u16* GetHeightMap() const { return m_Heightmap; } + + // get patch at given coordinates, expressed in patch-space; return 0 if + // coordinates represent patch off the edge of the map + CPatch* GetPatch(int32 x,int32 z); + // get tile at given coordinates, expressed in tile-space; return 0 if + // coordinates represent tile off the edge of the map + CMiniPatch* GetTile(int32 x,int32 z); + + // calculate the position of a given vertex + void CalcPosition(u32 i,u32 j,CVector3D& pos); + // calculate the normal at a given vertex + void CalcNormal(u32 i,u32 j,CVector3D& normal); + +private: + // delete any data allocated by this terrain + void ReleaseData(); + // setup patch pointers etc + void InitialisePatches(); + + // size of this map in each direction, in vertices; ie. total tiles = sqr(m_MapSize-1) + u32 m_MapSize; + // size of this map in each direction, in patches; total patches = sqr(m_MapSizePatches) + u32 m_MapSizePatches; + // the patches comprising this terrain + CPatch* m_Patches; + // 16-bit heightmap data + u16* m_Heightmap; +}; + +extern CTerrain g_Terrain; + +#endif diff --git a/source/terrain/TextureEntry.h b/source/terrain/TextureEntry.h index 8cc743307f..e827eecdc6 100755 --- a/source/terrain/TextureEntry.h +++ b/source/terrain/TextureEntry.h @@ -1,24 +1,24 @@ -#ifndef _TEXTUREENTRY_H -#define _TEXTUREENTRY_H - -#include "res/res.h" -#include "CStr.h" - -class CTextureEntry -{ -public: - CTextureEntry() : m_Bitmap(0), m_Handle(0), m_BaseColor(0), m_Type(0) {} - - // filename - CStr m_Name; - // UI bitmap object - void* m_Bitmap; - // handle to GL texture data - Handle m_Handle; - // BGRA color of topmost mipmap level, for coloring minimap - unsigned int m_BaseColor; - // "type" of texture - index into TextureManager texturetypes array - int m_Type; -}; - -#endif +#ifndef _TEXTUREENTRY_H +#define _TEXTUREENTRY_H + +#include "res/res.h" +#include "CStr.h" + +class CTextureEntry +{ +public: + CTextureEntry() : m_Bitmap(0), m_Handle(0), m_BaseColor(0), m_Type(0) {} + + // filename + CStr m_Name; + // UI bitmap object + void* m_Bitmap; + // handle to GL texture data + Handle m_Handle; + // BGRA color of topmost mipmap level, for coloring minimap + unsigned int m_BaseColor; + // "type" of texture - index into TextureManager texturetypes array + int m_Type; +}; + +#endif diff --git a/source/terrain/TextureManager.cpp b/source/terrain/TextureManager.cpp index 2a17172451..20f37b941a 100755 --- a/source/terrain/TextureManager.cpp +++ b/source/terrain/TextureManager.cpp @@ -1,3 +1,4 @@ + #include "TextureManager.h" #include "lib.h" #include "ogl.h" @@ -23,7 +24,7 @@ void CTextureManager::AddTextureType(const char* name) m_TerrainTextures.resize(m_TerrainTextures.size()+1); STextureType& ttype=m_TerrainTextures.back(); ttype.m_Name=name; - ttype.m_Index=(int)m_TerrainTextures.size()-1; + ttype.m_Index=m_TerrainTextures.size()-1; } CTextureEntry* CTextureManager::FindTexture(const char* filename) @@ -198,4 +199,3 @@ void CTextureManager::LoadTerrainTextures() } } } - diff --git a/source/terrain/TransparencyRenderer.cpp b/source/terrain/TransparencyRenderer.cpp index bbcd20986a..5a5a8658e4 100755 --- a/source/terrain/TransparencyRenderer.cpp +++ b/source/terrain/TransparencyRenderer.cpp @@ -1,136 +1,136 @@ -#include -#include "Renderer.h" -#include "TransparencyRenderer.h" -#include "terrain/Model.h" - - -CTransparencyRenderer g_TransparencyRenderer; - - -struct SortObjectsByDist { - typedef CTransparencyRenderer::SObject SortObj; - - bool operator()(const SortObj& lhs,const SortObj& rhs) { - return lhs.m_Dist>rhs.m_Dist? true : false; - } -}; - -void CTransparencyRenderer::Render() -{ - // coarsely sort submitted objects in back to front manner - std::sort(m_Objects.begin(),m_Objects.end(),SortObjectsByDist()); - - // switch on wireframe if we need it - if (g_Renderer.m_ModelRenderMode==WIREFRAME) { - glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); - } - - // switch on client states - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_COLOR_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - - // setup texture environment to modulate diffuse color with texture color - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); - glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE); - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR); - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PRIMARY_COLOR); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR); - - // just pass through texture's alpha - glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE); - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA); - - glEnable(GL_ALPHA_TEST); - glAlphaFunc(GL_GREATER,0.975f); - - uint i; - for (i=0;iGetRenderData(); - modeldata->RenderStreams(STREAM_POS|STREAM_COLOR|STREAM_UV0,model->GetTransform(),true); - } - - glDepthMask(0); - glAlphaFunc(GL_LEQUAL,0.975f); - - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); - - for (i=0;iGetRenderData(); - modeldata->RenderStreams(STREAM_POS|STREAM_COLOR|STREAM_UV0,model->GetTransform(),true); - } - glDisable(GL_BLEND); - glDisable(GL_ALPHA_TEST); - glDepthMask(1); - - // switch off client states - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - - if (g_Renderer.m_ModelRenderMode==WIREFRAME) { - // switch wireframe off again - glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); - } else if (g_Renderer.m_ModelRenderMode==EDGED_FACES) { - // edged faces: need to make a second pass over the data: - // first switch on wireframe - glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); - - // setup some renderstate .. - glDepthMask(0); - g_Renderer.SetTexture(0,0); - glColor4f(1,1,1,0.75f); - glLineWidth(1.0f); - - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); - - // .. and some client states - glEnableClientState(GL_VERTEX_ARRAY); - - // render each model - for (i=0;iGetRenderData(); - modeldata->RenderStreams(STREAM_POS,model->GetTransform(),true); - } - - // .. and switch off the client states - glDisableClientState(GL_VERTEX_ARRAY); - - // .. and restore the renderstates - glDisable(GL_BLEND); - glDepthMask(1); - - // restore fill mode, and we're done - glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); - } - - // all transparent objects rendered; release them - m_Objects.clear(); -} - -void CTransparencyRenderer::Add(CModel* model) -{ - // resize array, get last object in list - m_Objects.resize(m_Objects.size()+1); - - SObject& obj=m_Objects.back(); - obj.m_Model=model; - - // build transform from object to camera space - CMatrix3D objToCam,invcam; - g_Renderer.m_Camera.m_Orientation.GetInverse(objToCam); - objToCam*=model->GetTransform(); - - // resort model indices from back to front, according to camera position - and store - // the returned sqrd distance to the centre of the nearest triangle - CModelRData* modeldata=(CModelRData*) model->GetRenderData(); - obj.m_Dist=modeldata->BackToFrontIndexSort(objToCam); -} +#include +#include "Renderer.h" +#include "TransparencyRenderer.h" +#include "terrain/Model.h" + + +CTransparencyRenderer g_TransparencyRenderer; + + +struct SortObjectsByDist { + typedef CTransparencyRenderer::SObject SortObj; + + bool operator()(const SortObj& lhs,const SortObj& rhs) { + return lhs.m_Dist>rhs.m_Dist? true : false; + } +}; + +void CTransparencyRenderer::Render() +{ + // coarsely sort submitted objects in back to front manner + std::sort(m_Objects.begin(),m_Objects.end(),SortObjectsByDist()); + + // switch on wireframe if we need it + if (g_Renderer.m_ModelRenderMode==WIREFRAME) { + glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); + } + + // switch on client states + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + // setup texture environment to modulate diffuse color with texture color + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PRIMARY_COLOR); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR); + + // just pass through texture's alpha + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA); + + glEnable(GL_ALPHA_TEST); + glAlphaFunc(GL_GREATER,0.975f); + + uint i; + for (i=0;iGetRenderData(); + modeldata->RenderStreams(STREAM_POS|STREAM_COLOR|STREAM_UV0,model->GetTransform(),true); + } + + glDepthMask(0); + glAlphaFunc(GL_LEQUAL,0.975f); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); + + for (i=0;iGetRenderData(); + modeldata->RenderStreams(STREAM_POS|STREAM_COLOR|STREAM_UV0,model->GetTransform(),true); + } + glDisable(GL_BLEND); + glDisable(GL_ALPHA_TEST); + glDepthMask(1); + + // switch off client states + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + + if (g_Renderer.m_ModelRenderMode==WIREFRAME) { + // switch wireframe off again + glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); + } else if (g_Renderer.m_ModelRenderMode==EDGED_FACES) { + // edged faces: need to make a second pass over the data: + // first switch on wireframe + glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); + + // setup some renderstate .. + glDepthMask(0); + g_Renderer.SetTexture(0,0); + glColor4f(1,1,1,0.75f); + glLineWidth(1.0f); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); + + // .. and some client states + glEnableClientState(GL_VERTEX_ARRAY); + + // render each model + for (i=0;iGetRenderData(); + modeldata->RenderStreams(STREAM_POS,model->GetTransform(),true); + } + + // .. and switch off the client states + glDisableClientState(GL_VERTEX_ARRAY); + + // .. and restore the renderstates + glDisable(GL_BLEND); + glDepthMask(1); + + // restore fill mode, and we're done + glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); + } + + // all transparent objects rendered; release them + m_Objects.clear(); +} + +void CTransparencyRenderer::Add(CModel* model) +{ + // resize array, get last object in list + m_Objects.resize(m_Objects.size()+1); + + SObject& obj=m_Objects.back(); + obj.m_Model=model; + + // build transform from object to camera space + CMatrix3D objToCam,invcam; + g_Renderer.m_Camera.m_Orientation.GetInverse(objToCam); + objToCam*=model->GetTransform(); + + // resort model indices from back to front, according to camera position - and store + // the returned sqrd distance to the centre of the nearest triangle + CModelRData* modeldata=(CModelRData*) model->GetRenderData(); + obj.m_Dist=modeldata->BackToFrontIndexSort(objToCam); +} \ No newline at end of file diff --git a/source/terrain/TransparencyRenderer.h b/source/terrain/TransparencyRenderer.h index a3b730d2a0..e83cf71ba6 100755 --- a/source/terrain/TransparencyRenderer.h +++ b/source/terrain/TransparencyRenderer.h @@ -1,31 +1,31 @@ -#ifndef __TRANSPARENCYRENDERER_H -#define __TRANSPARENCYRENDERER_H - -#include - -class CModel; - -class CTransparencyRenderer -{ -public: - struct SObject { - // the transparent model - CModel* m_Model; - // sqrd distance from camera to centre of nearest triangle - float m_Dist; - }; - -public: - // add object to render in deferred transparency pass - void Add(CModel* model); - // render all deferred objects - void Render(); - -private: - // list of transparent objects to render - std::vector m_Objects; -}; - -extern CTransparencyRenderer g_TransparencyRenderer; - -#endif +#ifndef __TRANSPARENCYRENDERER_H +#define __TRANSPARENCYRENDERER_H + +#include + +class CModel; + +class CTransparencyRenderer +{ +public: + struct SObject { + // the transparent model + CModel* m_Model; + // sqrd distance from camera to centre of nearest triangle + float m_Dist; + }; + +public: + // add object to render in deferred transparency pass + void Add(CModel* model); + // render all deferred objects + void Render(); + +private: + // list of transparent objects to render + std::vector m_Objects; +}; + +extern CTransparencyRenderer g_TransparencyRenderer; + +#endif diff --git a/source/terrain/Unit.h b/source/terrain/Unit.h index 18649338e4..7b2f78b2fb 100755 --- a/source/terrain/Unit.h +++ b/source/terrain/Unit.h @@ -1,16 +1,16 @@ -#ifndef _UNIT_H -#define _UNIT_H - -class CModel; -class CObjectEntry; - -class CUnit -{ -public: - // object from which unit was created - CObjectEntry* m_Object; - // object model representation - CModel* m_Model; -}; - -#endif +#ifndef _UNIT_H +#define _UNIT_H + +class CModel; +class CObjectEntry; + +class CUnit +{ +public: + // object from which unit was created + CObjectEntry* m_Object; + // object model representation + CModel* m_Model; +}; + +#endif diff --git a/source/terrain/UnitManager.cpp b/source/terrain/UnitManager.cpp index ee309503a2..cf54802dd0 100755 --- a/source/terrain/UnitManager.cpp +++ b/source/terrain/UnitManager.cpp @@ -1,28 +1,28 @@ -#include "res/res.h" -#include "UnitManager.h" -#include - -CUnitManager g_UnitMan; - -void CUnitManager::AddUnit(CUnit* unit) -{ - m_Units.push_back(unit); -} - -void CUnitManager::RemoveUnit(CUnit* unit) -{ - // find entry in list - typedef std::vector::iterator Iter; - Iter i=std::find(m_Units.begin(),m_Units.end(),unit); - if (i!=m_Units.end()) { - m_Units.erase(i); - } -} - -void CUnitManager::DeleteAll() -{ - for (uint i=0;i + +CUnitManager g_UnitMan; + +void CUnitManager::AddUnit(CUnit* unit) +{ + m_Units.push_back(unit); +} + +void CUnitManager::RemoveUnit(CUnit* unit) +{ + // find entry in list + typedef std::vector::iterator Iter; + Iter i=std::find(m_Units.begin(),m_Units.end(),unit); + if (i!=m_Units.end()) { + m_Units.erase(i); + } +} + +void CUnitManager::DeleteAll() +{ + for (uint i=0;i -#include "Unit.h" - -class CUnitManager -{ -public: - CUnitManager() {} - - void AddUnit(CUnit* unit); - void RemoveUnit(CUnit* unit); - - void DeleteAll(); - - const std::vector& GetUnits() const { return m_Units; } - -private: - std::vector m_Units; -}; - -extern CUnitManager g_UnitMan; - +#ifndef _UNITMANAGER_H +#define _UNITMANAGER_H + +#include +#include "Unit.h" + +class CUnitManager +{ +public: + CUnitManager() {} + + void AddUnit(CUnit* unit); + void RemoveUnit(CUnit* unit); + + void DeleteAll(); + + const std::vector& GetUnits() const { return m_Units; } + +private: + std::vector m_Units; +}; + +extern CUnitManager g_UnitMan; + #endif \ No newline at end of file diff --git a/source/terrain/Vector3D.cpp b/source/terrain/Vector3D.cpp index b9abbef429..2f3a3b2ca3 100755 --- a/source/terrain/Vector3D.cpp +++ b/source/terrain/Vector3D.cpp @@ -1,153 +1,153 @@ -//*********************************************************** -// -// Name: Vector3D.Cpp -// Last Update: 28/1/02 -// Author: Poya Manouchehri -// -// Description: Provides an interface for a vector in R3 and -// allows vector and scalar operations on it -// -//*********************************************************** - -#include "Vector3D.h" - -CVector3D::CVector3D (float x, float y, float z) -{ - X = x; - Y = y; - Z = z; -} - -int CVector3D::operator ! () const -{ - if (X != 0.0f || - Y != 0.0f || - Z != 0.0f) - - return 0; - - return 1; -} - -//vector addition -CVector3D CVector3D::operator + (const CVector3D &vector) const -{ - CVector3D Temp; - - Temp.X = X + vector.X; - Temp.Y = Y + vector.Y; - Temp.Z = Z + vector.Z; - - return Temp; -} - -//vector addition/assignment -CVector3D &CVector3D::operator += (const CVector3D &vector) -{ - X += vector.X; - Y += vector.Y; - Z += vector.Z; - - return *this; -} - -//vector subtraction -CVector3D CVector3D::operator - (const CVector3D &vector) const -{ - CVector3D Temp; - - Temp.X = X - vector.X; - Temp.Y = Y - vector.Y; - Temp.Z = Z - vector.Z; - - return Temp; -} - -//vector negation -CVector3D CVector3D::operator-() const -{ - CVector3D Temp; - - Temp.X = -X; - Temp.Y = -Y; - Temp.Z = -Z; - - return Temp; -} -//vector subtrcation/assignment -CVector3D &CVector3D::operator -= (const CVector3D &vector) -{ - X -= vector.X; - Y -= vector.Y; - Z -= vector.Z; - - return *this; -} - -//scalar multiplication -CVector3D CVector3D::operator * (float value) const -{ - CVector3D Temp; - - Temp.X = X * value; - Temp.Y = Y * value; - Temp.Z = Z * value; - - return Temp; -} - -//scalar multiplication/assignment -CVector3D& CVector3D::operator *= (float value) -{ - X *= value; - Y *= value; - Z *= value; - - return *this; -} - -void CVector3D::Set (float x, float y, float z) -{ - X = x; - Y = y; - Z = z; -} - -void CVector3D::Clear () -{ - X = Y = Z = 0.0f; -} - -//Dot product -float CVector3D::Dot (const CVector3D &vector) const -{ - return ( X * vector.X + - Y * vector.Y + - Z * vector.Z ); -} - -//Cross product -CVector3D CVector3D::Cross (const CVector3D &vector) const -{ - CVector3D Temp; - - Temp.X = (Y * vector.Z) - (Z * vector.Y); - Temp.Y = (Z * vector.X) - (X * vector.Z); - Temp.Z = (X * vector.Y) - (Y * vector.X); - - return Temp; -} - -float CVector3D::GetLength () const -{ - return sqrtf ( SQR(X) + SQR(Y) + SQR(Z) ); -} - -void CVector3D::Normalize () -{ - float scale = 1.0f/GetLength (); - - X *= scale; - Y *= scale; - Z *= scale; -} +//*********************************************************** +// +// Name: Vector3D.Cpp +// Last Update: 28/1/02 +// Author: Poya Manouchehri +// +// Description: Provides an interface for a vector in R3 and +// allows vector and scalar operations on it +// +//*********************************************************** + +#include "Vector3D.h" + +CVector3D::CVector3D (float x, float y, float z) +{ + X = x; + Y = y; + Z = z; +} + +int CVector3D::operator ! () const +{ + if (X != 0.0f || + Y != 0.0f || + Z != 0.0f) + + return 0; + + return 1; +} + +//vector addition +CVector3D CVector3D::operator + (const CVector3D &vector) const +{ + CVector3D Temp; + + Temp.X = X + vector.X; + Temp.Y = Y + vector.Y; + Temp.Z = Z + vector.Z; + + return Temp; +} + +//vector addition/assignment +CVector3D &CVector3D::operator += (const CVector3D &vector) +{ + X += vector.X; + Y += vector.Y; + Z += vector.Z; + + return *this; +} + +//vector subtraction +CVector3D CVector3D::operator - (const CVector3D &vector) const +{ + CVector3D Temp; + + Temp.X = X - vector.X; + Temp.Y = Y - vector.Y; + Temp.Z = Z - vector.Z; + + return Temp; +} + +//vector negation +CVector3D CVector3D::operator-() const +{ + CVector3D Temp; + + Temp.X = -X; + Temp.Y = -Y; + Temp.Z = -Z; + + return Temp; +} +//vector subtrcation/assignment +CVector3D &CVector3D::operator -= (const CVector3D &vector) +{ + X -= vector.X; + Y -= vector.Y; + Z -= vector.Z; + + return *this; +} + +//scalar multiplication +CVector3D CVector3D::operator * (float value) const +{ + CVector3D Temp; + + Temp.X = X * value; + Temp.Y = Y * value; + Temp.Z = Z * value; + + return Temp; +} + +//scalar multiplication/assignment +CVector3D& CVector3D::operator *= (float value) +{ + X *= value; + Y *= value; + Z *= value; + + return *this; +} + +void CVector3D::Set (float x, float y, float z) +{ + X = x; + Y = y; + Z = z; +} + +void CVector3D::Clear () +{ + X = Y = Z = 0.0f; +} + +//Dot product +float CVector3D::Dot (const CVector3D &vector) const +{ + return ( X * vector.X + + Y * vector.Y + + Z * vector.Z ); +} + +//Cross product +CVector3D CVector3D::Cross (const CVector3D &vector) const +{ + CVector3D Temp; + + Temp.X = (Y * vector.Z) - (Z * vector.Y); + Temp.Y = (Z * vector.X) - (X * vector.Z); + Temp.Z = (X * vector.Y) - (Y * vector.X); + + return Temp; +} + +float CVector3D::GetLength () const +{ + return sqrtf ( SQR(X) + SQR(Y) + SQR(Z) ); +} + +void CVector3D::Normalize () +{ + float scale = 1.0f/GetLength (); + + X *= scale; + Y *= scale; + Z *= scale; +} diff --git a/source/terrain/Vector3D.h b/source/terrain/Vector3D.h index 30c59f79b8..8a68a1f6bd 100755 --- a/source/terrain/Vector3D.h +++ b/source/terrain/Vector3D.h @@ -1,67 +1,67 @@ -//*********************************************************** -// -// Name: Vector3D.H -// Last Update: 28/1/02 -// Author: Poya Manouchehri -// -// Description: Provides an interface for a vector in R3 and -// allows vector and scalar operations on it -// -//*********************************************************** - -#ifndef VECTOR3D_H -#define VECTOR3D_H - -#include -#include "res/res.h" -#include "MathUtil.h" - -class CVector3D -{ - public: - float X, Y, Z; - - public: - CVector3D () { } - CVector3D (float x, float y, float z); - - int operator ! () const ; - - float& operator[](int index) { return *((&X)+index); } - const float& operator[](int index) const { return *((&X)+index); } - - //vector addition - CVector3D operator + (const CVector3D &vector) const ; - //vector addition/assignment - CVector3D &operator += (const CVector3D &vector); - - //vector subtraction - CVector3D operator - (const CVector3D &vector) const ; - //vector subtraction/assignment - CVector3D &operator -= (const CVector3D &vector); - - //scalar multiplication - CVector3D operator * (float value) const ; - //scalar multiplication/assignment - CVector3D& operator *= (float value); - - // negation - CVector3D operator-() const; - - public: - void Set (float x, float y, float z); - void Clear (); - - //Dot product - float Dot (const CVector3D &vector) const; - //Cross product - CVector3D Cross (const CVector3D &vector) const; - - //Returns length of the vector - float GetLength () const; - void Normalize (); - -}; - - -#endif +//*********************************************************** +// +// Name: Vector3D.H +// Last Update: 28/1/02 +// Author: Poya Manouchehri +// +// Description: Provides an interface for a vector in R3 and +// allows vector and scalar operations on it +// +//*********************************************************** + +#ifndef VECTOR3D_H +#define VECTOR3D_H + +#include +#include "res/res.h" +#include "MathUtil.h" + +class CVector3D +{ + public: + float X, Y, Z; + + public: + CVector3D () { } + CVector3D (float x, float y, float z); + + int operator ! () const ; + + float& operator[](int index) { return *((&X)+index); } + const float& operator[](int index) const { return *((&X)+index); } + + //vector addition + CVector3D operator + (const CVector3D &vector) const ; + //vector addition/assignment + CVector3D &operator += (const CVector3D &vector); + + //vector subtraction + CVector3D operator - (const CVector3D &vector) const ; + //vector subtraction/assignment + CVector3D &operator -= (const CVector3D &vector); + + //scalar multiplication + CVector3D operator * (float value) const ; + //scalar multiplication/assignment + CVector3D& operator *= (float value); + + // negation + CVector3D operator-() const; + + public: + void Set (float x, float y, float z); + void Clear (); + + //Dot product + float Dot (const CVector3D &vector) const; + //Cross product + CVector3D Cross (const CVector3D &vector) const; + + //Returns length of the vector + float GetLength () const; + void Normalize (); + +}; + + +#endif diff --git a/source/terrain/Vector4D.h b/source/terrain/Vector4D.h index ba8468c374..081dc225e6 100755 --- a/source/terrain/Vector4D.h +++ b/source/terrain/Vector4D.h @@ -1,110 +1,110 @@ -//*********************************************************** -// -// Name: CVector4D.h -// Last Update: 02/11/03 -// Author: Rich Cross -// -// Description: Provides an interface for a vector in R4 and -// allows vector and scalar operations on it -// -//*********************************************************** - -#ifndef _VECTOR4D_H -#define _VECTOR4D_H - - -#include - -/////////////////////////////////////////////////////////////////////////////// -// CVector4D: -class CVector4D -{ -public: - CVector4D() {} - CVector4D(const float f[4]) { m_X=f[0]; m_Y=f[1]; m_Z=f[2]; m_W=f[3]; } - CVector4D(float x,float y,float z,float w) { m_X=x; m_Y=y; m_Z=z; m_W=w; } - CVector4D(const CVector4D& p) { m_X=p.m_X; m_Y=p.m_Y; m_Z=p.m_Z; m_W=p.m_W; } - - operator float*() { - return &m_X; - } - - operator const float*() const { - return &m_X; - } - - CVector4D operator-() const { - return CVector4D(-m_X,-m_Y,-m_Z,-m_W); - } - - CVector4D operator+(const CVector4D& t) const { - return CVector4D(m_X+t.m_X,m_Y+t.m_Y,m_Z+t.m_Z,m_W+t.m_W); - } - - CVector4D operator-(const CVector4D& t) const { - return CVector4D(m_X-t.m_X,m_Y-t.m_Y,m_Z-t.m_Z,m_W-t.m_W); - } - - CVector4D operator*(const CVector4D& t) const { - return CVector4D(m_X*t.m_X,m_Y*t.m_Y,m_Z*t.m_Z,m_W*t.m_W); - } - - CVector4D operator*(float f) const { - return CVector4D(m_X*f,m_Y*f,m_Z*f,m_W*f); - } - - CVector4D operator/(float f) const { - float inv=1.0f/f; - return CVector4D(m_X*inv,m_Y*inv,m_Z*inv,m_W*inv); - } - - CVector4D& operator+=(const CVector4D& t) { - m_X+=t.m_X; m_Y+=t.m_Y; m_Z+=t.m_Z; m_W+=t.m_W; - return *this; - } - - CVector4D& operator-=(const CVector4D& t) { - m_X-=t.m_X; m_Y-=t.m_Y; m_Z-=t.m_Z; m_W-=t.m_W; - return *this; - } - - CVector4D& operator*=(const CVector4D& t) { - m_X*=t.m_X; m_Y*=t.m_Y; m_Z*=t.m_Z; m_W*=t.m_W; - return *this; - } - - CVector4D& operator*=(float f) { - m_X*=f; m_Y*=f; m_Z*=f; m_W*=f; - return *this; - } - - CVector4D& operator/=(float f) { - float invf=1.0f/f; - m_X*=invf; m_Y*=invf; m_Z*=invf; m_W*=invf; - return *this; - } - - float dot(const CVector4D& a) const { - return m_X*a.m_X+m_Y*a.m_Y+m_Z*a.m_Z+m_W*a.m_W; - } - - float lengthSquared() const { - return SQR(m_X)+SQR(m_Y)+SQR(m_Z)+SQR(m_W); - } - - float length() const { - return (float) sqrt(lengthSquared()); - } - - void normalize() { - float mag=length(); - m_X/=mag; m_Y/=mag; m_Z/=mag; m_W/=mag; - } - -public: - float m_X,m_Y,m_Z,m_W; -}; -////////////////////////////////////////////////////////////////////////////////// - - -#endif +//*********************************************************** +// +// Name: CVector4D.h +// Last Update: 02/11/03 +// Author: Rich Cross +// +// Description: Provides an interface for a vector in R4 and +// allows vector and scalar operations on it +// +//*********************************************************** + +#ifndef _VECTOR4D_H +#define _VECTOR4D_H + + +#include + +/////////////////////////////////////////////////////////////////////////////// +// CVector4D: +class CVector4D +{ +public: + CVector4D() {} + CVector4D(const float f[4]) { m_X=f[0]; m_Y=f[1]; m_Z=f[2]; m_W=f[3]; } + CVector4D(float x,float y,float z,float w) { m_X=x; m_Y=y; m_Z=z; m_W=w; } + CVector4D(const CVector4D& p) { m_X=p.m_X; m_Y=p.m_Y; m_Z=p.m_Z; m_W=p.m_W; } + + operator float*() { + return &m_X; + } + + operator const float*() const { + return &m_X; + } + + CVector4D operator-() const { + return CVector4D(-m_X,-m_Y,-m_Z,-m_W); + } + + CVector4D operator+(const CVector4D& t) const { + return CVector4D(m_X+t.m_X,m_Y+t.m_Y,m_Z+t.m_Z,m_W+t.m_W); + } + + CVector4D operator-(const CVector4D& t) const { + return CVector4D(m_X-t.m_X,m_Y-t.m_Y,m_Z-t.m_Z,m_W-t.m_W); + } + + CVector4D operator*(const CVector4D& t) const { + return CVector4D(m_X*t.m_X,m_Y*t.m_Y,m_Z*t.m_Z,m_W*t.m_W); + } + + CVector4D operator*(float f) const { + return CVector4D(m_X*f,m_Y*f,m_Z*f,m_W*f); + } + + CVector4D operator/(float f) const { + float inv=1.0f/f; + return CVector4D(m_X*inv,m_Y*inv,m_Z*inv,m_W*inv); + } + + CVector4D& operator+=(const CVector4D& t) { + m_X+=t.m_X; m_Y+=t.m_Y; m_Z+=t.m_Z; m_W+=t.m_W; + return *this; + } + + CVector4D& operator-=(const CVector4D& t) { + m_X-=t.m_X; m_Y-=t.m_Y; m_Z-=t.m_Z; m_W-=t.m_W; + return *this; + } + + CVector4D& operator*=(const CVector4D& t) { + m_X*=t.m_X; m_Y*=t.m_Y; m_Z*=t.m_Z; m_W*=t.m_W; + return *this; + } + + CVector4D& operator*=(float f) { + m_X*=f; m_Y*=f; m_Z*=f; m_W*=f; + return *this; + } + + CVector4D& operator/=(float f) { + float invf=1.0f/f; + m_X*=invf; m_Y*=invf; m_Z*=invf; m_W*=invf; + return *this; + } + + float dot(const CVector4D& a) const { + return m_X*a.m_X+m_Y*a.m_Y+m_Z*a.m_Z+m_W*a.m_W; + } + + float lengthSquared() const { + return SQR(m_X)+SQR(m_Y)+SQR(m_Z)+SQR(m_W); + } + + float length() const { + return (float) sqrt(lengthSquared()); + } + + void normalize() { + float mag=length(); + m_X/=mag; m_Y/=mag; m_Z/=mag; m_W/=mag; + } + +public: + float m_X,m_Y,m_Z,m_W; +}; +////////////////////////////////////////////////////////////////////////////////// + + +#endif diff --git a/source/terrain/terrainMain.cpp b/source/terrain/terrainMain.cpp index 93fcf738c4..b18e2627a4 100755 --- a/source/terrain/terrainMain.cpp +++ b/source/terrain/terrainMain.cpp @@ -1,3 +1,4 @@ + #include "Matrix3D.h" #include "Renderer.h" #include "Terrain.h" @@ -23,21 +24,27 @@ void RenderScene (); extern bool keys[512]; // SDL also defines non-ascii keys; 512 should be enough -//CMatrix3D g_WorldMat; +CMatrix3D g_WorldMat; CRenderer g_Renderer; CTerrain g_Terrain; CCamera g_Camera; CLightEnv g_LightEnv; +int SelPX, SelPY, SelTX, SelTY; +int g_BaseTexCounter = 0; +int g_SecTexCounter = 1; +int g_TransTexCounter = 0; + +int g_TickCounter = 0; +double g_LastTime; + + +const int NUM_ALPHA_MAPS = 13; +const float ViewScrollSpeed = 60; +float ViewFOV; int mouse_x=50, mouse_y=50; - -float ViewScrollSpeed = 60.0f; -float ViewZoomFactor = 1.0f; -float ViewFOV = 0.0f; - - void terr_init() { int xres,yres; @@ -55,13 +62,12 @@ void terr_init() InitScene (); } - void terr_update(const float DeltaTime) { const float dx = ViewScrollSpeed * DeltaTime; const CVector3D Right(dx,0, dx); const CVector3D Up (dx,0,-dx); - + if (mouse_x >= g_xres-2) g_Camera.m_Orientation.Translate(Right); if (mouse_x <= 3) @@ -73,6 +79,7 @@ void terr_update(const float DeltaTime) g_Camera.m_Orientation.Translate(Up*-1); + const float s30 = sin(DEGTORAD(30.0f)); const float c30 = cos(DEGTORAD(30.0f)); const float s45 = sin(DEGTORAD(45.0f)); @@ -102,6 +109,8 @@ void terr_update(const float DeltaTime) + + bool terr_handler(const SDL_Event& ev) { switch(ev.type) @@ -129,7 +138,105 @@ bool terr_handler(const SDL_Event& ev) g_Camera.m_Orientation.RotateY(DEGTORAD(-45)); g_Camera.m_Orientation.Translate (100, 150, -100); break; - } + +/* case 'L': + g_HillShading = !g_HillShading; + break; + +// tile selection + case SDLK_DOWN: + if(++SelTX > 15) + if(SelPX == g_Terrain.GetPatchesPerSide()-1) + SelTX = 15; + else + SelTX = 0, SelPX++; + break; + + case SDLK_UP: + if(--SelTX < 0) + if(SelPX == 0) + SelTX = 0; + else + SelTX = 15, SelPX--; + break; + case SDLK_RIGHT: + if(++SelTY > 15) + if(SelPY == g_Terrain.GetPatchesPerSide()-1) + SelTY = 15; + else + SelTY = 0, SelPY++; + break; + + case SDLK_LEFT: + if(--SelTY < 0) + if(SelPY == 0) + SelTY = 0; + else + SelTY = 15, SelPY--; + break; + + + case SDLK_KP0: + { + CMiniPatch *MPatch = &g_Terrain.GetPatch(SelPY, SelPX)->m_MiniPatches[SelTY][SelTX]; + /*if (!MPatch->Tex2) + { + MPatch->m_AlphaMap = AlphaMaps[g_TransTexCounter]; + MPatch->Tex2 = BaseTexs[g_SecTexCounter]; + } + else + { + MPatch->Tex2 = 0; + MPatch->m_AlphaMap = 0; + }*/ + break; + } + + /*case SDLK_KP1: + { + CMiniPatch *MPatch = &g_Terrain.GetPatch(SelPY, SelPX)->m_MiniPatches[SelTY][SelTX]; + + g_BaseTexCounter++; + if (g_BaseTexCounter > 4) + g_BaseTexCounter = 0; + + MPatch->Tex1 = BaseTexs[g_BaseTexCounter]; + break; + } + + case SDLK_KP2: + { + CMiniPatch *MPatch = &g_Terrain.m_Patches[SelPY][SelPX].m_MiniPatches[SelTY][SelTX]; + + if (MPatch->Tex2) + { + g_SecTexCounter++; + if (g_SecTexCounter > 4) + g_SecTexCounter = 0; + + MPatch->Tex2 = BaseTexs[g_SecTexCounter]; + } + + break; + } + + case SDLK_KP3: + { + CMiniPatch *MPatch = &g_Terrain.m_Patches[SelPY][SelPX].m_MiniPatches[SelTY][SelTX]; + + if (MPatch->m_AlphaMap) + { + g_TransTexCounter++; + if (g_TransTexCounter >= NUM_ALPHA_MAPS) + g_TransTexCounter = 0; + + MPatch->m_AlphaMap = AlphaMaps[g_TransTexCounter]; + } + + break; + }*/ + + //} } return false; @@ -156,7 +263,7 @@ void InitScene () int w; int h; - tex_info(ht, &w, &h, NULL, NULL, (void**)&p); + tex_info(ht, &w, &h, NULL, NULL, (void **)&p); printf("terrain.raw: %dx%d\n", w, h); @@ -203,6 +310,7 @@ for (uint ii=0;ii