2012-04-22 06:04:02 +02:00
|
|
|
/* Copyright (C) 2012 Wildfire Games.
|
2009-04-18 19:00:33 +02:00
|
|
|
* 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/>.
|
|
|
|
*/
|
|
|
|
|
2009-04-18 19:51:05 +02:00
|
|
|
/*
|
|
|
|
* Base class for renderable objects
|
2007-05-07 18:33:24 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef INCLUDED_RENDERABLEOBJECT
|
|
|
|
#define INCLUDED_RENDERABLEOBJECT
|
2004-05-30 02:46:58 +02:00
|
|
|
|
2005-06-28 06:06:25 +02:00
|
|
|
|
2011-11-25 07:36:13 +01:00
|
|
|
#include "maths/BoundingBoxAligned.h"
|
2006-06-02 04:10:27 +02:00
|
|
|
#include "maths/Matrix3D.h"
|
2004-05-30 02:46:58 +02:00
|
|
|
|
|
|
|
|
|
|
|
// 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)
|
2006-02-15 01:45:16 +01:00
|
|
|
#define RENDERDATA_UPDATE_COLOR (1<<4)
|
2004-05-30 02:46:58 +02:00
|
|
|
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
2006-02-15 01:45:16 +01:00
|
|
|
// CRenderData: base class of all the renderer's renderdata classes - the
|
|
|
|
// derived class stores necessary information for rendering an object of a
|
2004-05-30 02:46:58 +02:00
|
|
|
// particular type
|
2006-02-15 01:45:16 +01:00
|
|
|
class CRenderData
|
2004-05-30 02:46:58 +02:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
CRenderData() : m_UpdateFlags(0) {}
|
|
|
|
virtual ~CRenderData() {}
|
|
|
|
|
had to remove uint and ulong from lib/types.h due to conflict with other library.
this snowballed into a massive search+destroy of the hodgepodge of
mostly equivalent types we had in use (int, uint, unsigned, unsigned
int, i32, u32, ulong, uintN).
it is more efficient to use 64-bit types in 64-bit mode, so the
preferred default is size_t (for anything remotely resembling a size or
index). tile coordinates are ssize_t to allow more efficient conversion
to/from floating point. flags are int because we almost never need more
than 15 distinct bits, bit test/set is not slower and int is fastest to
type. finally, some data that is pretty much directly passed to OpenGL
is now typed accordingly.
after several hours, the code now requires fewer casts and less
guesswork.
other changes:
- unit and player IDs now have an "invalid id" constant in the
respective class to avoid casting and -1
- fix some endian/64-bit bugs in the map (un)packing. added a
convenience function to write/read a size_t.
- ia32: change CPUID interface to allow passing in ecx (required for
cache topology detection, which I need at work). remove some unneeded
functions from asm, replace with intrinsics where possible.
This was SVN commit r5942.
2008-05-11 20:48:32 +02:00
|
|
|
int m_UpdateFlags;
|
2004-05-30 02:46:58 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
// CRenderableObject: base class of all renderable objects - patches, models,
|
2006-02-15 01:45:16 +01:00
|
|
|
// sprites, etc; stores position and bound information, and a pointer to
|
2004-05-30 02:46:58 +02:00
|
|
|
// some renderdata necessary for the renderer to actually render it
|
|
|
|
class CRenderableObject
|
|
|
|
{
|
2011-03-13 20:22:05 +01:00
|
|
|
NONCOPYABLE(CRenderableObject);
|
|
|
|
|
2004-05-30 02:46:58 +02:00
|
|
|
public:
|
|
|
|
// constructor
|
2012-04-22 06:04:02 +02:00
|
|
|
CRenderableObject() : m_RenderData(0), m_BoundsValid(false)
|
|
|
|
{
|
2004-05-30 02:46:58 +02:00
|
|
|
m_Transform.SetIdentity();
|
|
|
|
}
|
|
|
|
// destructor
|
|
|
|
virtual ~CRenderableObject() { delete m_RenderData; }
|
|
|
|
|
|
|
|
// set object transform
|
2012-04-22 06:04:02 +02:00
|
|
|
virtual void SetTransform(const CMatrix3D& transform)
|
|
|
|
{
|
2011-03-13 20:22:05 +01:00
|
|
|
if (m_Transform == transform)
|
|
|
|
return;
|
2004-05-30 02:46:58 +02:00
|
|
|
// 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);
|
2005-02-10 00:19:48 +01:00
|
|
|
// need to rebuild world space bounds
|
|
|
|
InvalidateBounds();
|
2004-05-30 02:46:58 +02:00
|
|
|
}
|
|
|
|
// 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
|
2012-04-22 06:04:02 +02:00
|
|
|
void SetDirty(u32 dirtyflags)
|
|
|
|
{
|
|
|
|
if (m_RenderData)
|
|
|
|
m_RenderData->m_UpdateFlags |= dirtyflags;
|
2004-05-30 02:46:58 +02:00
|
|
|
}
|
|
|
|
|
2011-11-25 07:36:13 +01:00
|
|
|
/**
|
|
|
|
* (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
|
|
|
|
*/
|
2005-02-10 00:19:48 +01:00
|
|
|
virtual void CalcBounds() = 0;
|
2004-05-30 02:46:58 +02:00
|
|
|
|
2011-11-25 07:36:13 +01:00
|
|
|
/// Returns the world-space axis-aligned bounds of this object.
|
2012-04-22 06:04:02 +02:00
|
|
|
const CBoundingBoxAligned& GetWorldBounds()
|
|
|
|
{
|
2011-11-25 07:36:13 +01:00
|
|
|
RecalculateBoundsIfNecessary();
|
|
|
|
return m_WorldBounds;
|
2005-02-10 00:19:48 +01:00
|
|
|
}
|
|
|
|
|
2011-11-25 07:36:13 +01:00
|
|
|
/**
|
|
|
|
* 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; }
|
2004-05-30 02:46:58 +02:00
|
|
|
|
2005-10-25 04:00:09 +02:00
|
|
|
// Set the object renderdata and free previous renderdata, if any.
|
2012-04-22 06:04:02 +02:00
|
|
|
void SetRenderData(CRenderData* renderdata)
|
|
|
|
{
|
2005-10-25 04:00:09 +02:00
|
|
|
delete m_RenderData;
|
2006-02-15 01:45:16 +01:00
|
|
|
m_RenderData = renderdata;
|
2004-05-30 02:46:58 +02:00
|
|
|
}
|
|
|
|
|
2011-11-25 07:36:13 +01:00
|
|
|
/// Return object renderdata - can be null if renderer hasn't yet created the renderdata
|
2004-05-30 02:46:58 +02:00
|
|
|
CRenderData* GetRenderData() { return m_RenderData; }
|
|
|
|
|
|
|
|
protected:
|
2011-11-25 07:36:13 +01:00
|
|
|
/// 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;
|
2004-05-30 02:46:58 +02:00
|
|
|
// local->world space transform
|
|
|
|
CMatrix3D m_Transform;
|
|
|
|
// world->local space transform
|
|
|
|
CMatrix3D m_InvTransform;
|
|
|
|
// object renderdata
|
|
|
|
CRenderData* m_RenderData;
|
2005-02-10 00:19:48 +01:00
|
|
|
|
2011-11-25 07:36:13 +01:00
|
|
|
/**
|
|
|
|
* 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
|
|
|
|
*/
|
2005-02-10 00:19:48 +01:00
|
|
|
bool m_BoundsValid;
|
2004-05-30 02:46:58 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
#endif
|