1
0
forked from 0ad/0ad

Optimised game-loading, by not reading terrain textures or calculating bounding boxes when not necessary; maps load about twenty seconds faster (at least in Debug mode). Also fixed possible minor bug (FLT_MIN vs -FLT_MAX) and other trivial things.

This was SVN commit r1917.
This commit is contained in:
Ykkrosh 2005-02-09 23:19:48 +00:00
parent 614e523c89
commit 3b1395d80b
14 changed files with 175 additions and 154 deletions

View File

@ -125,6 +125,17 @@ static CVector3D SkinPoint(const CVector3D& pos,const SVertexBlend& blend,
// CalcBound: calculate the world space bounds of this model
void CModel::CalcBounds()
{
// Need to calculate the object bounds first, if that hasn't already been done
if (! m_Anim)
CalcObjectBounds();
else
{
if (m_Anim->m_ObjectBounds.IsEmpty())
CalcAnimatedObjectBound(m_Anim->m_AnimDef, m_Anim->m_ObjectBounds);
assert(! m_Anim->m_ObjectBounds.IsEmpty()); // (if this happens, it'll be recalculating the bounds every time)
m_ObjectBounds = m_Anim->m_ObjectBounds;
}
m_ObjectBounds.Transform(GetTransform(),m_Bounds);
}
@ -148,13 +159,24 @@ void CModel::CalcAnimatedObjectBound(CSkeletonAnimDef* anim,CBound& result)
{
result.SetEmpty();
// Set the current animation on which to perform calculations (if it's necessary)
if (anim != m_Anim->m_AnimDef)
{
CSkeletonAnim dummyanim;
dummyanim.m_AnimDef=anim;
if (!SetAnimation(&dummyanim)) return;
}
int numverts=m_pModelDef->GetNumVertices();
SModelVertex* verts=m_pModelDef->GetVertices();
// Remove any transformations, so that we calculate the bounding box
// at the origin. The box is later re-transformed onto the object, without
// having to recalculate the size of the box.
CMatrix3D transform, oldtransform = GetTransform();
transform.SetIdentity();
SetTransform(transform);
// iterate through every frame of the animation
for (uint j=0;j<anim->GetNumFrames();j++) {
// extend bounds by vertex positions at the frame
@ -166,6 +188,8 @@ void CModel::CalcAnimatedObjectBound(CSkeletonAnimDef* anim,CBound& result)
m_AnimTime+=anim->GetFrameTime();
m_BoneMatricesValid=false;
}
SetTransform(oldtransform);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -179,7 +203,8 @@ CSkeletonAnim* CModel::BuildAnimation(const char* filename,float speed)
CSkeletonAnim* anim=new CSkeletonAnim;
anim->m_AnimDef=def;
anim->m_Speed=speed;
CalcAnimatedObjectBound(def,anim->m_ObjectBounds);
anim->m_ObjectBounds.SetEmpty();
InvalidateBounds();
return anim;
}
@ -268,13 +293,15 @@ bool CModel::SetAnimation(CSkeletonAnim* anim, bool once)
return false;
}
if (anim->m_AnimDef->GetNumKeys()!=m_pModelDef->GetNumBones()) {
// mismatch between models skeleton and animations skeleton
if (m_Anim->m_AnimDef->GetNumKeys()!=m_pModelDef->GetNumBones()) {
// mismatch between model's skeleton and animation's skeleton
return false;
}
// update object bounds to the bounds when given animation applied
m_ObjectBounds=m_Anim->m_ObjectBounds;
// reset the cached bounds when the animation is changed
m_ObjectBounds.SetEmpty();
InvalidateBounds();
// start anim from beginning
m_AnimTime=0;
}
@ -348,6 +375,7 @@ void CModel::SetTransform(const CMatrix3D& transform)
// call base class to set transform on this object
CRenderableObject::SetTransform(transform);
m_BoneMatricesValid=false;
InvalidateBounds();
// now set transforms on props
const CMatrix3D* bonematrices=GetBoneMatrices();

