1
0
forked from 0ad/0ad

Allow terrain aligned props. Patch by sanderd17. Fixes #2033.

This was SVN commit r13549.
This commit is contained in:
leper 2013-07-11 22:53:31 +00:00
parent 6cffdacb40
commit d5897854be
8 changed files with 72 additions and 27 deletions

View File

@ -7,9 +7,9 @@
<props>
<prop actor="props/structures/decals/dirt_4x4.xml" attachpoint="root"/>
<prop actor="props/structures/decals/celt_sb1_mud.xml" attachpoint="root"/>
<prop actor="props/structures/persians/stable_horse_a.xml" attachpoint="horsea"/>
<prop actor="props/structures/persians/stable_horse_b.xml" attachpoint="horseb"/>
<prop actor="props/structures/persians/stable_horse_c.xml" attachpoint="horsec"/>
<prop actor="props/structures/persians/stable_horse_a.xml" attachpoint="horsea" minheight="-20" maxheight="1.7"/>
<prop actor="props/structures/persians/stable_horse_b.xml" attachpoint="horseb" minheight="-20" maxheight="1.7"/>
<prop actor="props/structures/persians/stable_horse_c.xml" attachpoint="horsec" minheight="-20" maxheight="1.7"/>
</props>
<textures><texture file="structural/pers_struct.dds" name="baseTex"/></textures>
</variant>

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2012 Wildfire Games.
/* Copyright (C) 2013 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@ -36,13 +36,15 @@
#include "ps/Profile.h"
#include "ps/CLogger.h"
#include "renderer/Renderer.h"
#include "simulation2/Simulation2.h"
#include "simulation2/components/ICmpTerrain.h"
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Constructor
CModel::CModel(CSkeletonAnimManager& skeletonAnimManager)
: m_Flags(0), m_Anim(NULL), m_AnimTime(0),
m_BoneMatrices(NULL),
m_AmmoPropPoint(NULL), m_AmmoLoadedProp(0),
CModel::CModel(CSkeletonAnimManager& skeletonAnimManager, CSimulation2& simulation)
: m_Flags(0), m_Anim(NULL), m_AnimTime(0), m_Simulation(simulation),
m_BoneMatrices(NULL), m_AmmoPropPoint(NULL), m_AmmoLoadedProp(0),
m_SkeletonAnimManager(skeletonAnimManager)
{
}
@ -380,7 +382,8 @@ void CModel::ValidatePosition()
{
const Prop& prop=m_Props[j];
CMatrix3D proptransform = prop.m_Point->m_Transform;;
CMatrix3D proptransform = prop.m_Point->m_Transform;
if (prop.m_Point->m_BoneIndex != 0xff)
{
CMatrix3D boneMatrix = m_BoneMatrices[prop.m_Point->m_BoneIndex];
@ -393,7 +396,26 @@ void CModel::ValidatePosition()
// not relative to any bone; just apply world-space transformation (i.e. relative to object-space origin)
proptransform.Concatenate(m_Transform);
}
// Adjust prop height to terrain level when needed
if (prop.m_maxHeight != 0.f || prop.m_minHeight != 0.f)
{
CVector3D propTranslation = proptransform.GetTranslation();
CVector3D objTranslation = m_Transform.GetTranslation();
CmpPtr<ICmpTerrain> cmpTerrain(m_Simulation, SYSTEM_ENTITY);
if (cmpTerrain)
{
float objTerrain = cmpTerrain->GetExactGroundLevel(objTranslation.X, objTranslation.Z);
float propTerrain = cmpTerrain->GetExactGroundLevel(propTranslation.X, propTranslation.Z);
float translateHeight = std::min(prop.m_maxHeigth,
std::max(prop.m_minHeight, propTerrain - objTerrain));
CMatrix3D translate = CMatrix3D();
translate.SetTranslation(0.f, translateHeight, 0.f);
proptransform.Concatenate(translate);
}
}
prop.m_Model->SetTransform(proptransform);
prop.m_Model->ValidatePosition();
}
@ -484,7 +506,7 @@ void CModel::CopyAnimationFrom(CModel* source)
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// AddProp: add a prop to the model on the given point
void CModel::AddProp(const SPropPoint* point, CModelAbstract* model, CObjectEntry* objectentry)
void CModel::AddProp(const SPropPoint* point, CModelAbstract* model, CObjectEntry* objectentry, float minHeight, float maxHeight)
{
// position model according to prop point position
@ -496,6 +518,8 @@ void CModel::AddProp(const SPropPoint* point, CModelAbstract* model, CObjectEntr
prop.m_Point = point;
prop.m_Model = model;
prop.m_ObjectEntry = objectentry;
prop.m_minHeight = minHeight;
prop.m_maxHeight = maxHeight;
m_Props.push_back(prop);
}
@ -564,7 +588,7 @@ CModelAbstract* CModel::FindFirstAmmoProp()
// Clone: return a clone of this model
CModelAbstract* CModel::Clone() const
{
CModel* clone = new CModel(m_SkeletonAnimManager);
CModel* clone = new CModel(m_SkeletonAnimManager, m_Simulation);
clone->m_ObjectBounds = m_ObjectBounds;
clone->InitModel(m_pModelDef);
clone->SetMaterial(m_Material);
@ -577,7 +601,7 @@ CModelAbstract* CModel::Clone() const
if (m_AmmoPropPoint && i == m_AmmoLoadedProp)
clone->AddAmmoProp(m_Props[i].m_Point, m_Props[i].m_Model->Clone(), m_Props[i].m_ObjectEntry);
else
clone->AddProp(m_Props[i].m_Point, m_Props[i].m_Model->Clone(), m_Props[i].m_ObjectEntry);
clone->AddProp(m_Props[i].m_Point, m_Props[i].m_Model->Clone(), m_Props[i].m_ObjectEntry, m_Props[i].m_minHeight, m_Props[i].m_maxHeight);
}
return clone;

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2011 Wildfire Games.
/* Copyright (C) 2013 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@ -35,6 +35,7 @@ class CObjectEntry;
class CSkeletonAnim;
class CSkeletonAnimDef;
class CSkeletonAnimManager;
class CSimulation2;
#define MODELFLAG_CASTSHADOWS (1<<0)
#define MODELFLAG_NOLOOPANIMATION (1<<1)
@ -55,6 +56,9 @@ public:
{
Prop() : m_Point(0), m_Model(0), m_ObjectEntry(0), m_Hidden(false) {}
float m_minHeight;
float m_maxHeight;
/**
* Location of the prop point within its parent model, relative to either a bone in the parent model or to the
* parent model's origin. See the documentation for @ref SPropPoint for more details.
@ -75,10 +79,11 @@ public:
public:
// constructor
CModel(CSkeletonAnimManager& skeletonAnimManager);
CModel(CSkeletonAnimManager& skeletonAnimManager, CSimulation2& simulation);
// destructor
~CModel();
/// Dynamic cast
virtual CModel* ToCModel()
{
@ -205,7 +210,7 @@ public:
/**
* Add a prop to the model on the given point.
*/
void AddProp(const SPropPoint* point, CModelAbstract* model, CObjectEntry* objectentry);
void AddProp(const SPropPoint* point, CModelAbstract* model, CObjectEntry* objectentry, float minHeight = 0.f, float maxHeight = 0.f);
/**
* Add a prop to the model on the given point, and treat it as the ammo prop.
@ -250,6 +255,9 @@ public:
private:
// delete anything allocated by the model
void ReleaseData();
// Needed for terrain aligned props
CSimulation2& m_Simulation;
// object flags
int m_Flags;

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2012 Wildfire Games.
/* Copyright (C) 2013 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@ -80,6 +80,8 @@ bool CObjectBase::Load(const VfsPath& pathname)
AT(angle);
AT(offsetx);
AT(offsetz);
AT(minheight);
AT(maxheight);
#undef AT
#undef EL
@ -246,6 +248,10 @@ bool CObjectBase::Load(const VfsPath& pathname)
prop.m_PropPointName = pe.Value;
else if (pe.Name == at_actor)
prop.m_ModelName = pe.Value.FromUTF8();
else if (pe.Name == at_minheight)
prop.m_minHeight = pe.Value.ToFloat();
else if (pe.Name == at_maxheight)
prop.m_maxHeight = pe.Value.ToFloat();
}
currentVariant->m_Props.push_back(prop);
}

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2012 Wildfire Games.
/* Copyright (C) 2013 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@ -59,6 +59,9 @@ public:
CStr m_PropPointName;
// name of the model file - art/actors/props/sword.xml or whatever
CStrW m_ModelName;
// allow the prop to ajust the height from minHeight to maxHeight relative to the main model
float m_minHeight;
float m_maxHeight;
};
struct Samp

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2011 Wildfire Games.
/* Copyright (C) 2013 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@ -35,11 +35,12 @@
#include "ps/Game.h"
#include "ps/World.h"
#include "renderer/Renderer.h"
#include "simulation2/Simulation2.h"
#include <sstream>
CObjectEntry::CObjectEntry(CObjectBase* base) :
m_Base(base), m_Color(1.0f, 1.0f, 1.0f, 1.0f), m_Model(NULL), m_Outdated(false)
CObjectEntry::CObjectEntry(CObjectBase* base, CSimulation2& simulation) :
m_Base(base), m_Color(1.0f, 1.0f, 1.0f, 1.0f), m_Model(NULL), m_Outdated(false), m_Simulation(simulation)
{
}
@ -123,7 +124,7 @@ bool CObjectEntry::BuildVariation(const std::vector<std::set<CStr> >& selections
}
// delete old model, create new
CModel* model = new CModel(objectManager.GetSkeletonAnimManager());
CModel* model = new CModel(objectManager.GetSkeletonAnimManager(), m_Simulation);
delete m_Model;
m_Model = model;
model->SetMaterial(g_Renderer.GetMaterialManager().LoadMaterial(m_Base->m_Material));
@ -234,7 +235,7 @@ bool CObjectEntry::BuildVariation(const std::vector<std::set<CStr> >& selections
if (isAmmo)
model->AddAmmoProp(proppoint, propmodel, oe);
else
model->AddProp(proppoint, propmodel, oe);
model->AddProp(proppoint, propmodel, oe, prop.m_minHeight, prop.m_maxHeight);
if (propmodel->ToCModel())
propmodel->ToCModel()->SetAnimation(oe->GetRandomAnimation("idle"));
}

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2011 Wildfire Games.
/* Copyright (C) 2013 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@ -22,6 +22,7 @@ class CModelAbstract;
class CSkeletonAnim;
class CObjectBase;
class CObjectManager;
class CSimulation2;
struct SPropPoint;
#include <map>
@ -37,7 +38,7 @@ struct SPropPoint;
class CObjectEntry
{
public:
CObjectEntry(CObjectBase* base);
CObjectEntry(CObjectBase* base, CSimulation2& simulation);
~CObjectEntry();
// Construct this actor, using the specified variation selections
@ -75,6 +76,8 @@ public:
bool m_Outdated;
private:
CSimulation2& m_Simulation;
typedef std::multimap<CStr, CSkeletonAnim*> SkeletonAnimMap;
SkeletonAnimMap m_Animations;
// TODO: something more memory-efficient than storing loads of similar strings for each unit?

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2012 Wildfire Games.
/* Copyright (C) 2013 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@ -139,7 +139,7 @@ CObjectEntry* CObjectManager::FindObjectVariation(CObjectBase* base, const std::
// makes more sense (e.g. use shared_ptr); for now I'll just leak, to avoid making the logic
// more complex than it is already is, since this only matters for the rare case of hotloading.
CObjectEntry* obj = new CObjectEntry(base); // TODO: type ?
CObjectEntry* obj = new CObjectEntry(base, m_Simulation); // TODO: type ?
// TODO (for some efficiency): use the pre-calculated choices for this object,
// which has already worked out what to do for props, instead of passing the