2004-06-03 20:38:14 +02:00
# include "precompiled.h"
2004-05-30 02:46:58 +02:00
# include "ObjectEntry.h"
# include "ObjectManager.h"
2005-03-22 18:09:36 +01:00
# include "ObjectBase.h"
2004-05-30 02:46:58 +02:00
# include "Model.h"
# include "ModelDef.h"
2004-06-08 14:10:51 +02:00
# include "CLogger.h"
2004-09-24 05:52:03 +02:00
# include "MaterialManager.h"
2004-11-08 23:02:01 +01:00
# include "MeshManager.h"
2004-05-30 02:46:58 +02:00
# include "UnitManager.h"
2004-12-12 20:43:55 +01:00
# include "Unit.h"
2004-05-30 02:46:58 +02:00
2004-07-08 17:22:09 +02:00
# include "ps/Xeromyces.h"
2005-01-11 21:15:39 +01:00
# include "ps/XMLWriter.h"
2004-05-30 02:46:58 +02:00
2004-12-31 00:01:09 +01:00
# include "lib/res/vfs.h"
2004-08-15 22:57:31 +02:00
# define LOG_CATEGORY "graphics"
2005-03-18 23:30:23 +01:00
2005-03-22 18:09:36 +01:00
CObjectEntry : : CObjectEntry ( int type , CObjectBase * base )
: m_Model ( 0 ) , m_Type ( type ) , m_Base ( base )
2004-05-30 02:46:58 +02:00
{
m_IdleAnim = 0 ;
m_WalkAnim = 0 ;
m_DeathAnim = 0 ;
2004-11-11 08:09:32 +01:00
m_CorpseAnim = 0 ;
2004-05-30 02:46:58 +02:00
m_MeleeAnim = 0 ;
m_RangedAnim = 0 ;
}
CObjectEntry : : ~ CObjectEntry ( )
{
for ( size_t i = 0 ; i < m_Animations . size ( ) ; i + + ) {
2004-06-07 22:03:10 +02:00
delete m_Animations [ i ] . m_AnimData ;
2004-05-30 02:46:58 +02:00
}
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
2004-12-12 19:40:00 +01:00
CModelDefPtr oldmodeldef = m_Model ? m_Model - > GetModelDef ( ) : CModelDefPtr ( ) ;
2004-06-07 22:03:10 +02:00
2004-08-11 22:18:30 +02:00
const char * modelfilename = m_ModelName . c_str ( ) ;
2004-12-12 19:40:00 +01:00
// try and create a model
CModelDefPtr modeldef ( g_MeshManager . GetMesh ( modelfilename ) ) ;
if ( ! modeldef )
{
2004-08-15 22:57:31 +02:00
LOG ( ERROR , LOG_CATEGORY , " CObjectEntry::BuildModel(): Model %s failed to load " , modelfilename ) ;
2004-05-30 02:46:58 +02:00
return false ;
}
2004-06-07 22:03:10 +02:00
2004-10-06 20:46:33 +02:00
// delete old model, create new
delete m_Model ;
2004-05-30 02:46:58 +02:00
m_Model = new CModel ;
m_Model - > SetTexture ( ( const char * ) m_TextureName ) ;
2005-03-22 18:09:36 +01:00
m_Model - > SetMaterial ( g_MaterialManager . LoadMaterial ( m_Base - > m_Material ) ) ;
2004-05-30 02:46:58 +02:00
m_Model - > InitModel ( modeldef ) ;
2004-06-07 22:03:10 +02:00
2004-05-30 02:46:58 +02:00
// calculate initial object space bounds, based on vertex positions
m_Model - > CalcObjectBounds ( ) ;
2004-06-07 22:03:10 +02:00
2004-05-30 02:46:58 +02:00
// load animations
2005-02-11 13:57:19 +01:00
for ( uint t = 0 ; t < m_Animations . size ( ) ; t + + )
2004-05-30 02:46:58 +02:00
{
2005-02-11 13:57:19 +01:00
if ( m_Animations [ t ] . m_FileName . Length ( ) > 0 )
2004-05-30 02:46:58 +02:00
{
2004-08-11 22:18:30 +02:00
const char * animfilename = m_Animations [ t ] . m_FileName . c_str ( ) ;
m_Animations [ t ] . m_AnimData = m_Model - > BuildAnimation ( animfilename , m_Animations [ t ] . m_Speed ) ;
2004-05-30 02:46:58 +02:00
2005-01-12 15:31:47 +01:00
CStr AnimNameLC = m_Animations [ t ] . m_AnimName . LowerCase ( ) ;
2005-02-11 13:57:19 +01:00
if ( AnimNameLC = = " idle " )
2004-05-30 02:46:58 +02:00
m_IdleAnim = m_Animations [ t ] . m_AnimData ;
2005-01-12 15:31:47 +01:00
else
2005-02-11 13:57:19 +01:00
if ( AnimNameLC = = " walk " )
2004-05-30 02:46:58 +02:00
m_WalkAnim = m_Animations [ t ] . m_AnimData ;
2005-01-12 15:31:47 +01:00
else
2005-02-11 13:57:19 +01:00
if ( AnimNameLC = = " attack " )
2004-11-11 08:09:32 +01:00
m_MeleeAnim = m_Animations [ t ] . m_AnimData ;
2005-01-12 15:31:47 +01:00
else
2005-02-11 13:57:19 +01:00
if ( AnimNameLC = = " death " )
2004-11-11 08:09:32 +01:00
m_DeathAnim = m_Animations [ t ] . m_AnimData ;
2005-01-12 15:31:47 +01:00
else
2005-02-11 13:57:19 +01:00
if ( AnimNameLC = = " decay " )
2004-11-11 08:09:32 +01:00
m_CorpseAnim = m_Animations [ t ] . m_AnimData ;
2005-01-12 15:31:47 +01:00
//else
// debug_out("Invalid animation name '%s'\n", (const char*)AnimNameLC);
2004-05-30 02:46:58 +02:00
}
else
{
2004-06-07 22:03:10 +02:00
// FIXME, RC - don't store invalid animations (possible?)
2004-05-30 02:46:58 +02:00
m_Animations [ t ] . m_AnimData = 0 ;
}
}
// start up idling
2005-02-11 13:57:19 +01:00
if ( ! m_Model - > SetAnimation ( m_IdleAnim ) )
LOG ( ERROR , LOG_CATEGORY , " Failed to set idle animation in model \" %s \" " , modelfilename ) ;
2004-06-07 22:03:10 +02:00
2004-05-30 02:46:58 +02:00
// build props - TODO, RC - need to fix up bounds here
for ( uint p = 0 ; p < m_Props . size ( ) ; p + + ) {
2005-03-22 18:09:36 +01:00
const CObjectBase : : Prop & prop = m_Props [ p ] ;
2004-05-30 02:46:58 +02:00
SPropPoint * proppoint = modeldef - > FindPropPoint ( ( const char * ) prop . m_PropPointName ) ;
if ( proppoint ) {
CObjectEntry * oe = g_ObjMan . FindObject ( prop . m_ModelName ) ;
if ( oe ) {
// try and build model if we haven't already got it
if ( ! oe - > m_Model ) oe - > BuildModel ( ) ;
if ( oe - > m_Model ) {
CModel * propmodel = oe - > m_Model - > Clone ( ) ;
m_Model - > AddProp ( proppoint , propmodel ) ;
if ( oe - > m_WalkAnim ) propmodel - > SetAnimation ( oe - > m_WalkAnim ) ;
2004-06-08 14:10:51 +02:00
} else {
2005-03-29 22:50:04 +02:00
LOG ( ERROR , LOG_CATEGORY , " Failed to build prop model \" %s \" on actor \" %s \" " , ( const char * ) prop . m_ModelName , ( const char * ) m_Base - > m_ShortName ) ;
2004-05-30 02:46:58 +02:00
}
}
2004-06-08 14:10:51 +02:00
} else {
2005-03-26 01:22:42 +01:00
LOG ( ERROR , LOG_CATEGORY , " Failed to find matching prop point called \" %s \" in model \" %s \" on actor \" %s \" " , ( const char * ) prop . m_PropPointName , modelfilename , ( const char * ) prop . m_ModelName ) ;
2004-05-30 02:46:58 +02:00
}
}
2004-10-06 20:46:33 +02:00
// setup flags
2005-03-22 18:09:36 +01:00
if ( m_Base - > m_Properties . m_CastShadows ) {
2004-10-06 20:46:33 +02:00
m_Model - > SetFlags ( m_Model - > GetFlags ( ) | MODELFLAG_CASTSHADOWS ) ;
}
2004-05-30 02:46:58 +02:00
// replace any units using old model to now use new model; also reprop models, if necessary
2004-10-06 20:46:33 +02:00
// FIXME, RC - ugh, doesn't recurse correctly through props
2004-05-30 02:46:58 +02:00
const std : : vector < CUnit * > & units = g_UnitMan . GetUnits ( ) ;
for ( uint i = 0 ; i < units . size ( ) ; + + i ) {
CModel * unitmodel = units [ i ] - > GetModel ( ) ;
2004-10-06 20:46:33 +02:00
if ( unitmodel - > GetModelDef ( ) = = oldmodeldef ) {
2004-05-30 02:46:58 +02:00
unitmodel - > InitModel ( m_Model - > GetModelDef ( ) ) ;
2004-10-06 20:46:33 +02:00
unitmodel - > SetFlags ( m_Model - > GetFlags ( ) ) ;
2004-06-07 22:03:10 +02:00
2004-05-30 02:46:58 +02:00
const std : : vector < CModel : : Prop > & newprops = m_Model - > GetProps ( ) ;
for ( uint j = 0 ; j < newprops . size ( ) ; j + + ) {
unitmodel - > AddProp ( newprops [ j ] . m_Point , newprops [ j ] . m_Model - > Clone ( ) ) ;
}
}
2004-10-06 20:46:33 +02:00
std : : vector < CModel : : Prop > & mdlprops = unitmodel - > GetProps ( ) ;
for ( uint j = 0 ; j < mdlprops . size ( ) ; j + + ) {
CModel : : Prop & prop = mdlprops [ j ] ;
if ( prop . m_Model ) {
if ( prop . m_Model - > GetModelDef ( ) = = oldmodeldef ) {
delete prop . m_Model ;
prop . m_Model = m_Model - > Clone ( ) ;
}
}
}
2004-05-30 02:46:58 +02:00
}
return true ;
}
2005-03-22 18:09:36 +01:00
void CObjectEntry : : ApplyRandomVariant ( CObjectBase : : variation_key & vars )
2004-05-30 02:46:58 +02:00
{
2005-03-22 18:09:36 +01:00
CStr chosenTexture ;
CStr chosenModel ;
std : : map < CStr , CObjectBase : : Prop > chosenProps ;
std : : map < CStr , CObjectBase : : Anim > chosenAnims ;
2004-05-30 02:46:58 +02:00
2005-03-22 18:09:36 +01:00
CObjectBase : : variation_key : : const_iterator vars_it = vars . begin ( ) ;
2004-07-08 17:22:09 +02:00
2005-03-22 18:09:36 +01:00
for ( std : : vector < std : : vector < CObjectBase : : Variant > > : : iterator grp = m_Base - > m_Variants . begin ( ) ;
grp ! = m_Base - > m_Variants . end ( ) ;
+ + grp )
2005-03-18 23:30:23 +01:00
{
2005-03-22 18:09:36 +01:00
CObjectBase : : Variant & var ( grp - > at ( * ( vars_it + + ) ) ) ;
2005-01-11 21:15:39 +01:00
2005-03-22 18:09:36 +01:00
if ( var . m_TextureFilename . Length ( ) )
chosenTexture = var . m_TextureFilename ;
2005-01-11 21:15:39 +01:00
2005-03-22 18:09:36 +01:00
if ( var . m_ModelFilename . Length ( ) )
chosenModel = var . m_ModelFilename ;
2005-01-11 21:15:39 +01:00
2005-03-22 18:09:36 +01:00
for ( std : : vector < CObjectBase : : Prop > : : iterator it = var . m_Props . begin ( ) ; it ! = var . m_Props . end ( ) ; + + it )
chosenProps [ it - > m_PropPointName ] = * it ;
2005-01-11 21:15:39 +01:00
2005-03-22 18:09:36 +01:00
for ( std : : vector < CObjectBase : : Anim > : : iterator it = var . m_Anims . begin ( ) ; it ! = var . m_Anims . end ( ) ; + + it )
chosenAnims [ it - > m_AnimName ] = * it ;
2005-03-18 23:30:23 +01:00
}
2005-03-22 18:09:36 +01:00
m_TextureName = chosenTexture ;
m_ModelName = chosenModel ;
2005-03-18 23:30:23 +01:00
2005-03-22 18:09:36 +01:00
for ( std : : map < CStr , CObjectBase : : Prop > : : iterator it = chosenProps . begin ( ) ; it ! = chosenProps . end ( ) ; + + it )
m_Props . push_back ( it - > second ) ;
2004-07-08 17:22:09 +02:00
2005-03-22 18:09:36 +01:00
for ( std : : map < CStr , CObjectBase : : Anim > : : iterator it = chosenAnims . begin ( ) ; it ! = chosenAnims . end ( ) ; + + it )
m_Animations . push_back ( it - > second ) ;
2004-05-30 02:46:58 +02:00
}
2005-01-11 21:15:39 +01:00
2005-03-22 18:09:36 +01:00
CSkeletonAnim * CObjectEntry : : GetNamedAnimation ( CStr animationName )
{
for ( uint t = 0 ; t < m_Animations . size ( ) ; t + + )
2004-12-31 00:01:09 +01:00
{
2005-03-22 18:09:36 +01:00
if ( m_Animations [ t ] . m_AnimName = = animationName )
return ( m_Animations [ t ] . m_AnimData ) ;
2004-12-31 00:01:09 +01:00
}
2005-03-22 18:09:36 +01:00
return ( NULL ) ;
2004-05-30 02:46:58 +02:00
}
2004-10-06 20:46:33 +02:00
2005-03-22 18:09:36 +01:00
CObjectBase : : Prop * CObjectEntry : : FindProp ( const char * proppointname )
2004-10-06 20:46:33 +02:00
{
for ( size_t i = 0 ; i < m_Props . size ( ) ; i + + ) {
if ( strcmp ( proppointname , m_Props [ i ] . m_PropPointName ) = = 0 ) return & m_Props [ i ] ;
}
return 0 ;
}