View File

@ -85,8 +85,6 @@ public:
void CalcObjectBounds();
// calculate bounds encompassing all vertex positions for given animation
void CalcAnimatedObjectBound(CSkeletonAnimDef* anim,CBound& result);
// return object space bounds
const CBound& GetObjectBounds() const { return m_ObjectBounds; }
// set transform of this object, and recurse down into props to update their world space transform
void SetTransform(const CMatrix3D& transform);
@ -134,7 +132,8 @@ private:
// pointer to the model's raw 3d data
CModelDefPtr m_pModelDef;
// object space bounds of model - accounts for bounds of all possible animations
// that can play on a model
// that can play on a model. Not always up-to-date - currently CalcBounds()
// updates it when necessary.
CBound m_ObjectBounds;
// animation currently playing on this model, if any
CSkeletonAnim* m_Anim;

View File

@ -135,9 +135,6 @@ bool CObjectEntry::BuildModel()
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<CUnit*>& units=g_UnitMan.GetUnits();

View File

@ -42,7 +42,7 @@ void CPatch::Initialize(CTerrain* parent,u32 x,u32 z)
}
}
CalcBounds();
InvalidateBounds();
}
///////////////////////////////////////////////////////////////////////////////

View File

@ -42,7 +42,7 @@ class CRenderableObject
{
public:
// constructor
CRenderableObject() : m_RenderData(0) {
CRenderableObject() : m_RenderData(0), m_BoundsValid(false) {
m_Transform.SetIdentity();
}
// destructor
@ -55,8 +55,8 @@ public:
m_Transform.GetInverse(m_InvTransform);
// normal recalculation likely required on transform change; flag it
SetDirty(RENDERDATA_UPDATE_VERTICES);
// rebuild world space bounds
CalcBounds();
// need to rebuild world space bounds
InvalidateBounds();
}
// get object to world space transform
const CMatrix3D& GetTransform() const { return m_Transform; }
@ -74,7 +74,15 @@ public:
virtual void CalcBounds() = 0;
// return world space bounds of this object
const CBound& GetBounds() const { return m_Bounds; }
const CBound& GetBounds() {
if (! m_BoundsValid) {
CalcBounds();
m_BoundsValid = true;
}
return m_Bounds;
}
void InvalidateBounds() { m_BoundsValid = false; }
// set the object renderdata
// TODO,RC 10/04/04 - need to delete existing renderdata here, or can we
@ -98,6 +106,10 @@ protected:
CMatrix3D m_InvTransform;
// object renderdata
CRenderData* m_RenderData;
private:
// remembers whether m_bounds needs to be recalculated
bool m_BoundsValid;
};
#endif

View File

@ -326,7 +326,7 @@ void CTerrain::SetHeightMap(u16* heightmap)
for (u32 j=0;j<m_MapSizePatches;j++) {
for (u32 i=0;i<m_MapSizePatches;i++) {
CPatch* patch=GetPatch(i,j);
patch->CalcBounds();
patch->InvalidateBounds();
patch->SetDirty(RENDERDATA_UPDATE_VERTICES);
}
}

View File

@ -34,6 +34,9 @@ public:
// accessor - return texture type
int GetType() const { return m_Type; }
// returns whether this texture-entry has loaded any data yet
bool IsLoaded() { return (m_Handle!=-1); }
private:
// load texture from file
void LoadTexture();

View File

