forked from 0ad/0ad
Added PASAP entity systems
This was SVN commit r246.
This commit is contained in:
parent
6f2aba631b
commit
6d5afc10ff
@ -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;i<units.size();++i) {
|
||||
units[i]->m_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;
|
||||
}
|
||||
|
@ -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" }
|
||||
|
@ -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 <vector>
|
||||
#include <iostream>
|
||||
|
||||
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<USHORT>& 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<USHORT>& GetBuildingsReqToBuild( void ) { return( m_vBuildingsReqToBuild ); };
|
||||
|
||||
inline
|
||||
virtual const std::vector<USHORT>& 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<USHORT>& GetBuildingsReqToUpgrade( void ) { return( m_vBuildingsReqToUpgrade ); };
|
||||
|
||||
inline
|
||||
virtual const std::vector<USHORT>& 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<USHORT> 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<USHORT> m_vBuildingsReqToBuild; // buildings required to build this entity
|
||||
std::vector<USHORT> 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<USHORT> m_vBuildingsReqToUpgrade; // buildings required to upgrade this entity
|
||||
std::vector<USHORT> 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
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 );
|
||||
}
|
@ -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<CHandlePool>
|
||||
{
|
||||
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 )
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
@ -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<namelen;i++) {
|
||||
char c;
|
||||
if (fread(&c,sizeof(char),1,fp)!=1) {
|
||||
fclose(fp);
|
||||
delete font;
|
||||
return 0;
|
||||
}
|
||||
texname+=c;
|
||||
}
|
||||
font->_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<namelen;i++) {
|
||||
char c;
|
||||
if (fread(&c,sizeof(char),1,fp)!=1) {
|
||||
fclose(fp);
|
||||
delete font;
|
||||
return 0;
|
||||
}
|
||||
texname+=c;
|
||||
}
|
||||
font->_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++;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -1,102 +1,102 @@
|
||||
#include "NPFontManager.h"
|
||||
#include "NPFont.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
// 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<NPFont*>::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 <algorithm>
|
||||
|
||||
// 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<NPFont*>::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;
|
||||
|
||||
}
|
||||
|
@ -1,39 +1,39 @@
|
||||
#ifndef _FONTMANAGER_H
|
||||
#define _FONTMANAGER_H
|
||||
|
||||
// necessary includes
|
||||
#include <vector>
|
||||
|
||||
// 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<NPFont*> _fonts;
|
||||
|
||||
// the sole instance of the FontManager
|
||||
static NPFontManager* _instance;
|
||||
};
|
||||
|
||||
#endif
|
||||
#ifndef _FONTMANAGER_H
|
||||
#define _FONTMANAGER_H
|
||||
|
||||
// necessary includes
|
||||
#include <vector>
|
||||
|
||||
// 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<NPFont*> _fonts;
|
||||
|
||||
// the sole instance of the FontManager
|
||||
static NPFontManager* _instance;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -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()
|
||||
{
|
||||
}
|
@ -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
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
91
source/simulation/BaseEntity.cpp
Executable file
91
source/simulation/BaseEntity.cpp
Executable file
@ -0,0 +1,91 @@
|
||||
#include "BaseEntity.h"
|
||||
#include "ObjectManager.h"
|
||||
#include "CStr.h"
|
||||
|
||||
// xerces XML stuff
|
||||
#include <xercesc/dom/DOM.hpp>
|
||||
#include <xercesc/parsers/XercesDOMParser.hpp>
|
||||
#include <xercesc/framework/LocalFileInputSource.hpp>
|
||||
#include <xercesc/util/XMLString.hpp>
|
||||
#include <xercesc/util/PlatformUtils.hpp>
|
||||
|
||||
// Gee's custom error handler
|
||||
#include <ps/XercesErrorHandler.h>
|
||||
|
||||
// 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; i<numChildren; ++i) {
|
||||
// Get node
|
||||
DOMNode *child = children->item(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;
|
||||
}
|
27
source/simulation/BaseEntity.h
Executable file
27
source/simulation/BaseEntity.h
Executable file
@ -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<CStr,CGenericProperty,CStr_hash_compare> m_properties;
|
||||
};
|
||||
|
||||
#endif
|
67
source/simulation/BaseEntityCollection.cpp
Executable file
67
source/simulation/BaseEntityCollection.cpp
Executable file
@ -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 );
|
||||
}
|
24
source/simulation/BaseEntityCollection.h
Executable file
24
source/simulation/BaseEntityCollection.h
Executable file
@ -0,0 +1,24 @@
|
||||
// Last modified: May 15 2004, Mark Thompson (mark@wildfiregames.com)
|
||||
|
||||
#ifndef BASEENT_COLLECTION_INCLUDED
|
||||
#define BASEENT_COLLECTION_INCLUDED
|
||||
|
||||
#include <vector>
|
||||
#include "CStr.h"
|
||||
#include "Singleton.h"
|
||||
#include "ObjectEntry.h"
|
||||
#include "BaseEntity.h"
|
||||
|
||||
#define g_EntityTemplateCollection CBaseEntityCollection::GetSingleton()
|
||||
|
||||
class CBaseEntityCollection : public Singleton<CBaseEntityCollection>
|
||||
{
|
||||
std::vector<CBaseEntity> m_templates;
|
||||
public:
|
||||
CBaseEntity* getTemplate( CStr entityType );
|
||||
void loadTemplates();
|
||||
void addTemplate( CBaseEntity& temp );
|
||||
CBaseEntity* getTemplateByActor( CObjectEntry* actor );
|
||||
};
|
||||
|
||||
#endif
|
242
source/simulation/Entity.cpp
Executable file
242
source/simulation/Entity.cpp
Executable file
@ -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<HEntity>* waypoints = g_EntityManager.matches( isWaypoint );
|
||||
while( !waypoints->empty() )
|
||||
{
|
||||
CEntityOrder patrol;
|
||||
int id = rand() % waypoints->size();
|
||||
std::vector<HEntity>::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 );
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
}
|
54
source/simulation/Entity.h
Executable file
54
source/simulation/Entity.h
Executable file
@ -0,0 +1,54 @@
|
||||
// Last modified: May 15 2004, Mark Thompson (mark@wildfiregames.com)
|
||||
|
||||
#ifndef ENTITY_INCLUDED
|
||||
#define ENTITY_INCLUDED
|
||||
|
||||
#include <deque>
|
||||
#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<CEntityOrder> m_orderQueue;
|
||||
|
||||
// Extended properties table
|
||||
|
||||
std::hash_map<CStr,CGenericProperty,CStr_hash_compare> 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
|
71
source/simulation/EntityHandles.cpp
Executable file
71
source/simulation/EntityHandles.cpp
Executable file
@ -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 );
|
||||
}
|
||||
|
35
source/simulation/EntityHandles.h
Executable file
35
source/simulation/EntityHandles.h
Executable file
@ -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
|
56
source/simulation/EntityManager.cpp
Executable file
56
source/simulation/EntityManager.cpp
Executable file
@ -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<HEntity>* CEntityManager::matches( EntityPredicate predicate )
|
||||
{
|
||||
std::vector<HEntity>* matchlist = new std::vector<HEntity>;
|
||||
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;
|
35
source/simulation/EntityManager.h
Executable file
35
source/simulation/EntityManager.h
Executable file
@ -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<CEntityManager>
|
||||
{
|
||||
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<HEntity>* 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
|
19
source/simulation/EntityMessage.h
Executable file
19
source/simulation/EntityMessage.h
Executable file
@ -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
|
36
source/simulation/EntityOrders.h
Executable file
36
source/simulation/EntityOrders.h
Executable file
@ -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
|
160
source/simulation/EntityProperties.cpp
Executable file
160
source/simulation/EntityProperties.cpp
Executable file
@ -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 );
|
||||
}
|
||||
}
|
65
source/simulation/EntityProperties.h
Executable file
65
source/simulation/EntityProperties.h
Executable file
@ -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 <hash_map>
|
||||
|
||||
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
|
||||
|
@ -1,303 +1,303 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: AlphaMapCalculator.cpp
|
||||
// Author: Rich Cross
|
||||
// Contact: rich@wildfiregames.com
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "AlphaMapCalculator.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// 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<class T>
|
||||
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<class T>
|
||||
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<class S,class T>
|
||||
int LookupBlend(int tableSize,const S* table,const T& shape,unsigned int& flags)
|
||||
{
|
||||
// iterate through known blend shapes
|
||||
for (int b=0;b<tableSize;b++) {
|
||||
const S& blend=table[b];
|
||||
if (MatchBlendShape(blend.m_Shape,shape,flags)) {
|
||||
return blend.m_AlphaMap;
|
||||
}
|
||||
}
|
||||
|
||||
// eh? shouldn't get here if we've correctly considered all possible cases;
|
||||
// keep the compiler happy, and, while we're still debugging possible shapes,
|
||||
// return bad blend to highlight suspect alphamap logic
|
||||
return 13;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// 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)
|
||||
{
|
||||
// assume we're not going to require flipping or rotating
|
||||
flags=0;
|
||||
|
||||
// count number of neighbours
|
||||
int count=0;
|
||||
for (int i=0;i<8;i++) {
|
||||
if (shape[i]) count++;
|
||||
}
|
||||
|
||||
if (count==0) {
|
||||
// no neighbours, just the centre tile has the given texture; use blend circle
|
||||
return 0;
|
||||
} else if (count==8) {
|
||||
// all neighbours have same texture; return code to signal no alphamap required
|
||||
return -1;
|
||||
} else {
|
||||
if (count<=4) {
|
||||
// check if we can consider this a BlendShape4 - ie are any of the diagonals (NE,SE,SW,NW) set?
|
||||
if (!shape[1] && !shape[3] && !shape[5] && !shape[7]) {
|
||||
// ok, build a BlendShape4 and use that
|
||||
BlendShape4 shape4;
|
||||
shape4[0]=shape[0];
|
||||
shape4[1]=shape[2];
|
||||
shape4[2]=shape[4];
|
||||
shape4[3]=shape[6];
|
||||
|
||||
switch (count) {
|
||||
case 1:
|
||||
return LookupBlend(sizeof(Blends1Neighbour)/sizeof(Blend4),Blends1Neighbour,shape4,flags);
|
||||
|
||||
case 2:
|
||||
return LookupBlend(sizeof(Blends2Neighbour)/sizeof(Blend4),Blends2Neighbour,shape4,flags);
|
||||
|
||||
case 3:
|
||||
return LookupBlend(sizeof(Blends3Neighbour)/sizeof(Blend4),Blends3Neighbour,shape4,flags);
|
||||
|
||||
case 4:
|
||||
// N,S,E,W have same texture, NE,SE,SW,NW don't; use a blend 4 corners
|
||||
return 5;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// we've got this far, so now we've got to consider the remaining choices, all containing
|
||||
// diagonal elements
|
||||
switch (count) {
|
||||
case 1:
|
||||
// trivial case - just return a circle blend
|
||||
return 0;
|
||||
|
||||
case 2:
|
||||
return LookupBlend(sizeof(Blends2Neighbour8)/sizeof(Blend8),Blends2Neighbour8,shape,flags);
|
||||
|
||||
case 3:
|
||||
return LookupBlend(sizeof(Blends3Neighbour8)/sizeof(Blend8),Blends3Neighbour8,shape,flags);
|
||||
|
||||
case 4:
|
||||
return LookupBlend(sizeof(Blends4Neighbour8)/sizeof(Blend8),Blends4Neighbour8,shape,flags);
|
||||
|
||||
case 5:
|
||||
return LookupBlend(sizeof(Blends5Neighbour8)/sizeof(Blend8),Blends5Neighbour8,shape,flags);
|
||||
|
||||
case 6:
|
||||
return LookupBlend(sizeof(Blends6Neighbour8)/sizeof(Blend8),Blends6Neighbour8,shape,flags);
|
||||
|
||||
case 7:
|
||||
return LookupBlend(sizeof(Blends7Neighbour8)/sizeof(Blend8),Blends7Neighbour8,shape,flags);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Shouldn't get here if we've correctly considered all possible cases;
|
||||
// keep the compiler happy, and, while we're still debugging possible shapes,
|
||||
// return bad blend to highlight suspect alphamap logic
|
||||
return 13;
|
||||
}
|
||||
|
||||
} // end of namespace
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: AlphaMapCalculator.cpp
|
||||
// Author: Rich Cross
|
||||
// Contact: rich@wildfiregames.com
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "AlphaMapCalculator.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// 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<class T>
|
||||
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<class T>
|
||||
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<class S,class T>
|
||||
int LookupBlend(int tableSize,const S* table,const T& shape,unsigned int& flags)
|
||||
{
|
||||
// iterate through known blend shapes
|
||||
for (int b=0;b<tableSize;b++) {
|
||||
const S& blend=table[b];
|
||||
if (MatchBlendShape(blend.m_Shape,shape,flags)) {
|
||||
return blend.m_AlphaMap;
|
||||
}
|
||||
}
|
||||
|
||||
// eh? shouldn't get here if we've correctly considered all possible cases;
|
||||
// keep the compiler happy, and, while we're still debugging possible shapes,
|
||||
// return bad blend to highlight suspect alphamap logic
|
||||
return 13;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// 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)
|
||||
{
|
||||
// assume we're not going to require flipping or rotating
|
||||
flags=0;
|
||||
|
||||
// count number of neighbours
|
||||
int count=0;
|
||||
for (int i=0;i<8;i++) {
|
||||
if (shape[i]) count++;
|
||||
}
|
||||
|
||||
if (count==0) {
|
||||
// no neighbours, just the centre tile has the given texture; use blend circle
|
||||
return 0;
|
||||
} else if (count==8) {
|
||||
// all neighbours have same texture; return code to signal no alphamap required
|
||||
return -1;
|
||||
} else {
|
||||
if (count<=4) {
|
||||
// check if we can consider this a BlendShape4 - ie are any of the diagonals (NE,SE,SW,NW) set?
|
||||
if (!shape[1] && !shape[3] && !shape[5] && !shape[7]) {
|
||||
// ok, build a BlendShape4 and use that
|
||||
BlendShape4 shape4;
|
||||
shape4[0]=shape[0];
|
||||
shape4[1]=shape[2];
|
||||
shape4[2]=shape[4];
|
||||
shape4[3]=shape[6];
|
||||
|
||||
switch (count) {
|
||||
case 1:
|
||||
return LookupBlend(sizeof(Blends1Neighbour)/sizeof(Blend4),Blends1Neighbour,shape4,flags);
|
||||
|
||||
case 2:
|
||||
return LookupBlend(sizeof(Blends2Neighbour)/sizeof(Blend4),Blends2Neighbour,shape4,flags);
|
||||
|
||||
case 3:
|
||||
return LookupBlend(sizeof(Blends3Neighbour)/sizeof(Blend4),Blends3Neighbour,shape4,flags);
|
||||
|
||||
case 4:
|
||||
// N,S,E,W have same texture, NE,SE,SW,NW don't; use a blend 4 corners
|
||||
return 5;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// we've got this far, so now we've got to consider the remaining choices, all containing
|
||||
// diagonal elements
|
||||
switch (count) {
|
||||
case 1:
|
||||
// trivial case - just return a circle blend
|
||||
return 0;
|
||||
|
||||
case 2:
|
||||
return LookupBlend(sizeof(Blends2Neighbour8)/sizeof(Blend8),Blends2Neighbour8,shape,flags);
|
||||
|
||||
case 3:
|
||||
return LookupBlend(sizeof(Blends3Neighbour8)/sizeof(Blend8),Blends3Neighbour8,shape,flags);
|
||||
|
||||
case 4:
|
||||
return LookupBlend(sizeof(Blends4Neighbour8)/sizeof(Blend8),Blends4Neighbour8,shape,flags);
|
||||
|
||||
case 5:
|
||||
return LookupBlend(sizeof(Blends5Neighbour8)/sizeof(Blend8),Blends5Neighbour8,shape,flags);
|
||||
|
||||
case 6:
|
||||
return LookupBlend(sizeof(Blends6Neighbour8)/sizeof(Blend8),Blends6Neighbour8,shape,flags);
|
||||
|
||||
case 7:
|
||||
return LookupBlend(sizeof(Blends7Neighbour8)/sizeof(Blend8),Blends7Neighbour8,shape,flags);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Shouldn't get here if we've correctly considered all possible cases;
|
||||
// keep the compiler happy, and, while we're still debugging possible shapes,
|
||||
// return bad blend to highlight suspect alphamap logic
|
||||
return 13;
|
||||
}
|
||||
|
||||
} // end of namespace
|
||||
|
@ -1,31 +1,31 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: AlphaMapCalculator.h
|
||||
// Author: Rich Cross
|
||||
// Contact: rich@wildfiregames.com
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _ALPHAMAPCALCULATOR_H
|
||||
#define _ALPHAMAPCALCULATOR_H
|
||||
|
||||
#include <string.h>
|
||||
#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 <string.h>
|
||||
#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
|
||||
|
@ -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
|
||||
|
@ -1,162 +1,162 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: Bound.cpp
|
||||
// Author: Rich Cross
|
||||
// Contact: rich@wildfiregames.com
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
// necessary includes
|
||||
#include <assert.h>
|
||||
#include <float.h>
|
||||
#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[0][i])
|
||||
m_Data[0][i]=b[0][i];
|
||||
if (b[1][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[0][i])
|
||||
m_Data[0][i]=pt[i];
|
||||
else 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[0][0] || 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[0][1] || 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 (t1<tfar)
|
||||
tfar = t1;
|
||||
} else {
|
||||
if (t1>tnear)
|
||||
tnear = t1;
|
||||
if (t2<tfar)
|
||||
tfar = t2;
|
||||
}
|
||||
|
||||
if (tnear>tfar || tfar<0)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (dir[2]==0 && (origin[2]<m_Data[0][2] || 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 (t1<tfar)
|
||||
tfar = t1;
|
||||
} else {
|
||||
if (t1>tnear)
|
||||
tnear = t1;
|
||||
if (t2<tfar)
|
||||
tfar = t2;
|
||||
}
|
||||
|
||||
if (tnear>tfar || 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<b) {
|
||||
result[0][i]+=a;
|
||||
result[1][i]+=b;
|
||||
} else {
|
||||
result[0][i]+=b;
|
||||
result[1][i]+=a;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: Bound.cpp
|
||||
// Author: Rich Cross
|
||||
// Contact: rich@wildfiregames.com
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
// necessary includes
|
||||
#include <assert.h>
|
||||
#include <float.h>
|
||||
#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[0][i])
|
||||
m_Data[0][i]=b[0][i];
|
||||
if (b[1][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[0][i])
|
||||
m_Data[0][i]=pt[i];
|
||||
else 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[0][0] || 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[0][1] || 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 (t1<tfar)
|
||||
tfar = t1;
|
||||
} else {
|
||||
if (t1>tnear)
|
||||
tnear = t1;
|
||||
if (t2<tfar)
|
||||
tfar = t2;
|
||||
}
|
||||
|
||||
if (tnear>tfar || tfar<0)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (dir[2]==0 && (origin[2]<m_Data[0][2] || 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 (t1<tfar)
|
||||
tfar = t1;
|
||||
} else {
|
||||
if (t1>tnear)
|
||||
tnear = t1;
|
||||
if (t2<tfar)
|
||||
tfar = t2;
|
||||
}
|
||||
|
||||
if (tnear>tfar || 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<b) {
|
||||
result[0][i]+=a;
|
||||
result[1][i]+=b;
|
||||
} else {
|
||||
result[0][i]+=b;
|
||||
result[1][i]+=a;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,50 +1,50 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: Bound.h
|
||||
// Author: Rich Cross
|
||||
// Contact: rich@wildfiregames.com
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _BOUND_H
|
||||
#define _BOUND_H
|
||||
|
||||
// necessary includes
|
||||
#include "Vector3D.h"
|
||||
#include "Matrix3D.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// CBound: basic axis aligned bounding box class
|
||||
class CBound
|
||||
{
|
||||
public:
|
||||
CBound() {}
|
||||
CBound(const CVector3D& min,const CVector3D& max) {
|
||||
m_Data[0]=min; m_Data[1]=max;
|
||||
}
|
||||
|
||||
void Transform(const CMatrix3D& m,CBound& result) const;
|
||||
|
||||
CVector3D& operator[](int index) { return m_Data[index]; }
|
||||
const CVector3D& operator[](int index) const { return m_Data[index]; }
|
||||
|
||||
void SetEmpty();
|
||||
|
||||
CBound& operator+=(const CBound& b);
|
||||
CBound& operator+=(const CVector3D& pt);
|
||||
|
||||
bool RayIntersect(const CVector3D& origin,const CVector3D& dir,float& tmin,float& tmax) const;
|
||||
|
||||
float GetVolume() const {
|
||||
CVector3D v=m_Data[1]-m_Data[0];
|
||||
return v.X*v.Y*v.Z;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
CVector3D m_Data[2];
|
||||
};
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#endif
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: Bound.h
|
||||
// Author: Rich Cross
|
||||
// Contact: rich@wildfiregames.com
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _BOUND_H
|
||||
#define _BOUND_H
|
||||
|
||||
// necessary includes
|
||||
#include "Vector3D.h"
|
||||
#include "Matrix3D.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// CBound: basic axis aligned bounding box class
|
||||
class CBound
|
||||
{
|
||||
public:
|
||||
CBound() {}
|
||||
CBound(const CVector3D& min,const CVector3D& max) {
|
||||
m_Data[0]=min; m_Data[1]=max;
|
||||
}
|
||||
|
||||
void Transform(const CMatrix3D& m,CBound& result) const;
|
||||
|
||||
CVector3D& operator[](int index) { return m_Data[index]; }
|
||||
const CVector3D& operator[](int index) const { return m_Data[index]; }
|
||||
|
||||
void SetEmpty();
|
||||
|
||||
CBound& operator+=(const CBound& b);
|
||||
CBound& operator+=(const CVector3D& pt);
|
||||
|
||||
bool RayIntersect(const CVector3D& origin,const CVector3D& dir,float& tmin,float& tmax) const;
|
||||
|
||||
float GetVolume() const {
|
||||
CVector3D v=m_Data[1]-m_Data[0];
|
||||
return v.X*v.Y*v.Z;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
CVector3D m_Data[2];
|
||||
};
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -1,108 +1,108 @@
|
||||
//***********************************************************
|
||||
//
|
||||
// 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;
|
||||
}
|
||||
//***********************************************************
|
||||
//
|
||||
// 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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -1,76 +1,76 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: FilePacker.cpp
|
||||
// Author: Rich Cross
|
||||
// Contact: rich@wildfiregames.com
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "FilePacker.h"
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// 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 <stdio.h>
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// 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);
|
||||
}
|
||||
|
||||
|
@ -1,43 +1,43 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: FilePacker.h
|
||||
// Author: Rich Cross
|
||||
// Contact: rich@wildfiregames.com
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _FILEPACKER_H
|
||||
#define _FILEPACKER_H
|
||||
|
||||
#include <vector>
|
||||
#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<u8> m_Data;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: FilePacker.h
|
||||
// Author: Rich Cross
|
||||
// Contact: rich@wildfiregames.com
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _FILEPACKER_H
|
||||
#define _FILEPACKER_H
|
||||
|
||||
#include <vector>
|
||||
#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<u8> m_Data;
|
||||
};
|
||||
|
||||
#endif
|
@ -1,101 +1,101 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: FileUnpacker.cpp
|
||||
// Author: Rich Cross
|
||||
// Contact: rich@wildfiregames.com
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "FileUnpacker.h"
|
||||
#include <stdio.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// 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<char> 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 <stdio.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// 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<char> tmp;
|
||||
tmp.resize(length+1);
|
||||
UnpackRaw(&tmp[0],length);
|
||||
tmp[length]='\0';
|
||||
|
||||
// assign to output
|
||||
result=&tmp[0];
|
||||
}
|
||||
|
||||
|
@ -1,56 +1,56 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: FileUnpacker.h
|
||||
// Author: Rich Cross
|
||||
// Contact: rich@wildfiregames.com
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _FILEUNPACKER_H
|
||||
#define _FILEUNPACKER_H
|
||||
|
||||
#include <vector>
|
||||
#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<u8> 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 <vector>
|
||||
#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<u8> m_Data;
|
||||
// current unpack position in stream
|
||||
u32 m_UnpackPos;
|
||||
// version of the file currently being read
|
||||
u32 m_Version;
|
||||
};
|
||||
|
||||
#endif
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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 <set>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
// 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()<FILE_READ_VERSION) {
|
||||
throw CFileUnpacker::CFileVersionError();
|
||||
}
|
||||
|
||||
// unpack the data
|
||||
UnpackMap(unpacker);
|
||||
|
||||
// finally, apply data to the world
|
||||
ApplyData(unpacker);
|
||||
}
|
||||
|
||||
// UnpackMap: unpack the given data from the raw data stream into local variables
|
||||
void CMapReader::UnpackMap(CFileUnpacker& unpacker)
|
||||
{
|
||||
// now unpack everything into local data
|
||||
UnpackTerrain(unpacker);
|
||||
UnpackObjects(unpacker);
|
||||
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;i<numObjTypes;i++) {
|
||||
CStr objname;
|
||||
unpacker.UnpackString(objname);
|
||||
|
||||
CObjectEntry* object=g_ObjMan.FindObject((const char*) objname);
|
||||
m_ObjectTypes[i]=object;
|
||||
}
|
||||
|
||||
// unpack object data
|
||||
u32 numObjects;
|
||||
unpacker.UnpackRaw(&numObjects,sizeof(numObjects));
|
||||
m_Objects.resize(numObjects);
|
||||
unpacker.UnpackRaw(&m_Objects[0],sizeof(SObjectDesc)*numObjects);
|
||||
}
|
||||
|
||||
// UnpackTerrain: unpack the terrain from the end of the input data stream
|
||||
// - data: map size, heightmap, list of textures used by map, texture tile assignments
|
||||
void CMapReader::UnpackTerrain(CFileUnpacker& unpacker)
|
||||
{
|
||||
// unpack map size
|
||||
unpacker.UnpackRaw(&m_MapSize,sizeof(m_MapSize));
|
||||
|
||||
// unpack heightmap
|
||||
u32 verticesPerSide=m_MapSize*PATCH_SIZE+1;
|
||||
m_Heightmap.resize(SQR(verticesPerSide));
|
||||
unpacker.UnpackRaw(&m_Heightmap[0],SQR(verticesPerSide)*sizeof(u16));
|
||||
|
||||
// unpack texture names; find handle for each texture
|
||||
u32 numTextures;
|
||||
unpacker.UnpackRaw(&numTextures,sizeof(numTextures));
|
||||
|
||||
m_TerrainTextures.reserve(numTextures);
|
||||
for (uint i=0;i<numTextures;i++) {
|
||||
CStr texturename;
|
||||
unpacker.UnpackString(texturename);
|
||||
|
||||
Handle handle;
|
||||
CTextureEntry* texentry=g_TexMan.FindTexture(texturename);
|
||||
if (!texentry) {
|
||||
// ack; mismatch between texture datasets?
|
||||
handle=0;
|
||||
} else {
|
||||
handle=texentry->m_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;j<m_MapSize;j++) {
|
||||
for (u32 i=0;i<m_MapSize;i++) {
|
||||
for (u32 m=0;m<PATCH_SIZE;m++) {
|
||||
for (u32 k=0;k<PATCH_SIZE;k++) {
|
||||
CMiniPatch& mp=g_Terrain.GetPatch(i,j)->m_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;i<m_Objects.size();i++) {
|
||||
CObjectEntry* objentry=m_ObjectTypes[m_Objects[i].m_ObjectIndex];
|
||||
if (objentry && objentry->m_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 <set>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
// 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()<FILE_READ_VERSION) {
|
||||
throw CFileUnpacker::CFileVersionError();
|
||||
}
|
||||
|
||||
// unpack the data
|
||||
UnpackMap(unpacker);
|
||||
|
||||
// finally, apply data to the world
|
||||
ApplyData(unpacker);
|
||||
}
|
||||
|
||||
// UnpackMap: unpack the given data from the raw data stream into local variables
|
||||
void CMapReader::UnpackMap(CFileUnpacker& unpacker)
|
||||
{
|
||||
// now unpack everything into local data
|
||||
UnpackTerrain(unpacker);
|
||||
UnpackObjects(unpacker);
|
||||
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;i<numObjTypes;i++) {
|
||||
CStr objname;
|
||||
unpacker.UnpackString(objname);
|
||||
|
||||
CObjectEntry* object=g_ObjMan.FindObject((const char*) objname);
|
||||
m_ObjectTypes[i]=object;
|
||||
}
|
||||
|
||||
// unpack object data
|
||||
u32 numObjects;
|
||||
unpacker.UnpackRaw(&numObjects,sizeof(numObjects));
|
||||
m_Objects.resize(numObjects);
|
||||
unpacker.UnpackRaw(&m_Objects[0],sizeof(SObjectDesc)*numObjects);
|
||||
}
|
||||
|
||||
// UnpackTerrain: unpack the terrain from the end of the input data stream
|
||||
// - data: map size, heightmap, list of textures used by map, texture tile assignments
|
||||
void CMapReader::UnpackTerrain(CFileUnpacker& unpacker)
|
||||
{
|
||||
// unpack map size
|
||||
unpacker.UnpackRaw(&m_MapSize,sizeof(m_MapSize));
|
||||
|
||||
// unpack heightmap
|
||||
u32 verticesPerSide=m_MapSize*PATCH_SIZE+1;
|
||||
m_Heightmap.resize(SQR(verticesPerSide));
|
||||
unpacker.UnpackRaw(&m_Heightmap[0],SQR(verticesPerSide)*sizeof(u16));
|
||||
|
||||
// unpack texture names; find handle for each texture
|
||||
u32 numTextures;
|
||||
unpacker.UnpackRaw(&numTextures,sizeof(numTextures));
|
||||
|
||||
m_TerrainTextures.reserve(numTextures);
|
||||
for (uint i=0;i<numTextures;i++) {
|
||||
CStr texturename;
|
||||
unpacker.UnpackString(texturename);
|
||||
|
||||
Handle handle;
|
||||
CTextureEntry* texentry=g_TexMan.FindTexture(texturename);
|
||||
if (!texentry) {
|
||||
// ack; mismatch between texture datasets?
|
||||
handle=0;
|
||||
} else {
|
||||
handle=texentry->m_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;j<m_MapSize;j++) {
|
||||
for (u32 i=0;i<m_MapSize;i++) {
|
||||
for (u32 m=0;m<PATCH_SIZE;m++) {
|
||||
for (u32 k=0;k<PATCH_SIZE;k++) {
|
||||
CMiniPatch& mp=g_Terrain.GetPatch(i,j)->m_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;i<m_Objects.size();i++) {
|
||||
CObjectEntry* objentry=m_ObjectTypes[m_Objects[i].m_ObjectIndex];
|
||||
if (objentry && objentry->m_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;
|
||||
}
|
||||
}
|
||||
|
@ -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<u16> m_Heightmap;
|
||||
// list of terrain textures used by map
|
||||
std::vector<Handle> m_TerrainTextures;
|
||||
// tile descriptions for each tile
|
||||
std::vector<STileDesc> m_Tiles;
|
||||
// list of object types used by map
|
||||
std::vector<CObjectEntry*> m_ObjectTypes;
|
||||
// descriptions for each objects
|
||||
std::vector<SObjectDesc> 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<u16> m_Heightmap;
|
||||
// list of terrain textures used by map
|
||||
std::vector<Handle> m_TerrainTextures;
|
||||
// tile descriptions for each tile
|
||||
std::vector<STileDesc> m_Tiles;
|
||||
// list of object types used by map
|
||||
std::vector<CObjectEntry*> m_ObjectTypes;
|
||||
// descriptions for each objects
|
||||
std::vector<SObjectDesc> m_Objects;
|
||||
// lightenv stored in file
|
||||
CLightEnv m_LightEnv;
|
||||
};
|
||||
|
||||
#endif
|
@ -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 <set>
|
||||
#include <stdio.h>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// 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<Handle>& handles)
|
||||
{
|
||||
for (uint i=0;i<handles.size();i++) {
|
||||
if (handles[i]==handle) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return 0xffff;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// GetObjectIndex: return the index of the given object in the given list; or 0xffff if
|
||||
// object isn't in list
|
||||
static u16 GetObjectIndex(const CObjectEntry* object,const std::vector<CObjectEntry*>& objects)
|
||||
{
|
||||
for (uint i=0;i<objects.size();i++) {
|
||||
if (objects[i]==object) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return 0xffff;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// EnumTerrainTextures: build lists of textures used by map, and tile descriptions for
|
||||
// each tile on the terrain
|
||||
void CMapWriter::EnumTerrainTextures(std::vector<CStr>& textures,
|
||||
std::vector<STileDesc>& tiles)
|
||||
{
|
||||
// the list of all handles in use
|
||||
std::vector<Handle> 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;j<mapsize;j++) {
|
||||
for (u32 i=0;i<mapsize;i++) {
|
||||
for (u32 m=0;m<PATCH_SIZE;m++) {
|
||||
for (u32 k=0;k<PATCH_SIZE;k++) {
|
||||
CMiniPatch& mp=g_Terrain.GetPatch(i,j)->m_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;i<handles.size();i++) {
|
||||
CStr texturename;
|
||||
CTextureEntry* texentry=g_TexMan.FindTexture(handles[i]);
|
||||
if (!texentry) {
|
||||
// uh-oh, this shouldn't happen; set texturename to empty string
|
||||
texturename="";
|
||||
} else {
|
||||
texturename=texentry->m_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<CStr>& objectTypes,std::vector<SObjectDesc>& objects)
|
||||
{
|
||||
// the list of all object entries in use
|
||||
std::vector<CObjectEntry*> objectsInUse;
|
||||
|
||||
// resize object array to required size
|
||||
const std::vector<CUnit*>& units=g_UnitMan.GetUnits();
|
||||
objects.resize(units.size());
|
||||
SObjectDesc* objptr=&objects[0];
|
||||
|
||||
// now iterate through all the units
|
||||
for (u32 j=0;j<units.size();j++) {
|
||||
CUnit* unit=units[j];
|
||||
|
||||
u16 index=u16(GetObjectIndex(unit->m_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;i<objectsInUse.size();i++) {
|
||||
objectTypes.push_back(objectsInUse[i]->m_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<CStr> objectTypes;
|
||||
// descriptions of each object
|
||||
std::vector<SObjectDesc> 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<numObjTypes;i++) {
|
||||
packer.PackString(objectTypes[i]);
|
||||
}
|
||||
|
||||
// pack object data
|
||||
u32 numObjects=objects.size();
|
||||
packer.PackRaw(&numObjects,sizeof(numObjects));
|
||||
packer.PackRaw(&objects[0],sizeof(SObjectDesc)*numObjects);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// PackTerrain: pack the terrain onto the end of the output data stream
|
||||
// - data: map size, heightmap, list of textures used by map, texture tile assignments
|
||||
void CMapWriter::PackTerrain(CFilePacker& packer)
|
||||
{
|
||||
// pack map size
|
||||
u32 mapsize=g_Terrain.GetPatchesPerSide();
|
||||
packer.PackRaw(&mapsize,sizeof(mapsize));
|
||||
|
||||
// pack heightmap
|
||||
packer.PackRaw(g_Terrain.GetHeightMap(),sizeof(u16)*SQR(g_Terrain.GetVerticesPerSide()));
|
||||
|
||||
// the list of textures used by map
|
||||
std::vector<CStr> terrainTextures;
|
||||
// descriptions of each tile
|
||||
std::vector<STileDesc> 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<numTextures;i++) {
|
||||
packer.PackString(terrainTextures[i]);
|
||||
}
|
||||
|
||||
// pack tile data
|
||||
packer.PackRaw(&tiles[0],sizeof(STileDesc)*tiles.size());
|
||||
}
|
||||
|
||||
// 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 <set>
|
||||
#include <stdio.h>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// 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<Handle>& handles)
|
||||
{
|
||||
for (uint i=0;i<handles.size();i++) {
|
||||
if (handles[i]==handle) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return 0xffff;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// GetObjectIndex: return the index of the given object in the given list; or 0xffff if
|
||||
// object isn't in list
|
||||
static u16 GetObjectIndex(const CObjectEntry* object,const std::vector<CObjectEntry*>& objects)
|
||||
{
|
||||
for (uint i=0;i<objects.size();i++) {
|
||||
if (objects[i]==object) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return 0xffff;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// EnumTerrainTextures: build lists of textures used by map, and tile descriptions for
|
||||
// each tile on the terrain
|
||||
void CMapWriter::EnumTerrainTextures(std::vector<CStr>& textures,
|
||||
std::vector<STileDesc>& tiles)
|
||||
{
|
||||
// the list of all handles in use
|
||||
std::vector<Handle> 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;j<mapsize;j++) {
|
||||
for (u32 i=0;i<mapsize;i++) {
|
||||
for (u32 m=0;m<PATCH_SIZE;m++) {
|
||||
for (u32 k=0;k<PATCH_SIZE;k++) {
|
||||
CMiniPatch& mp=g_Terrain.GetPatch(i,j)->m_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;i<handles.size();i++) {
|
||||
CStr texturename;
|
||||
CTextureEntry* texentry=g_TexMan.FindTexture(handles[i]);
|
||||
if (!texentry) {
|
||||
// uh-oh, this shouldn't happen; set texturename to empty string
|
||||
texturename="";
|
||||
} else {
|
||||
texturename=texentry->m_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<CStr>& objectTypes,std::vector<SObjectDesc>& objects)
|
||||
{
|
||||
// the list of all object entries in use
|
||||
std::vector<CObjectEntry*> objectsInUse;
|
||||
|
||||
// resize object array to required size
|
||||
const std::vector<CUnit*>& units=g_UnitMan.GetUnits();
|
||||
objects.resize(units.size());
|
||||
SObjectDesc* objptr=&objects[0];
|
||||
|
||||
// now iterate through all the units
|
||||
for (u32 j=0;j<units.size();j++) {
|
||||
CUnit* unit=units[j];
|
||||
|
||||
u16 index=u16(GetObjectIndex(unit->m_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;i<objectsInUse.size();i++) {
|
||||
objectTypes.push_back(objectsInUse[i]->m_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<CStr> objectTypes;
|
||||
// descriptions of each object
|
||||
std::vector<SObjectDesc> 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<numObjTypes;i++) {
|
||||
packer.PackString(objectTypes[i]);
|
||||
}
|
||||
|
||||
// pack object data
|
||||
u32 numObjects=objects.size();
|
||||
packer.PackRaw(&numObjects,sizeof(numObjects));
|
||||
packer.PackRaw(&objects[0],sizeof(SObjectDesc)*numObjects);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// PackTerrain: pack the terrain onto the end of the output data stream
|
||||
// - data: map size, heightmap, list of textures used by map, texture tile assignments
|
||||
void CMapWriter::PackTerrain(CFilePacker& packer)
|
||||
{
|
||||
// pack map size
|
||||
u32 mapsize=g_Terrain.GetPatchesPerSide();
|
||||
packer.PackRaw(&mapsize,sizeof(mapsize));
|
||||
|
||||
// pack heightmap
|
||||
packer.PackRaw(g_Terrain.GetHeightMap(),sizeof(u16)*SQR(g_Terrain.GetVerticesPerSide()));
|
||||
|
||||
// the list of textures used by map
|
||||
std::vector<CStr> terrainTextures;
|
||||
// descriptions of each tile
|
||||
std::vector<STileDesc> 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<numTextures;i++) {
|
||||
packer.PackString(terrainTextures[i]);
|
||||
}
|
||||
|
||||
// pack tile data
|
||||
packer.PackRaw(&tiles[0],sizeof(STileDesc)*tiles.size());
|
||||
}
|
||||
|
||||
|
@ -1,36 +1,36 @@
|
||||
#ifndef _MAPWRITER_H
|
||||
#define _MAPWRITER_H
|
||||
|
||||
#include <vector>
|
||||
#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<CStr>& textures,std::vector<STileDesc>& tileIndices);
|
||||
|
||||
// EnumObjects: build lists of object types used by map, and object descriptions for
|
||||
// each object in the world
|
||||
void EnumObjects(std::vector<CStr>& objectTypes,std::vector<SObjectDesc>& objects);
|
||||
};
|
||||
|
||||
#ifndef _MAPWRITER_H
|
||||
#define _MAPWRITER_H
|
||||
|
||||
#include <vector>
|
||||
#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<CStr>& textures,std::vector<STileDesc>& tileIndices);
|
||||
|
||||
// EnumObjects: build lists of object types used by map, and object descriptions for
|
||||
// each object in the world
|
||||
void EnumObjects(std::vector<CStr>& objectTypes,std::vector<SObjectDesc>& objects);
|
||||
};
|
||||
|
||||
#endif
|
@ -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
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,120 +1,120 @@
|
||||
#ifndef __MATRIX3D_H
|
||||
#define __MATRIX3D_H
|
||||
|
||||
#include <math.h>
|
||||
#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 <math.h>
|
||||
#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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;i<numBones;i++) {
|
||||
CMatrix3D& m=m_BoneMatrices[i];
|
||||
m.SetIdentity();
|
||||
m.Rotate(defpose[i].m_Rotation);
|
||||
m.Translate(defpose[i].m_Translation);
|
||||
m.GetInverse(m_InvBoneMatrices[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// SkinPoint: skin the given point using the given blend and bonestate data
|
||||
static CVector3D SkinPoint(const CVector3D& pos,const SVertexBlend& blend,
|
||||
const CBoneState* bonestates)
|
||||
{
|
||||
CVector3D result(0,0,0);
|
||||
for (int i=0;i<SVertexBlend::SIZE && blend.m_Bone[i]!=0xff;i++) {
|
||||
CMatrix3D m;
|
||||
m.SetIdentity();
|
||||
m.Rotate(bonestates[blend.m_Bone[i]].m_Rotation);
|
||||
m.Translate(bonestates[blend.m_Bone[i]].m_Translation);
|
||||
|
||||
CVector3D tmp=m.Transform(pos);
|
||||
result+=tmp*blend.m_Weight[i];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// CalcBound: calculate the world space bounds of this model
|
||||
//
|
||||
// TODO,RC 11/03/04: need to calculate (and store somewhere) the object space
|
||||
// bounds, and then just retransform the bounds as necessary, rather than
|
||||
// recalculating them from vertex data every time the transform changes
|
||||
void CModel::CalcBounds()
|
||||
{
|
||||
m_Bounds.SetEmpty();
|
||||
|
||||
int numverts=m_pModelDef->GetNumVertices();
|
||||
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;i<numverts;i++) {
|
||||
CVector3D tmp=SkinPoint(verts[i].m_Coords,verts[i].m_Blend,m_pModelDef->GetBones());
|
||||
m_Bounds+=m_Transform.Transform(tmp);
|
||||
}
|
||||
} else {
|
||||
for (int i=0;i<numverts;i++) {
|
||||
m_Bounds+=m_Transform.Transform(verts[i].m_Coords);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Update: update this model by the given time, in seconds
|
||||
void CModel::Update(float time)
|
||||
{
|
||||
// convert to ms
|
||||
time*=1000;
|
||||
|
||||
if (m_Anim && m_BoneMatrices) {
|
||||
m_AnimTime+=time;
|
||||
|
||||
float duration=m_Anim->GetDuration();
|
||||
if (m_AnimTime>duration) {
|
||||
m_AnimTime=(float) fmod(m_AnimTime,duration);
|
||||
}
|
||||
|
||||
m_Anim->BuildBoneMatrices(m_AnimTime,m_BoneMatrices);
|
||||
for (int i=0;i<m_pModelDef->GetNumBones();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;i<numBones;i++) {
|
||||
CMatrix3D& m=m_BoneMatrices[i];
|
||||
m.SetIdentity();
|
||||
m.Rotate(defpose[i].m_Rotation);
|
||||
m.Translate(defpose[i].m_Translation);
|
||||
m.GetInverse(m_InvBoneMatrices[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// SkinPoint: skin the given point using the given blend and bonestate data
|
||||
static CVector3D SkinPoint(const CVector3D& pos,const SVertexBlend& blend,
|
||||
const CBoneState* bonestates)
|
||||
{
|
||||
CVector3D result(0,0,0);
|
||||
for (int i=0;i<SVertexBlend::SIZE && blend.m_Bone[i]!=0xff;i++) {
|
||||
CMatrix3D m;
|
||||
m.SetIdentity();
|
||||
m.Rotate(bonestates[blend.m_Bone[i]].m_Rotation);
|
||||
m.Translate(bonestates[blend.m_Bone[i]].m_Translation);
|
||||
|
||||
CVector3D tmp=m.Transform(pos);
|
||||
result+=tmp*blend.m_Weight[i];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// CalcBound: calculate the world space bounds of this model
|
||||
//
|
||||
// TODO,RC 11/03/04: need to calculate (and store somewhere) the object space
|
||||
// bounds, and then just retransform the bounds as necessary, rather than
|
||||
// recalculating them from vertex data every time the transform changes
|
||||
void CModel::CalcBounds()
|
||||
{
|
||||
m_Bounds.SetEmpty();
|
||||
|
||||
int numverts=m_pModelDef->GetNumVertices();
|
||||
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;i<numverts;i++) {
|
||||
CVector3D tmp=SkinPoint(verts[i].m_Coords,verts[i].m_Blend,m_pModelDef->GetBones());
|
||||
m_Bounds+=m_Transform.Transform(tmp);
|
||||
}
|
||||
} else {
|
||||
for (int i=0;i<numverts;i++) {
|
||||
m_Bounds+=m_Transform.Transform(verts[i].m_Coords);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Update: update this model by the given time, in seconds
|
||||
void CModel::Update(float time)
|
||||
{
|
||||
// convert to ms
|
||||
time*=1000;
|
||||
|
||||
if (m_Anim && m_BoneMatrices) {
|
||||
m_AnimTime+=time;
|
||||
|
||||
float duration=m_Anim->GetDuration();
|
||||
if (m_AnimTime>duration) {
|
||||
m_AnimTime=(float) fmod(m_AnimTime,duration);
|
||||
}
|
||||
|
||||
m_Anim->BuildBoneMatrices(m_AnimTime,m_BoneMatrices);
|
||||
for (int i=0;i<m_pModelDef->GetNumBones();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;
|
||||
}
|
@ -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
|
||||
|
@ -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()<FILE_READ_VERSION) {
|
||||
throw CFileUnpacker::CFileVersionError();
|
||||
}
|
||||
|
||||
CModelDef* mdef=new CModelDef;
|
||||
try {
|
||||
// now unpack everything
|
||||
unpacker.UnpackRaw(&mdef->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()<FILE_READ_VERSION) {
|
||||
throw CFileUnpacker::CFileVersionError();
|
||||
}
|
||||
|
||||
CModelDef* mdef=new CModelDef;
|
||||
try {
|
||||
// now unpack everything
|
||||
unpacker.UnpackRaw(&mdef->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");
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -1,257 +1,257 @@
|
||||
#include <assert.h>
|
||||
#include <algorithm>
|
||||
#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; j<mdef->GetNumFaces(); 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 (x<min) return min;
|
||||
else if (x>max) 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 && i<SVertexBlend::SIZE;i++) {
|
||||
const CMatrix3D& m=matrices[vertex.m_Blend.m_Bone[i]];
|
||||
m.Transform(vertex.m_Coords,tmp);
|
||||
result+=tmp*vertex.m_Blend.m_Weight[i];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static CVector3D SkinNormal(const SModelVertex& vertex,const CMatrix3D* invmatrices)
|
||||
{
|
||||
CVector3D result(0,0,0),tmp;
|
||||
|
||||
for (u32 i=0;vertex.m_Blend.m_Bone[i]!=0xff && i<SVertexBlend::SIZE;i++) {
|
||||
const CMatrix3D& m=invmatrices[vertex.m_Blend.m_Bone[i]];
|
||||
m.RotateTransposed(vertex.m_Norm,tmp);
|
||||
result+=tmp*vertex.m_Blend.m_Weight[i];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void CModelRData::BuildVertices()
|
||||
{
|
||||
CModelDef* mdef=m_Model->GetModelDef();
|
||||
|
||||
// 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; j<numVertices; j++) {
|
||||
m_Vertices[j].m_Position=SkinPoint(vertices[j],m_Model->GetBoneMatrices());
|
||||
m_Normals[j]=SkinNormal(vertices[j],m_Model->GetInvBoneMatrices());
|
||||
}
|
||||
} else {
|
||||
// just copy regular positions
|
||||
for (uint j=0; j<numVertices; j++) {
|
||||
m_Vertices[j].m_Position=vertices[j].m_Coords;
|
||||
m_Normals[j]=vertices[j].m_Norm;
|
||||
}
|
||||
}
|
||||
|
||||
// now fill in UV and vertex colour data
|
||||
for (uint j=0; j<numVertices; j++) {
|
||||
m_Vertices[j].m_UVs[0]=vertices[j].m_U;
|
||||
m_Vertices[j].m_UVs[1]=1-vertices[j].m_V;
|
||||
|
||||
RGBColor c;
|
||||
g_Renderer.m_SHCoeffsUnits.Evaluate(m_Normals[j],c);
|
||||
|
||||
m_Vertices[j].m_Color=ConvertColor(c);
|
||||
}
|
||||
|
||||
if (g_Renderer.m_Caps.m_VBO) {
|
||||
if (!m_VB) {
|
||||
glGenBuffersARB(1,(GLuint*) &m_VB);
|
||||
glBindBufferARB(GL_ARRAY_BUFFER_ARB,m_VB);
|
||||
glBufferDataARB(GL_ARRAY_BUFFER_ARB,mdef->GetNumVertices()*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<int,float> IntFloatPair;
|
||||
static std::vector<IntFloatPair> 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;i<numFaces;i++)
|
||||
{
|
||||
osvtx=vtxs[facePtr->m_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<mindist) mindist=distsqrd;
|
||||
|
||||
IndexSorter.push_back(IntFloatPair(i,distsqrd));
|
||||
facePtr++;
|
||||
}
|
||||
|
||||
std::sort(IndexSorter.begin(),IndexSorter.end(),SortFacesByDist());
|
||||
|
||||
// now build index list
|
||||
u32 indices=0;
|
||||
for (i=0;i<numFaces;i++) {
|
||||
SModelFace& face=faces[IndexSorter[i].first];
|
||||
m_Indices[indices++]=face.m_Verts[0];
|
||||
m_Indices[indices++]=face.m_Verts[1];
|
||||
m_Indices[indices++]=face.m_Verts[2];
|
||||
}
|
||||
|
||||
// clear list for next call
|
||||
IndexSorter.clear();
|
||||
|
||||
return mindist;
|
||||
}
|
||||
#include <assert.h>
|
||||
#include <algorithm>
|
||||
#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; j<mdef->GetNumFaces(); 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 (x<min) return min;
|
||||
else if (x>max) 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 && i<SVertexBlend::SIZE;i++) {
|
||||
const CMatrix3D& m=matrices[vertex.m_Blend.m_Bone[i]];
|
||||
m.Transform(vertex.m_Coords,tmp);
|
||||
result+=tmp*vertex.m_Blend.m_Weight[i];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static CVector3D SkinNormal(const SModelVertex& vertex,const CMatrix3D* invmatrices)
|
||||
{
|
||||
CVector3D result(0,0,0),tmp;
|
||||
|
||||
for (u32 i=0;vertex.m_Blend.m_Bone[i]!=0xff && i<SVertexBlend::SIZE;i++) {
|
||||
const CMatrix3D& m=invmatrices[vertex.m_Blend.m_Bone[i]];
|
||||
m.RotateTransposed(vertex.m_Norm,tmp);
|
||||
result+=tmp*vertex.m_Blend.m_Weight[i];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void CModelRData::BuildVertices()
|
||||
{
|
||||
CModelDef* mdef=m_Model->GetModelDef();
|
||||
|
||||
// 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; j<numVertices; j++) {
|
||||
m_Vertices[j].m_Position=SkinPoint(vertices[j],m_Model->GetBoneMatrices());
|
||||
m_Normals[j]=SkinNormal(vertices[j],m_Model->GetInvBoneMatrices());
|
||||
}
|
||||
} else {
|
||||
// just copy regular positions
|
||||
for (uint j=0; j<numVertices; j++) {
|
||||
m_Vertices[j].m_Position=vertices[j].m_Coords;
|
||||
m_Normals[j]=vertices[j].m_Norm;
|
||||
}
|
||||
}
|
||||
|
||||
// now fill in UV and vertex colour data
|
||||
for (uint j=0; j<numVertices; j++) {
|
||||
m_Vertices[j].m_UVs[0]=vertices[j].m_U;
|
||||
m_Vertices[j].m_UVs[1]=1-vertices[j].m_V;
|
||||
|
||||
RGBColor c;
|
||||
g_Renderer.m_SHCoeffsUnits.Evaluate(m_Normals[j],c);
|
||||
|
||||
m_Vertices[j].m_Color=ConvertColor(c);
|
||||
}
|
||||
|
||||
if (g_Renderer.m_Caps.m_VBO) {
|
||||
if (!m_VB) {
|
||||
glGenBuffersARB(1,(GLuint*) &m_VB);
|
||||
glBindBufferARB(GL_ARRAY_BUFFER_ARB,m_VB);
|
||||
glBufferDataARB(GL_ARRAY_BUFFER_ARB,mdef->GetNumVertices()*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<int,float> IntFloatPair;
|
||||
static std::vector<IntFloatPair> 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;i<numFaces;i++)
|
||||
{
|
||||
osvtx=vtxs[facePtr->m_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<mindist) mindist=distsqrd;
|
||||
|
||||
IndexSorter.push_back(IntFloatPair(i,distsqrd));
|
||||
facePtr++;
|
||||
}
|
||||
|
||||
std::sort(IndexSorter.begin(),IndexSorter.end(),SortFacesByDist());
|
||||
|
||||
// now build index list
|
||||
u32 indices=0;
|
||||
for (i=0;i<numFaces;i++) {
|
||||
SModelFace& face=faces[IndexSorter[i].first];
|
||||
m_Indices[indices++]=face.m_Verts[0];
|
||||
m_Indices[indices++]=face.m_Verts[1];
|
||||
m_Indices[indices++]=face.m_Verts[2];
|
||||
}
|
||||
|
||||
// clear list for next call
|
||||
IndexSorter.clear();
|
||||
|
||||
return mindist;
|
||||
}
|
||||
|
@ -1,54 +1,54 @@
|
||||
#ifndef _MODELRDATA_H
|
||||
#define _MODELRDATA_H
|
||||
|
||||
#include <vector>
|
||||
#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 <vector>
|
||||
#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
|
||||
|
@ -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 <xercesc/dom/DOM.hpp>
|
||||
#include <xercesc/parsers/XercesDOMParser.hpp>
|
||||
#include <xercesc/framework/LocalFileInputSource.hpp>
|
||||
#include <xercesc/util/XMLString.hpp>
|
||||
#include <xercesc/util/PlatformUtils.hpp>
|
||||
|
||||
// Gee's custom error handler
|
||||
#include <ps/XercesErrorHandler.h>
|
||||
|
||||
// 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;i<m_Animations.size();i++) {
|
||||
if (m_Animations[i].m_FileName.Length()>0) {
|
||||
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;i<m_Animations.size();i++) {
|
||||
if (m_Animations[i].m_AnimData) {
|
||||
m_Model->SetAnimation(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<CUnit*>& units=g_UnitMan.GetUnits();
|
||||
for (uint i=0;i<units.size();++i) {
|
||||
if (units[i]->m_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; i<numChildren; ++i) {
|
||||
// Get node
|
||||
DOMNode *child = children->item(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; j<animations->getLength(); ++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,"<?xml version=\"1.0\" encoding=\"iso-8859-1\" standalone=\"no\"?>\n\n");
|
||||
fprintf(fp,"<!DOCTYPE Object SYSTEM \"..\\object.dtd\">\n\n");
|
||||
|
||||
// write the object itself
|
||||
fprintf(fp,"<!-- File automatically generated by ScEd -->\n");
|
||||
fprintf(fp,"<Object>\n");
|
||||
fprintf(fp,"\t<Name>%s</Name>\n",(const char*) m_Name);
|
||||
fprintf(fp,"\t<ModelName>%s</ModelName>\n",(const char*) m_ModelName);
|
||||
fprintf(fp,"\t<TextureName>%s</TextureName>\n",(const char*) m_TextureName);
|
||||
if (m_Animations.size()>0) {
|
||||
fprintf(fp,"\t<Animations>\n");
|
||||
for (uint i=0;i<m_Animations.size();i++) {
|
||||
fprintf(fp,"\t\t<Animation name=\"%s\" file=\"%s\"> </Animation>\n",(const char*) m_Animations[i].m_AnimName,(const char*) m_Animations[i].m_FileName);
|
||||
}
|
||||
fprintf(fp,"\t</Animations>\n");
|
||||
}
|
||||
fprintf(fp,"</Object>\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 <xercesc/dom/DOM.hpp>
|
||||
#include <xercesc/parsers/XercesDOMParser.hpp>
|
||||
#include <xercesc/framework/LocalFileInputSource.hpp>
|
||||
#include <xercesc/util/XMLString.hpp>
|
||||
#include <xercesc/util/PlatformUtils.hpp>
|
||||
|
||||
// Gee's custom error handler
|
||||
#include <ps/XercesErrorHandler.h>
|
||||
|
||||
// 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<CUnit*>& units=g_UnitMan.GetUnits();
|
||||
for (uint i=0;i<units.size();++i) {
|
||||
if (units[i]->m_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; i<numChildren; ++i) {
|
||||
// Get node
|
||||
DOMNode *child = children->item(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; j<animations->getLength(); ++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,"<?xml version=\"1.0\" encoding=\"iso-8859-1\" standalone=\"no\"?>\n\n");
|
||||
fprintf(fp,"<!DOCTYPE Object SYSTEM \"..\\object.dtd\">\n\n");
|
||||
|
||||
// write the object itself
|
||||
fprintf(fp,"<!-- File automatically generated by ScEd -->\n");
|
||||
fprintf(fp,"<Object>\n");
|
||||
fprintf(fp,"\t<Name>%s</Name>\n",(const char*) m_Name);
|
||||
fprintf(fp,"\t<ModelName>%s</ModelName>\n",(const char*) m_ModelName);
|
||||
fprintf(fp,"\t<TextureName>%s</TextureName>\n",(const char*) m_TextureName);
|
||||
if (m_Animations.size()>0) {
|
||||
fprintf(fp,"\t<Animations>\n");
|
||||
for (uint i=0;i<m_Animations.size();i++) {
|
||||
fprintf(fp,"\t\t<Animation name=\"%s\" file=\"%s\"> </Animation>\n",(const char*) m_Animations[i].m_AnimName,(const char*) m_Animations[i].m_FileName);
|
||||
}
|
||||
fprintf(fp,"\t</Animations>\n");
|
||||
}
|
||||
fprintf(fp,"</Object>\n");
|
||||
fclose(fp);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -1,47 +1,46 @@
|
||||
#ifndef _OBJECTENTRY_H
|
||||
#define _OBJECTENTRY_H
|
||||
|
||||
class CModel;
|
||||
class CSkeletonAnim;
|
||||
|
||||
#include <vector>
|
||||
#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<Anim> 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 <vector>
|
||||
#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<Anim> 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
|
||||
|
||||
|
@ -1,132 +1,128 @@
|
||||
#include "ObjectManager.h"
|
||||
#include <io.h>
|
||||
#include <algorithm>
|
||||
|
||||
CObjectManager g_ObjMan;
|
||||
|
||||
CObjectManager::CObjectManager() : m_SelectedObject(0)
|
||||
{
|
||||
m_ObjectTypes.reserve(32);
|
||||
}
|
||||
|
||||
|
||||
CObjectEntry* CObjectManager::FindObject(const char* objectname)
|
||||
{
|
||||
for (uint k=0;k<m_ObjectTypes.size();k++) {
|
||||
std::vector<CObjectEntry*>& objects=m_ObjectTypes[k].m_Objects;
|
||||
|
||||
for (uint i=0;i<objects.size();i++) {
|
||||
if (strcmp(objectname,(const char*) objects[i]->m_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)type<m_ObjectTypes.size());
|
||||
// build the model now to load the required model/animations from it
|
||||
if (object->BuildModel()) {
|
||||
m_ObjectTypes[type].m_Objects.push_back(object);
|
||||
}
|
||||
}
|
||||
|
||||
void CObjectManager::DeleteObject(CObjectEntry* entry)
|
||||
{
|
||||
std::vector<CObjectEntry*>& objects=m_ObjectTypes[entry->m_Type].m_Objects;
|
||||
|
||||
typedef std::vector<CObjectEntry*>::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;i<m_ObjectTypes.size();i++) {
|
||||
LoadObjects(i);
|
||||
}
|
||||
}
|
||||
|
||||
void CObjectManager::BuildObjectTypes()
|
||||
{
|
||||
struct _finddata_t file;
|
||||
long handle;
|
||||
|
||||
// Find first matching directory in terrain\textures
|
||||
if ((handle=_findfirst("mods\\official\\art\\actors\\*",&file))!=-1) {
|
||||
|
||||
if ((file.attrib & _A_SUBDIR) && file.name[0]!='.') {
|
||||
AddObjectType(file.name);
|
||||
}
|
||||
|
||||
// Find the rest of the matching files
|
||||
while( _findnext(handle,&file)==0) {
|
||||
if ((file.attrib & _A_SUBDIR) && file.name[0]!='.') {
|
||||
AddObjectType(file.name);
|
||||
}
|
||||
}
|
||||
|
||||
_findclose(handle);
|
||||
}
|
||||
}
|
||||
|
||||
void CObjectManager::LoadObjects(int type)
|
||||
{
|
||||
struct _finddata_t file;
|
||||
long handle;
|
||||
|
||||
// build pathname
|
||||
CStr pathname("mods\\official\\art\\actors\\");
|
||||
pathname+=m_ObjectTypes[type].m_Name;
|
||||
pathname+="\\";
|
||||
|
||||
CStr findname(pathname);
|
||||
findname+="*.xml";
|
||||
|
||||
// Find first matching file in directory for this terrain type
|
||||
if ((handle=_findfirst((const char*) findname,&file))!=-1) {
|
||||
|
||||
CObjectEntry* object=new CObjectEntry(type);
|
||||
CStr filename(pathname);
|
||||
filename+=file.name;
|
||||
if (!object->Load((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 <io.h>
|
||||
#include <algorithm>
|
||||
|
||||
CObjectManager g_ObjMan;
|
||||
|
||||
CObjectManager::CObjectManager() : m_SelectedObject(0)
|
||||
{
|
||||
m_ObjectTypes.reserve(32);
|
||||
}
|
||||
|
||||
|
||||
CObjectEntry* CObjectManager::FindObject(const char* objectname)
|
||||
{
|
||||
for (uint k=0;k<m_ObjectTypes.size();k++) {
|
||||
std::vector<CObjectEntry*>& objects=m_ObjectTypes[k].m_Objects;
|
||||
|
||||
for (uint i=0;i<objects.size();i++) {
|
||||
if (strcmp(objectname,(const char*) objects[i]->m_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)type<m_ObjectTypes.size());
|
||||
if( object->BuildModel() )
|
||||
m_ObjectTypes[type].m_Objects.push_back(object);
|
||||
}
|
||||
|
||||
void CObjectManager::DeleteObject(CObjectEntry* entry)
|
||||
{
|
||||
std::vector<CObjectEntry*>& objects=m_ObjectTypes[entry->m_Type].m_Objects;
|
||||
|
||||
typedef std::vector<CObjectEntry*>::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;i<m_ObjectTypes.size();i++) {
|
||||
LoadObjects(i);
|
||||
}
|
||||
}
|
||||
|
||||
void CObjectManager::BuildObjectTypes()
|
||||
{
|
||||
struct _finddata_t file;
|
||||
long handle;
|
||||
|
||||
// Find first matching directory in terrain\textures
|
||||
if ((handle=_findfirst("mods\\official\\art\\actors\\*",&file))!=-1) {
|
||||
|
||||
if ((file.attrib & _A_SUBDIR) && file.name[0]!='.') {
|
||||
AddObjectType(file.name);
|
||||
}
|
||||
|
||||
// Find the rest of the matching files
|
||||
while( _findnext(handle,&file)==0) {
|
||||
if ((file.attrib & _A_SUBDIR) && file.name[0]!='.') {
|
||||
AddObjectType(file.name);
|
||||
}
|
||||
}
|
||||
|
||||
_findclose(handle);
|
||||
}
|
||||
}
|
||||
|
||||
void CObjectManager::LoadObjects(int type)
|
||||
{
|
||||
struct _finddata_t file;
|
||||
long handle;
|
||||
|
||||
// build pathname
|
||||
CStr pathname("mods\\official\\art\\actors\\");
|
||||
pathname+=m_ObjectTypes[type].m_Name;
|
||||
pathname+="\\";
|
||||
|
||||
CStr findname(pathname);
|
||||
findname+="*.xml";
|
||||
|
||||
// Find first matching file in directory for this terrain type
|
||||
if ((handle=_findfirst((const char*) findname,&file))!=-1) {
|
||||
|
||||
CObjectEntry* object=new CObjectEntry(type);
|
||||
CStr filename(pathname);
|
||||
filename+=file.name;
|
||||
if (!object->Load((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);
|
||||
}
|
||||
}
|
||||
|
@ -1,47 +1,47 @@
|
||||
#ifndef _OBJECTMANAGER_H
|
||||
#define _OBJECTMANAGER_H
|
||||
|
||||
#include <vector>
|
||||
#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<CObjectEntry*> 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<SObjectType> m_ObjectTypes;
|
||||
|
||||
private:
|
||||
void BuildObjectTypes();
|
||||
void LoadObjects(int type);
|
||||
|
||||
CObjectEntry* m_SelectedObject;
|
||||
};
|
||||
|
||||
extern CObjectManager g_ObjMan;
|
||||
|
||||
|
||||
#ifndef _OBJECTMANAGER_H
|
||||
#define _OBJECTMANAGER_H
|
||||
|
||||
#include <vector>
|
||||
#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<CObjectEntry*> 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<SObjectType> m_ObjectTypes;
|
||||
|
||||
private:
|
||||
void BuildObjectTypes();
|
||||
void LoadObjects(int type);
|
||||
|
||||
CObjectEntry* m_SelectedObject;
|
||||
};
|
||||
|
||||
extern CObjectManager g_ObjMan;
|
||||
|
||||
|
||||
#endif
|
@ -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;j<PATCH_SIZE+1;j++) {
|
||||
for (int i=0;i<PATCH_SIZE+1;i++) {
|
||||
CVector3D pos;
|
||||
m_Parent->CalcPosition(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;j<PATCH_SIZE+1;j++) {
|
||||
for (int i=0;i<PATCH_SIZE+1;i++) {
|
||||
CVector3D pos;
|
||||
m_Parent->CalcPosition(m_X*PATCH_SIZE+i,m_Z*PATCH_SIZE+j,pos);
|
||||
m_Bounds+=pos;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,91 +1,91 @@
|
||||
#ifndef _PATCHRDATA_H
|
||||
#define _PATCHRDATA_H
|
||||
|
||||
#include <vector>
|
||||
#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<rhs.m_Priority; }
|
||||
Handle m_Handle;
|
||||
int m_Priority;
|
||||
};
|
||||
|
||||
// owner patch
|
||||
CPatch* m_Patch;
|
||||
// vertex buffer handle for base vertices
|
||||
u32 m_VBBase;
|
||||
// vertex buffer handle for blend vertices
|
||||
u32 m_VBBlends;
|
||||
// patch render vertices
|
||||
SBaseVertex* m_Vertices;
|
||||
// patch index list
|
||||
std::vector<unsigned short> m_Indices;
|
||||
// list of base splats to apply to this patch
|
||||
std::vector<SSplat> m_Splats;
|
||||
// vertices to use for blending transition texture passes
|
||||
std::vector<SBlendVertex> m_BlendVertices;
|
||||
// indices into blend vertices for the blend splats
|
||||
std::vector<unsigned short> m_BlendIndices;
|
||||
// splats used in blend pass
|
||||
std::vector<SSplat> m_BlendSplats;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
#ifndef _PATCHRDATA_H
|
||||
#define _PATCHRDATA_H
|
||||
|
||||
#include <vector>
|
||||
#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<rhs.m_Priority; }
|
||||
Handle m_Handle;
|
||||
int m_Priority;
|
||||
};
|
||||
|
||||
// owner patch
|
||||
CPatch* m_Patch;
|
||||
// vertex buffer handle for base vertices
|
||||
u32 m_VBBase;
|
||||
// vertex buffer handle for blend vertices
|
||||
u32 m_VBBlends;
|
||||
// patch render vertices
|
||||
SBaseVertex* m_Vertices;
|
||||
// patch index list
|
||||
std::vector<unsigned short> m_Indices;
|
||||
// list of base splats to apply to this patch
|
||||
std::vector<SSplat> m_Splats;
|
||||
// vertices to use for blending transition texture passes
|
||||
std::vector<SBlendVertex> m_BlendVertices;
|
||||
// indices into blend vertices for the blend splats
|
||||
std::vector<unsigned short> m_BlendIndices;
|
||||
// splats used in blend pass
|
||||
std::vector<SSplat> m_BlendSplats;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -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];
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -1,94 +1,94 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: RenderableObject.h
|
||||
// Author: Rich Cross
|
||||
// Contact: rich@wildfiregames.com
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _RENDERABLEOBJECT_H
|
||||
#define _RENDERABLEOBJECT_H
|
||||
|
||||
#include <assert.h>
|
||||
#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 <assert.h>
|
||||
#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
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -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 <vector>
|
||||
#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<CPatch*> m_TerrainPatches;
|
||||
std::vector<CModel*> m_Models;
|
||||
std::vector<CSprite*> m_Sprites;
|
||||
std::vector<CParticleSys*> m_ParticleSyses;
|
||||
std::vector<COverlay*> 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 <vector>
|
||||
#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<CPatch*> m_TerrainPatches;
|
||||
std::vector<CModel*> m_Models;
|
||||
std::vector<CSprite*> m_Sprites;
|
||||
std::vector<CParticleSys*> m_ParticleSyses;
|
||||
std::vector<COverlay*> 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
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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;i<m_NumKeys;i++) {
|
||||
const Key& startkey=GetKey(startframe,i);
|
||||
const Key& endkey=GetKey(endframe,i);
|
||||
|
||||
CVector3D trans=startkey.m_Translation*(1-deltatime)+endkey.m_Translation*deltatime;
|
||||
CQuaternion rot;
|
||||
rot.Slerp(startkey.m_Rotation,endkey.m_Rotation,deltatime);
|
||||
|
||||
matrices[i].SetIdentity();
|
||||
matrices[i].Rotate(rot);
|
||||
matrices[i].Translate(trans);
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Load: try to load the anim from given file; return a new anim if successful
|
||||
CSkeletonAnim* CSkeletonAnim::Load(const char* filename)
|
||||
{
|
||||
CFileUnpacker unpacker;
|
||||
unpacker.Read(filename,"PSSA");
|
||||
|
||||
// check version
|
||||
if (unpacker.GetVersion()<FILE_READ_VERSION) {
|
||||
throw CFileUnpacker::CFileVersionError();
|
||||
}
|
||||
|
||||
// unpack the data
|
||||
CSkeletonAnim* anim=new CSkeletonAnim;
|
||||
try {
|
||||
CStr str;
|
||||
unpacker.UnpackString(str);
|
||||
strcpy(anim->m_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;i<m_NumKeys;i++) {
|
||||
const Key& startkey=GetKey(startframe,i);
|
||||
const Key& endkey=GetKey(endframe,i);
|
||||
|
||||
CVector3D trans=startkey.m_Translation*(1-deltatime)+endkey.m_Translation*deltatime;
|
||||
CQuaternion rot;
|
||||
rot.Slerp(startkey.m_Rotation,endkey.m_Rotation,deltatime);
|
||||
|
||||
matrices[i].SetIdentity();
|
||||
matrices[i].Rotate(rot);
|
||||
matrices[i].Translate(trans);
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Load: try to load the anim from given file; return a new anim if successful
|
||||
CSkeletonAnim* CSkeletonAnim::Load(const char* filename)
|
||||
{
|
||||
CFileUnpacker unpacker;
|
||||
unpacker.Read(filename,"PSSA");
|
||||
|
||||
// check version
|
||||
if (unpacker.GetVersion()<FILE_READ_VERSION) {
|
||||
throw CFileUnpacker::CFileVersionError();
|
||||
}
|
||||
|
||||
// unpack the data
|
||||
CSkeletonAnim* anim=new CSkeletonAnim;
|
||||
try {
|
||||
CStr str;
|
||||
unpacker.UnpackString(str);
|
||||
strcpy(anim->m_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");
|
||||
}
|
||||
|
||||
|
@ -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
|
@ -1,292 +1,292 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: Terrain.cpp
|
||||
// Author: Rich Cross
|
||||
// Contact: rich@wildfiregames.com
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "res/tex.h"
|
||||
#include "res/mem.h"
|
||||
|
||||
#include <string.h>
|
||||
#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 (i<m_MapSize-1) {
|
||||
CalcPosition(i+1,j,tmp);
|
||||
right=tmp-basepos;
|
||||
}
|
||||
|
||||
if (j>0) {
|
||||
CalcPosition(i,j-1,tmp);
|
||||
up=tmp-basepos;
|
||||
}
|
||||
|
||||
if (j<m_MapSize-1) {
|
||||
CalcPosition(i,j+1,tmp);
|
||||
down=tmp-basepos;
|
||||
}
|
||||
|
||||
CVector3D n0 = up.Cross(left);
|
||||
CVector3D n1 = left.Cross(down);
|
||||
CVector3D n2 = down.Cross(right);
|
||||
CVector3D n3 = right.Cross(up);
|
||||
|
||||
normal = n0 + n1 + n2 + n3;
|
||||
float nlen=normal.GetLength();
|
||||
if (nlen>0.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;j<copysize;j++) {
|
||||
memcpy(dst,src,copysize*sizeof(u16));
|
||||
dst+=copysize;
|
||||
src+=m_MapSize;
|
||||
if (newMapSize>m_MapSize) {
|
||||
// entend the last height to the end of the row
|
||||
for (u32 i=0;i<newMapSize-m_MapSize;i++) {
|
||||
*dst++=*(src-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (newMapSize>m_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;i<newMapSize-m_MapSize;i++) {
|
||||
memcpy(dst,src,newMapSize*sizeof(u16));
|
||||
dst+=newMapSize;
|
||||
}
|
||||
}
|
||||
|
||||
// now build new patches
|
||||
for (j=0;j<size;j++) {
|
||||
for (u32 i=0;i<size;i++) {
|
||||
// copy over texture data from existing tiles, if possible
|
||||
if (i<m_MapSizePatches && j<m_MapSizePatches) {
|
||||
memcpy(newPatches[j*size+i].m_MiniPatches,m_Patches[j*m_MapSizePatches+i].m_MiniPatches,sizeof(CMiniPatch)*16*16);
|
||||
}
|
||||
}
|
||||
|
||||
if (j<m_MapSizePatches && size>m_MapSizePatches) {
|
||||
// copy over the last tile from each column
|
||||
for (u32 n=0;n<size-m_MapSizePatches;n++) {
|
||||
for (int m=0;m<16;m++) {
|
||||
CMiniPatch& src=m_Patches[j*m_MapSizePatches+m_MapSizePatches-1].m_MiniPatches[m][15];
|
||||
for (int k=0;k<16;k++) {
|
||||
CMiniPatch& dst=newPatches[j*size+m_MapSizePatches+n].m_MiniPatches[m][k];
|
||||
dst.Tex1=src.Tex1;
|
||||
dst.Tex1Priority=src.Tex1Priority;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (size>m_MapSizePatches) {
|
||||
// copy over the last tile from each column
|
||||
CPatch* srcpatch=&newPatches[(m_MapSizePatches-1)*size];
|
||||
CPatch* dstpatch=srcpatch+size;
|
||||
for (u32 p=0;p<size-m_MapSizePatches;p++) {
|
||||
for (u32 n=0;n<size;n++) {
|
||||
for (int m=0;m<16;m++) {
|
||||
for (int k=0;k<16;k++) {
|
||||
CMiniPatch& src=srcpatch->m_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;j<m_MapSizePatches;j++) {
|
||||
for (u32 i=0;i<m_MapSizePatches;i++) {
|
||||
CPatch* patch=GetPatch(i,j);
|
||||
patch->Initialize(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;j<m_MapSizePatches;j++) {
|
||||
for (u32 i=0;i<m_MapSizePatches;i++) {
|
||||
CPatch* patch=GetPatch(i,j);
|
||||
patch->CalcBounds();
|
||||
patch->SetDirty(RENDERDATA_UPDATE_VERTICES);
|
||||
}
|
||||
}
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: Terrain.cpp
|
||||
// Author: Rich Cross
|
||||
// Contact: rich@wildfiregames.com
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "res/tex.h"
|
||||
#include "res/mem.h"
|
||||
|
||||
#include <string.h>
|
||||
#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 (i<m_MapSize-1) {
|
||||
CalcPosition(i+1,j,tmp);
|
||||
right=tmp-basepos;
|
||||
}
|
||||
|
||||
if (j>0) {
|
||||
CalcPosition(i,j-1,tmp);
|
||||
up=tmp-basepos;
|
||||
}
|
||||
|
||||
if (j<m_MapSize-1) {
|
||||
CalcPosition(i,j+1,tmp);
|
||||
down=tmp-basepos;
|
||||
}
|
||||
|
||||
CVector3D n0 = up.Cross(left);
|
||||
CVector3D n1 = left.Cross(down);
|
||||
CVector3D n2 = down.Cross(right);
|
||||
CVector3D n3 = right.Cross(up);
|
||||
|
||||
normal = n0 + n1 + n2 + n3;
|
||||
float nlen=normal.GetLength();
|
||||
if (nlen>0.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;j<copysize;j++) {
|
||||
memcpy(dst,src,copysize*sizeof(u16));
|
||||
dst+=copysize;
|
||||
src+=m_MapSize;
|
||||
if (newMapSize>m_MapSize) {
|
||||
// entend the last height to the end of the row
|
||||
for (u32 i=0;i<newMapSize-m_MapSize;i++) {
|
||||
*dst++=*(src-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (newMapSize>m_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;i<newMapSize-m_MapSize;i++) {
|
||||
memcpy(dst,src,newMapSize*sizeof(u16));
|
||||
dst+=newMapSize;
|
||||
}
|
||||
}
|
||||
|
||||
// now build new patches
|
||||
for (j=0;j<size;j++) {
|
||||
for (u32 i=0;i<size;i++) {
|
||||
// copy over texture data from existing tiles, if possible
|
||||
if (i<m_MapSizePatches && j<m_MapSizePatches) {
|
||||
memcpy(newPatches[j*size+i].m_MiniPatches,m_Patches[j*m_MapSizePatches+i].m_MiniPatches,sizeof(CMiniPatch)*16*16);
|
||||
}
|
||||
}
|
||||
|
||||
if (j<m_MapSizePatches && size>m_MapSizePatches) {
|
||||
// copy over the last tile from each column
|
||||
for (u32 n=0;n<size-m_MapSizePatches;n++) {
|
||||
for (int m=0;m<16;m++) {
|
||||
CMiniPatch& src=m_Patches[j*m_MapSizePatches+m_MapSizePatches-1].m_MiniPatches[m][15];
|
||||
for (int k=0;k<16;k++) {
|
||||
CMiniPatch& dst=newPatches[j*size+m_MapSizePatches+n].m_MiniPatches[m][k];
|
||||
dst.Tex1=src.Tex1;
|
||||
dst.Tex1Priority=src.Tex1Priority;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (size>m_MapSizePatches) {
|
||||
// copy over the last tile from each column
|
||||
CPatch* srcpatch=&newPatches[(m_MapSizePatches-1)*size];
|
||||
CPatch* dstpatch=srcpatch+size;
|
||||
for (u32 p=0;p<size-m_MapSizePatches;p++) {
|
||||
for (u32 n=0;n<size;n++) {
|
||||
for (int m=0;m<16;m++) {
|
||||
for (int k=0;k<16;k++) {
|
||||
CMiniPatch& src=srcpatch->m_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;j<m_MapSizePatches;j++) {
|
||||
for (u32 i=0;i<m_MapSizePatches;i++) {
|
||||
CPatch* patch=GetPatch(i,j);
|
||||
patch->Initialize(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;j<m_MapSizePatches;j++) {
|
||||
for (u32 i=0;i<m_MapSizePatches;i++) {
|
||||
CPatch* patch=GetPatch(i,j);
|
||||
patch->CalcBounds();
|
||||
patch->SetDirty(RENDERDATA_UPDATE_VERTICES);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,136 +1,136 @@
|
||||
#include <algorithm>
|
||||
#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;i<m_Objects.size();++i) {
|
||||
CModel* model=m_Objects[i].m_Model;
|
||||
CModelRData* modeldata=(CModelRData*) model->GetRenderData();
|
||||
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;i<m_Objects.size();++i) {
|
||||
CModel* model=m_Objects[i].m_Model;
|
||||
CModelRData* modeldata=(CModelRData*) model->GetRenderData();
|
||||
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;i<m_Objects.size();++i) {
|
||||
CModel* model=m_Objects[i].m_Model;
|
||||
CModelRData* modeldata=(CModelRData*) model->GetRenderData();
|
||||
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 <algorithm>
|
||||
#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;i<m_Objects.size();++i) {
|
||||
CModel* model=m_Objects[i].m_Model;
|
||||
CModelRData* modeldata=(CModelRData*) model->GetRenderData();
|
||||
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;i<m_Objects.size();++i) {
|
||||
CModel* model=m_Objects[i].m_Model;
|
||||
CModelRData* modeldata=(CModelRData*) model->GetRenderData();
|
||||
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;i<m_Objects.size();++i) {
|
||||
CModel* model=m_Objects[i].m_Model;
|
||||
CModelRData* modeldata=(CModelRData*) model->GetRenderData();
|
||||
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);
|
||||
}
|
||||
|
@ -1,31 +1,31 @@
|
||||
#ifndef __TRANSPARENCYRENDERER_H
|
||||
#define __TRANSPARENCYRENDERER_H
|
||||
|
||||
#include <vector>
|
||||
|
||||
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<SObject> m_Objects;
|
||||
};
|
||||
|
||||
extern CTransparencyRenderer g_TransparencyRenderer;
|
||||
|
||||
#endif
|
||||
#ifndef __TRANSPARENCYRENDERER_H
|
||||
#define __TRANSPARENCYRENDERER_H
|
||||
|
||||
#include <vector>
|
||||
|
||||
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<SObject> m_Objects;
|
||||
};
|
||||
|
||||
extern CTransparencyRenderer g_TransparencyRenderer;
|
||||
|
||||
#endif
|
||||
|
@ -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
|
||||
|
@ -1,28 +1,28 @@
|
||||
#include "res/res.h"
|
||||
#include "UnitManager.h"
|
||||
#include <algorithm>
|
||||
|
||||
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<CUnit*>::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<m_Units.size();i++) {
|
||||
delete m_Units[i];
|
||||
}
|
||||
m_Units.clear();
|
||||
}
|
||||
#include "res/res.h"
|
||||
#include "UnitManager.h"
|
||||
#include <algorithm>
|
||||
|
||||
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<CUnit*>::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<m_Units.size();i++) {
|
||||
delete m_Units[i];
|
||||
}
|
||||
m_Units.clear();
|
||||
}
|
||||
|
@ -1,25 +1,25 @@
|
||||
#ifndef _UNITMANAGER_H
|
||||
#define _UNITMANAGER_H
|
||||
|
||||
#include <vector>
|
||||
#include "Unit.h"
|
||||
|
||||
class CUnitManager
|
||||
{
|
||||
public:
|
||||
CUnitManager() {}
|
||||
|
||||
void AddUnit(CUnit* unit);
|
||||
void RemoveUnit(CUnit* unit);
|
||||
|
||||
void DeleteAll();
|
||||
|
||||
const std::vector<CUnit*>& GetUnits() const { return m_Units; }
|
||||
|
||||
private:
|
||||
std::vector<CUnit*> m_Units;
|
||||
};
|
||||
|
||||
extern CUnitManager g_UnitMan;
|
||||
|
||||
#ifndef _UNITMANAGER_H
|
||||
#define _UNITMANAGER_H
|
||||
|
||||
#include <vector>
|
||||
#include "Unit.h"
|
||||
|
||||
class CUnitManager
|
||||
{
|
||||
public:
|
||||
CUnitManager() {}
|
||||
|
||||
void AddUnit(CUnit* unit);
|
||||
void RemoveUnit(CUnit* unit);
|
||||
|
||||
void DeleteAll();
|
||||
|
||||
const std::vector<CUnit*>& GetUnits() const { return m_Units; }
|
||||
|
||||
private:
|
||||
std::vector<CUnit*> m_Units;
|
||||
};
|
||||
|
||||
extern CUnitManager g_UnitMan;
|
||||
|
||||
#endif
|
@ -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;
|
||||
}
|
||||
|
@ -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 <math.h>
|
||||
#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 <math.h>
|
||||
#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
|
||||
|
@ -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 <math.h>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// 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 <math.h>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// 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
|
||||
|
@ -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<g_TexMan.m_TerrainTextures.size();ii++) {
|
||||
g_Camera.m_Orientation.RotateY(DEGTORAD(-45));
|
||||
|
||||
g_Camera.m_Orientation.Translate (100, 150, -100);
|
||||
|
||||
}
|
||||
|
||||
void InitResources()
|
||||
|
Loading…
Reference in New Issue
Block a user