diff --git a/source/graphics/ObjectEntry.cpp b/source/graphics/ObjectEntry.cpp index f370ff1adf..3137bc1a70 100755 --- a/source/graphics/ObjectEntry.cpp +++ b/source/graphics/ObjectEntry.cpp @@ -20,6 +20,8 @@ CObjectEntry::CObjectEntry(int type) : m_Model(0), m_Type(type) m_DeathAnim=0; m_MeleeAnim=0; m_RangedAnim=0; + m_Properties.m_CastShadows=true; + m_Properties.m_AutoFlatten=false; } CObjectEntry::~CObjectEntry() @@ -33,7 +35,6 @@ CObjectEntry::~CObjectEntry() bool CObjectEntry::BuildModel() { - // check we've enough data to consider building the object if (m_ModelName.Length()==0 || m_TextureName.Length()==0) { return false; @@ -43,7 +44,7 @@ bool CObjectEntry::BuildModel() 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; + CModelDef* oldmodeldef=m_Model ? m_Model->GetModelDef() : 0; // try and create a model CModelDef* modeldef; @@ -57,7 +58,8 @@ bool CObjectEntry::BuildModel() return false; } - // create new Model + // delete old model, create new + delete m_Model; m_Model=new CModel; m_Model->SetTexture((const char*) m_TextureName); m_Model->SetMaterial(g_MaterialManager.LoadMaterial((const char *)m_Material)); @@ -110,25 +112,43 @@ bool CObjectEntry::BuildModel() } } + // setup flags + if (m_Properties.m_CastShadows) { + m_Model->SetFlags(m_Model->GetFlags()|MODELFLAG_CASTSHADOWS); + } + // build world space bounds m_Model->CalcBounds(); // replace any units using old model to now use new model; also reprop models, if necessary + // FIXME, RC - ugh, doesn't recurse correctly through props const std::vector& units=g_UnitMan.GetUnits(); for (uint i=0;iGetModel(); - if (unitmodel->GetModelDef()==oldmodel) { + if (unitmodel->GetModelDef()==oldmodeldef) { unitmodel->InitModel(m_Model->GetModelDef()); + unitmodel->SetFlags(m_Model->GetFlags()); const std::vector& newprops=m_Model->GetProps(); for (uint j=0;jAddProp(newprops[j].m_Point,newprops[j].m_Model->Clone()); } } + + std::vector& mdlprops=unitmodel->GetProps(); + for (uint j=0;jGetModelDef()==oldmodeldef) { + delete prop.m_Model; + prop.m_Model=m_Model->Clone(); + } + } + } } // and were done with the old model .. - delete oldmodel; + delete oldmodeldef; return true; } @@ -159,11 +179,14 @@ bool CObjectEntry::Load(const char* filename) EL(material); EL(animations); EL(props); + EL(properties); AT(attachpoint); AT(model); AT(name); AT(file); AT(speed); + AT(autoflatten); + AT(castshadows); #undef AT #undef EL @@ -190,6 +213,21 @@ bool CObjectEntry::Load(const char* filename) else if(element_name == el_material) m_Material = element_value; + else if (element_name == el_properties) { + XMBAttributeList attributes=child.getAttributes(); + for (int j = 0; j < attributes.Count; ++j) { + XMBAttribute attrib=attributes.item(j); + int attrib_name = attrib.Name; + if (attrib_name == at_autoflatten) { + CStr str= (CStr) attrib.Value; + m_Properties.m_AutoFlatten=str.ToInt() ? true : false; + } else if (attrib_name == at_castshadows) { + CStr str= (CStr) attrib.Value; + m_Properties.m_CastShadows=str.ToInt() ? true : false; + } + } + } + else if (element_name == el_animations) { XMBElementList animations=child.getChildNodes(); @@ -252,15 +290,38 @@ bool CObjectEntry::Save(const char* filename) fprintf(fp,"\t%s\n",(const char*) m_TextureName); if(m_Material.Trim(PS_TRIM_BOTH).Length()) fprintf(fp,"\t%s\n", (const char*)m_Material); + + fprintf(fp,"\t\n"); if (m_Animations.size()>0) { fprintf(fp,"\t\n"); for (uint i=0;i \n",(const char*) m_Animations[i].m_AnimName,(const char*) m_Animations[i].m_FileName); + fprintf(fp,"\t\t \n",(const char*) m_Animations[i].m_AnimName,(const char*) m_Animations[i].m_FileName,int(m_Animations[i].m_Speed*100)); } fprintf(fp,"\t\n"); } + if (m_Props.size()>0) { + fprintf(fp,"\t\n"); + for (uint i=0;i \n",(const char*) m_Props[i].m_PropPointName,(const char*) m_Props[i].m_ModelName); + } + fprintf(fp,"\t\n"); + } + fprintf(fp,"\n"); fclose(fp); return true; } + + +CObjectEntry::Prop* CObjectEntry::FindProp(const char* proppointname) +{ + for (size_t i=0;i m_Props; + struct { + // automatically flatten terrain when applying object + bool m_AutoFlatten; + // cast shadows from this object + bool m_CastShadows; + } m_Properties; // corresponding model CModel* m_Model; // type of object; index into object managers types array diff --git a/source/graphics/ObjectManager.cpp b/source/graphics/ObjectManager.cpp index 9c3219cc3a..307b1fd7f9 100755 --- a/source/graphics/ObjectManager.cpp +++ b/source/graphics/ObjectManager.cpp @@ -39,6 +39,21 @@ CObjectEntry* CObjectManager::FindObject(const char* objectname) return 0; } +CObjectEntry* CObjectManager::FindObjectByFileName(const char* filename) +{ + for (uint k=0;k& objects=m_ObjectTypes[k].m_Objects; + + for (uint i=0;im_FileName)==0) { + return objects[i]; + } + } + } + + return 0; +} + void CObjectManager::AddObjectType(const char* name) { m_ObjectTypes.resize(m_ObjectTypes.size()+1); @@ -68,7 +83,7 @@ void CObjectManager::DeleteObject(CObjectEntry* entry) void CObjectManager::LoadObjects() { // find all the object types by directory name - BuildObjectTypes(); + BuildObjectTypes(0); // now iterate through terrain types loading all textures of that type uint i; @@ -92,21 +107,35 @@ void CObjectManager::LoadObjects() } } -void CObjectManager::BuildObjectTypes() +void CObjectManager::BuildObjectTypes(const char* base) { - Handle dir=vfs_open_dir("art/actors/"); + CStr rootdir("art/actors/"); + if (base) { + rootdir+=base; + rootdir+='/'; + } + + Handle dir=vfs_open_dir(rootdir); vfsDirEnt dent; - if (dir > 0) - { + if (dir > 0) { // Iterate subdirs while (vfs_next_dirent(dir, &dent, "/")==0) { - AddObjectType(dent.name); + CStr groupname; + if (base) { + groupname=base; + groupname+='/'; + groupname+=dent.name; + } else { + groupname=dent.name; } - vfs_close_dir(dir); + AddObjectType(groupname); + BuildObjectTypes(groupname); } - else + vfs_close_dir(dir); + } else { LOG(ERROR, LOG_CATEGORY, "CObjectManager::BuildObjectTypes(): Unable to open dir art/actors/"); + } } void CObjectManager::LoadObjects(int type) @@ -129,6 +158,7 @@ void CObjectManager::LoadObjects(int type) LOG(ERROR, LOG_CATEGORY, "CObjectManager::LoadObjects(): %s: XML Load failed", filename.c_str()); delete object; } else { + object->m_FileName=dent.name; AddObject(object,type); LOG(NORMAL, LOG_CATEGORY, "CObjectManager::LoadObjects(): %s: XML Loaded", filename.c_str()); } diff --git a/source/graphics/ObjectManager.h b/source/graphics/ObjectManager.h index 482db763e4..10db4fdc28 100755 --- a/source/graphics/ObjectManager.h +++ b/source/graphics/ObjectManager.h @@ -33,6 +33,7 @@ public: void AddObjectType(const char* name); CObjectEntry* FindObject(const char* objname); + CObjectEntry* FindObjectByFileName(const char* filename); void AddObject(CObjectEntry* entry,int type); void DeleteObject(CObjectEntry* entry); @@ -42,7 +43,7 @@ public: std::vector m_ObjectTypes; private: - void BuildObjectTypes(); + void BuildObjectTypes(const char* basedir); void LoadObjects(int type); CObjectEntry* m_SelectedObject;