@ -57,7 +57,11 @@ CTextureEntry* CTextureManager::FindTexture(Handle handle)
for (uint k=0;k<m_TerrainTextures.size();k++) {
STextureType& ttype=m_TerrainTextures[k];
for (uint i=0;i<ttype.m_Textures.size();i++) {
if (handle==ttype.m_Textures[i]->GetHandle()) {
// Don't bother looking at textures that haven't been loaded yet - since
// the caller has given us a Handle to the texture, it must be loaded.
// (This matters because GetHandle would load the texture, even though
// there's no need to.)
if (ttype.m_Textures[i]->IsLoaded() && handle==ttype.m_Textures[i]->GetHandle()) {
return ttype.m_Textures[i];
}
}

View File

@ -56,7 +56,7 @@ bool CBound::RayIntersect(const CVector3D& origin,const CVector3D& dir,
if (origin[0]<m_Data[0][0] || origin[0]>m_Data[1][0])
return false;
else {
tnear=(float) FLT_MIN;
tnear=(float) -FLT_MAX;
tfar=(float) FLT_MAX;
}
} else {
@ -129,8 +129,16 @@ bool CBound::RayIntersect(const CVector3D& origin,const CVector3D& dir,
// 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);
m_Data[0]=CVector3D( FLT_MAX, FLT_MAX, FLT_MAX);
m_Data[1]=CVector3D(-FLT_MAX,-FLT_MAX,-FLT_MAX);
}
///////////////////////////////////////////////////////////////////////////////
// IsEmpty: tests whether this bound is empty
bool CBound::IsEmpty()
{
return (m_Data[0].X == FLT_MAX && m_Data[0].Y == FLT_MAX && m_Data[0].Z == FLT_MAX
&& m_Data[1].X == -FLT_MAX && m_Data[1].Y == -FLT_MAX && m_Data[1].Z == -FLT_MAX);
}
///////////////////////////////////////////////////////////////////////////////

View File

@ -29,6 +29,7 @@ public:
const CVector3D& operator[](int index) const { return m_Data[index]; }
void SetEmpty();
bool IsEmpty();
CBound& operator+=(const CBound& b);
CBound& operator+=(const CVector3D& pt);

View File

@ -13,13 +13,6 @@
#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 ||
@ -34,13 +27,7 @@ int CVector3D::operator ! () const
//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;
return CVector3D(X+vector.X, Y+vector.Y, Z+vector.Z);
}
//vector addition/assignment
@ -56,25 +43,13 @@ CVector3D &CVector3D::operator += (const CVector3D &vector)
//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;
return CVector3D(X-vector.X, Y-vector.Y, Z-vector.Z);
}
//vector negation
CVector3D CVector3D::operator-() const
{
CVector3D Temp;
Temp.X = -X;
Temp.Y = -Y;
Temp.Z = -Z;
return Temp;
return CVector3D(-X, -Y, -Z);
}
//vector subtrcation/assignment
CVector3D &CVector3D::operator -= (const CVector3D &vector)
@ -89,13 +64,7 @@ CVector3D &CVector3D::operator -= (const CVector3D &vector)
//scalar multiplication
CVector3D CVector3D::operator * (float value) const
{
CVector3D Temp;
Temp.X = X * value;
Temp.Y = Y * value;
Temp.Z = Z * value;
return Temp;
return CVector3D(X*value, Y*value, Z*value);
}
//scalar multiplication/assignment

View File

@ -22,8 +22,8 @@ class CVector3D
float X, Y, Z;
public:
CVector3D () { X = 0.0f; Y = 0.0f; Z = 0.0f; }
CVector3D (float x, float y, float z);
CVector3D () : X(0.0f), Y(0.0f), Z(0.0f) {}
CVector3D (float x, float y, float z) : X(x), Y(y), Z(z) {}
int operator!() const;

View File

@ -44,7 +44,7 @@ void CModelRData::Build()
// build data
BuildVertices();
BuildIndices();
// force a texture load on models texture
// force a texture load on model's texture
g_Renderer.LoadTexture(m_Model->GetTexture(),GL_CLAMP_TO_EDGE);
// setup model render flags
/*if (g_Renderer.IsTextureTransparent(m_Model->GetTexture())) {

View File

@ -47,7 +47,7 @@ bool sparsePathTree::slice()
if( len == 0.0f )
{
// Too wierd. (Heavy traffic, obstacles in positions leading to this degenerate state.
// Too weird. (Heavy traffic, obstacles in positions leading to this degenerate state.
type = SPF_IMPOSSIBLE;
return( true );
}