forked from 0ad/0ad
164 lines
5.5 KiB
C++
164 lines
5.5 KiB
C++
/* Copyright (C) 2012 Wildfire Games.
|
|
* This file is part of 0 A.D.
|
|
*
|
|
* 0 A.D. is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* 0 A.D. is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
/*
|
|
* Base class for renderable objects
|
|
*/
|
|
|
|
#ifndef INCLUDED_RENDERABLEOBJECT
|
|
#define INCLUDED_RENDERABLEOBJECT
|
|
|
|
|
|
#include "maths/BoundingBoxAligned.h"
|
|
#include "maths/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)
|
|
#define RENDERDATA_UPDATE_COLOR (1<<4)
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// 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() {}
|
|
|
|
int 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
|
|
{
|
|
NONCOPYABLE(CRenderableObject);
|
|
|
|
public:
|
|
// constructor
|
|
CRenderableObject() : m_RenderData(0), m_BoundsValid(false)
|
|
{
|
|
m_Transform.SetIdentity();
|
|
}
|
|
// destructor
|
|
virtual ~CRenderableObject() { delete m_RenderData; }
|
|
|
|
// set object transform
|
|
virtual void SetTransform(const CMatrix3D& transform)
|
|
{
|
|
if (m_Transform == transform)
|
|
return;
|
|
// store transform, calculate inverse
|
|
m_Transform=transform;
|
|
m_Transform.GetInverse(m_InvTransform);
|
|
// normal recalculation likely required on transform change; flag it
|
|
SetDirty(RENDERDATA_UPDATE_VERTICES);
|
|
// need to rebuild world space bounds
|
|
InvalidateBounds();
|
|
}
|
|
// get object to world space transform
|
|
const CMatrix3D& GetTransform() const { return m_Transform; }
|
|
// get world to object space transform
|
|
const CMatrix3D& GetInvTransform() const { return m_InvTransform; }
|
|
|
|
// 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;
|
|
}
|
|
|
|
/**
|
|
* (Re)calculates and stores any bounds or bound-dependent data for this object. At this abstraction level, this is only the world-space
|
|
* bounds stored in @ref m_WorldBounds; subclasses may use this method to (re)compute additional bounds if necessary, or any data that
|
|
* depends on the bounds. Whenever bound-dependent data is requested through a public interface, @ref RecalculateBoundsIfNecessary should
|
|
* be called first to ensure bound correctness, which will in turn call this method if it turns out that they're outdated.
|
|
*
|
|
* @see m_BoundsValid
|
|
* @see RecalculateBoundsIfNecessary
|
|
*/
|
|
virtual void CalcBounds() = 0;
|
|
|
|
/// Returns the world-space axis-aligned bounds of this object.
|
|
const CBoundingBoxAligned& GetWorldBounds()
|
|
{
|
|
RecalculateBoundsIfNecessary();
|
|
return m_WorldBounds;
|
|
}
|
|
|
|
/**
|
|
* Marks the bounds as invalid. This will trigger @ref RecalculateBoundsIfNecessary to recompute any bound-related data the next time
|
|
* any bound-related data is requested through a public interface -- at least, if you've made sure to call it before returning the
|
|
* stored data.
|
|
*/
|
|
virtual void InvalidateBounds() { m_BoundsValid = false; }
|
|
|
|
// Set the object renderdata and free previous renderdata, if any.
|
|
void SetRenderData(CRenderData* renderdata)
|
|
{
|
|
delete m_RenderData;
|
|
m_RenderData = renderdata;
|
|
}
|
|
|
|
/// Return object renderdata - can be null if renderer hasn't yet created the renderdata
|
|
CRenderData* GetRenderData() { return m_RenderData; }
|
|
|
|
protected:
|
|
/// Factored out so subclasses don't need to repeat this if they want to add additional getters for bounds-related methods
|
|
/// (since they'll have to make sure to recalc the bounds if necessary before they return it).
|
|
void RecalculateBoundsIfNecessary()
|
|
{
|
|
if (!m_BoundsValid) {
|
|
CalcBounds();
|
|
m_BoundsValid = true;
|
|
}
|
|
}
|
|
|
|
protected:
|
|
/// World-space bounds of this object
|
|
CBoundingBoxAligned m_WorldBounds;
|
|
// local->world space transform
|
|
CMatrix3D m_Transform;
|
|
// world->local space transform
|
|
CMatrix3D m_InvTransform;
|
|
// object renderdata
|
|
CRenderData* m_RenderData;
|
|
|
|
/**
|
|
* Remembers whether any bounds need to be recalculated. Subclasses that add any data that depends on the bounds should
|
|
* take care to consider the validity of the bounds and recalculate their data when necessary -- overriding @ref CalcBounds
|
|
* to do so would be a good idea, since it's already set up to be called by @ref RecalculateBoundsIfNecessary whenever the
|
|
* bounds are marked as invalid. The latter should then be called before returning any bounds or bounds-derived data through
|
|
* a public interface (see the implementation of @ref GetWorldBounds for an example).
|
|
*
|
|
* @see CalcBounds
|
|
* @see InvalidateBounds
|
|
* @see RecalculateBoundsIfNecessary
|
|
*/
|
|
bool m_BoundsValid;
|
|
};
|
|
|
|
#endif
|