[Gameplay] Reduce loom cost
[0ad.git] / source / graphics / ModelAbstract.h
blob6c9b897452a41058e6de6254470769b145ce1a77
1 /* Copyright (C) 2023 Wildfire Games.
2 * This file is part of 0 A.D.
4 * 0 A.D. is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 2 of the License, or
7 * (at your option) any later version.
9 * 0 A.D. is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
18 #ifndef INCLUDED_MODELABSTRACT
19 #define INCLUDED_MODELABSTRACT
21 #include "graphics/Color.h"
22 #include "graphics/RenderableObject.h"
23 #include "maths/BoundingBoxOriented.h"
24 #include "simulation2/helpers/Player.h"
26 #include <memory>
28 class CModelDummy;
29 class CModel;
30 class CModelDecal;
31 class CModelParticleEmitter;
33 /**
34 * Abstract base class for graphical objects that are used by units,
35 * or as props attached to other CModelAbstract objects.
36 * This includes meshes, terrain decals, and sprites.
37 * These objects exist in a tree hierarchy.
39 class CModelAbstract : public CRenderableObject
41 NONCOPYABLE(CModelAbstract);
43 public:
45 /**
46 * Describes a custom selection shape to be used for a model's selection box instead of the default
47 * recursive bounding boxes.
49 struct CustomSelectionShape
51 enum EType {
52 /// The selection shape is determined by an oriented box of custom, user-specified size.
53 BOX,
54 /// The selection shape is determined by a cylinder of custom, user-specified size.
55 CYLINDER
58 EType m_Type; ///< Type of shape.
59 float m_Size0; ///< Box width if @ref BOX, or radius if @ref CYLINDER
60 float m_Size1; ///< Box depth if @ref BOX, or radius if @ref CYLINDER
61 float m_Height; ///< Box height if @ref BOX, cylinder height if @ref CYLINDER
64 public:
66 CModelAbstract()
67 : m_Parent(NULL), m_PositionValid(false), m_ShadingColor(1, 1, 1, 1), m_PlayerID(INVALID_PLAYER),
68 m_SelectionBoxValid(false), m_CustomSelectionShape(NULL)
69 { }
71 ~CModelAbstract()
73 delete m_CustomSelectionShape; // allocated and set externally by CCmpVisualActor, but our responsibility to clean up
76 virtual std::unique_ptr<CModelAbstract> Clone() const = 0;
78 /// Dynamic cast
79 virtual CModelDummy* ToCModelDummy() { return nullptr; }
81 /// Dynamic cast
82 virtual CModel* ToCModel() { return nullptr; }
84 /// Dynamic cast
85 virtual CModelDecal* ToCModelDecal() { return nullptr; }
87 /// Dynamic cast
88 virtual CModelParticleEmitter* ToCModelParticleEmitter() { return nullptr; }
90 // (This dynamic casting is a bit ugly, but we won't have many subclasses
91 // and this seems the easiest way to integrate with other code that wants
92 // type-specific processing)
94 /// Returns world space bounds of this object and all child objects.
95 virtual const CBoundingBoxAligned GetWorldBoundsRec() { return GetWorldBounds(); } // default implementation
97 /**
98 * Returns the world-space selection box of this model. Used primarily for hittesting against against a selection ray. The
99 * returned selection box may be empty to indicate that it does not wish to participate in the selection process.
101 virtual const CBoundingBoxOriented& GetSelectionBox();
103 virtual void InvalidateBounds()
105 m_BoundsValid = false;
106 // a call to this method usually means that the model's transform has changed, i.e. it has moved or rotated, so we'll also
107 // want to update the selection box accordingly regardless of the shape it is built from.
108 m_SelectionBoxValid = false;
111 /// Sets a custom selection shape as described by a @p descriptor. Argument may be NULL
112 /// if you wish to keep the default behaviour of using the recursively-calculated bounding boxes.
113 void SetCustomSelectionShape(CustomSelectionShape* descriptor)
115 if (m_CustomSelectionShape != descriptor)
117 m_CustomSelectionShape = descriptor;
118 m_SelectionBoxValid = false; // update the selection box when it is next requested
123 * Returns the (object-space) bounds that should be used to construct a selection box for this model and its children.
124 * May return an empty bound to indicate that this model and its children should not be selectable themselves, or should
125 * not be included in its parent model's selection box. This method is used for constructing the default selection boxes,
126 * as opposed to any boxes of custom shape specified by @ref m_CustomSelectionShape.
128 * If you wish your model type to be included in selection boxes, override this method and have it return the object-space
129 * bounds of itself, augmented recursively (via this method) with the object-space selection bounds of its children.
131 virtual const CBoundingBoxAligned GetObjectSelectionBoundsRec() { return CBoundingBoxAligned::EMPTY; }
134 * Called when terrain has changed in the given inclusive bounds.
135 * Might call SetDirty if the change affects this model.
137 virtual void SetTerrainDirty(ssize_t i0, ssize_t j0, ssize_t i1, ssize_t j1) = 0;
140 * Called when the entity tries to set some variable to affect the display of this model
141 * and/or its child objects.
143 virtual void SetEntityVariable(const std::string& UNUSED(name), float UNUSED(value)) { }
146 * Ensure that both the transformation and the bone matrices are correct for this model and all its props.
148 virtual void ValidatePosition() = 0;
151 * Mark this model's position and bone matrices, and all props' positions as invalid.
153 virtual void InvalidatePosition() = 0;
155 virtual void SetPlayerID(player_id_t id) { m_PlayerID = id; }
157 // get the model's player ID; initial default is INVALID_PLAYER
158 virtual player_id_t GetPlayerID() const { return m_PlayerID; }
160 virtual void SetShadingColor(const CColor& color) { m_ShadingColor = color; }
161 virtual const CColor& GetShadingColor() const { return m_ShadingColor; }
163 protected:
164 void CalcSelectionBox();
166 public:
167 /// If non-null, points to the model that we are attached to.
168 CModelAbstract* m_Parent;
170 /// True if both transform and and bone matrices are valid.
171 bool m_PositionValid;
173 player_id_t m_PlayerID;
175 /// Modulating color
176 CColor m_ShadingColor;
178 protected:
180 /// Selection box for this model.
181 CBoundingBoxOriented m_SelectionBox;
183 /// Is the current selection box valid?
184 bool m_SelectionBoxValid;
186 /// Pointer to a descriptor for a custom-defined selection box shape. If no custom selection box is required, this is NULL
187 /// and the standard recursive-bounding-box-based selection box is used. Otherwise, a custom selection box described by this
188 /// field will be used.
189 /// @see SetCustomSelectionShape
190 CustomSelectionShape* m_CustomSelectionShape;
194 #endif // INCLUDED_MODELABSTRACT