-
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathObject.hpp
More file actions
222 lines (192 loc) · 10.1 KB
/
Object.hpp
File metadata and controls
222 lines (192 loc) · 10.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
#ifndef OBJECT_HPP
#define OBJECT_HPP
#include <vector>
#include <cstdint>
#include "Texture.hpp"
#include "Material.hpp"
#include "Shader.hpp"
namespace Renderer {
/// @brief Triangle culling mode for an Object.
enum class CullingMode {
CULL_BACKFACES, ///< Cull triangles facing away from the camera.
CULL_FRONTFACES, ///< Cull triangles facing the camera.
NO_CULLING, ///< Draw both winding orders.
};
/// @brief Per-pixel blend mode applied when writing this object to the framebuffer.
enum class BlendMode {
BLEND_REPLACE, ///< Overwrite destination.
BLEND_ADD, ///< Saturating add.
BLEND_SUBTRACT, ///< Saturating subtract.
BLEND_SCALE, ///< Multiply destination by source.
BLEND_AVERAGE, ///< Average source and destination.
BLEND_XOR, ///< Bitwise XOR.
};
/// @brief Renderable mesh: vertices, triangles, transform, render flags and per-object fade bands.
class Object {
public:
/// @brief Single triangle indexing into the parent Object's `vertices`.
struct Triangle {
uint16_t v1, v2, v3; ///< Vertex indices.
Material* material; ///< Material applied to this face.
};
/// @brief Single mesh vertex.
struct Vertex {
Vector3 position = {0,0,0}; ///< World-local position.
Vector2 uv = {0,0}; ///< Texture coordinates.
Vector3 normal = {0,0,0}; ///< Normal vector.
uint16_t color = 0x0000; ///< Per-vertex colour (RGB565).
};
std::vector<Vertex> vertices; ///< Mesh vertices.
std::vector<int> indices; ///< Index buffer (unused by the default rasteriser).
std::vector<Triangle> triangles; ///< Mesh triangles.
Vector3 boundingBoxMin = {0,0,0}; ///< Local-space AABB minimum (recomputed by calculateBoundingBox).
Vector3 boundingBoxMax = {0,0,0}; ///< Local-space AABB maximum.
Vector3 centreVolume = {0,0,0}; ///< Local-space AABB centre.
Vector3 rotation = {0,0,0}; ///< Euler rotation in degrees.
Vector3 position = {0,0,0}; ///< World-space position.
Vector3 scale = {FIXED_POINT_SCALE, FIXED_POINT_SCALE, FIXED_POINT_SCALE}; ///< Per-axis scale (FIXED_POINT_SCALE = 1.0).
CullingMode cullingMode = CullingMode::CULL_BACKFACES; ///< Triangle culling mode.
BlendMode blendMode = BlendMode::BLEND_REPLACE; ///< Blend mode.
bool isBillboard = false; ///< When true, the object is auto-rotated to face the camera.
bool ignoreZBuffer = false; ///< When true, depth test is skipped (always passes).
bool noWriteZBuffer = false; ///< When true, depth is not written.
/// @brief Depth bias applied at raster time in z-buffer units.
///
/// Positive values pull the surface toward the camera for both the Z
/// test and the Z write, so a biased surface wins depth fights against
/// coplanar or near-coplanar geometry but still loses to anything
/// genuinely closer. Use for decals / shadows / ground markings sitting
/// just above another surface. Small values (1..8) are typical;
/// 0 disables.
int8_t zBias = 0;
bool transformScale = false; ///< When true, scale is included in the world transform; otherwise scale is baked-in.
bool enabled = true; ///< When false, the object is skipped entirely.
/// @brief Distance at which the object starts fading out (world units, 0 disables).
///
/// When the camera is between `fadeNear` and `fadeFar` from
/// (position + centreVolume), the object is drawn with a screen-door
/// alpha that ramps linearly from 255 at fadeNear to 0 at fadeFar.
/// Beyond fadeFar the object is skipped entirely. Both default to 0
/// (disabled); the global depth fog still applies independently.
int32_t fadeNear = 0;
/// @brief Distance at which the object becomes fully transparent / culled (paired with fadeNear).
int32_t fadeFar = 0;
/// @brief Distance at which the object starts fading in (LOD pop-in, 0 disables).
///
/// Inverse of fadeNear/fadeFar: invisible when closer than `appearNear`,
/// fades in linearly between `appearNear` and `appearFar`, fully visible
/// beyond `appearFar`. Pair with a high-detail object using matching
/// fadeNear/fadeFar to get a screen-door dissolve LOD swap.
int32_t appearNear = 0;
/// @brief Distance at which the object is fully visible (paired with appearNear).
int32_t appearFar = 0;
/// @name Distance-based level of detail (LOD)
///
/// Optional alternative meshes used when this object is far from the
/// camera. The head Object IS LOD 0; entries in `lodMeshes` are LOD 1,
/// 2, ... in order. The Scene picks a level per frame based on the
/// head's distance to the camera and a Scene-wide `lodScale`:
/// level = max(0, distance / lodScale + sceneLodBias + lodBias)
/// The Scene then uses `lodMeshes[level - 1]` for the mesh data
/// (vertices + triangles) while keeping THIS object's transform,
/// flags, AABB, fade ramps, etc. — i.e. the LOD entries are pure mesh
/// substitutions.
///
/// LOD entries are typically authored as separate Objects with
/// `enabled = false` (so they don't render independently) and held
/// either in the Scene or in user-side storage; the head only borrows
/// their pointers.
///
/// When the chosen level exceeds the available LODs, behaviour is
/// controlled by `lodPersist`: if true (the default), the object
/// keeps drawing using the lowest-detail mesh available — or, if
/// no LOD chain was provided at all, the head mesh itself. This
/// makes "stay visible" the default so simply enabling Scene LOD
/// doesn't quietly delete distant geometry the author never wired
/// LODs for. Set to false on foliage / minor scenery that should
/// drop out past the configured range.
/// @{
std::vector<Object*> lodMeshes; ///< Reduced-detail alternatives; index 0 = LOD 1.
int8_t lodBias = 0; ///< Per-object LOD level bias (negative = use higher detail).
bool lodPersist = true; ///< When true (default), clamp to the last LOD instead of culling.
/// @}
/// @brief Construct an empty object.
Object();
/// @brief Append a vertex to the mesh.
/// @param vertex Vertex to append.
void addVertex(const Vertex& vertex);
/// @brief Append a triangle indexing existing vertices.
/// @param idx1 First vertex index.
/// @param idx2 Second vertex index.
/// @param idx3 Third vertex index.
/// @param material Material applied to the triangle.
void addTriangle(uint16_t idx1, uint16_t idx2, uint16_t idx3, Material* material);
/// @brief Append a quad as two triangles.
/// @param v1 First vertex index.
/// @param v2 Second vertex index.
/// @param v3 Third vertex index.
/// @param v4 Fourth vertex index.
/// @param material Material applied to both triangles.
void addFace(uint16_t v1, uint16_t v2, uint16_t v3, uint16_t v4, Material* material);
/// @brief Set the world-space position.
/// @param x World X.
/// @param y World Y.
/// @param z World Z.
void setPosition(int32_t x, int32_t y, int32_t z);
/// @brief Set the world-space position.
/// @param pos World-space position.
void setPosition(const Vector3& pos);
/// @brief Set the absolute Euler rotation (degrees).
/// @param rotX Rotation about X.
/// @param rotY Rotation about Y.
/// @param rotZ Rotation about Z.
void setRotation(int32_t rotX, int32_t rotY, int32_t rotZ);
/// @brief Set the absolute Euler rotation (degrees).
/// @param rot Rotation vector.
void setRotation(const Vector3& rot);
/// @brief Add a delta rotation (degrees).
/// @param angleX Delta about X.
/// @param angleY Delta about Y.
/// @param angleZ Delta about Z.
void rotate(int32_t angleX, int32_t angleY, int32_t angleZ);
/// @brief Add a delta rotation (degrees).
/// @param rot Delta rotation vector.
void rotate(const Vector3& rot);
/// @brief Translate the object in world space.
/// @param dx Delta X.
/// @param dy Delta Y.
/// @param dz Delta Z.
void translate(int32_t dx, int32_t dy, int32_t dz);
/// @brief Orient the object so its forward axis faces a target.
/// @param target World-space point to face.
void lookAt(const Vector3& target);
/// @brief Orient the object so its forward axis faces another object's centre.
/// @param targetObject Object to face.
void lookAt(const Object* targetObject);
/// @brief Recompute boundingBoxMin/Max and centreVolume from the current vertex set.
void calculateBoundingBox();
/// @brief Bake the current rotation into vertex positions and normals, then reset rotation to zero.
///
/// Intended for static meshes authored with a non-zero rotation purely
/// for placement convenience. After baking, the renderer hits its
/// zero-rotation fast path on every subsequent frame (saves
/// ~12 muls + 6 divs + 9 adds per vertex). One-shot operation. The
/// bounding box is recomputed automatically.
void bakeRotation();
/// @brief Bake a rational scale factor into vertex positions; one-shot operation.
///
/// Useful for permanently enlarging or shrinking geometry to give the
/// renderer's integer rotation chain more sub-pixel headroom at high
/// output resolutions. Scale is supplied as numerator/denominator to
/// stay deterministic and avoid floating point. e.g. (8, 1) makes the
/// object 8x larger; (1, 2) halves it. Performed with int64
/// intermediates so positions up to ~2.1e9 / numerator survive without
/// overflow. Normals are direction vectors and are NOT scaled. The
/// bounding box is recomputed automatically.
/// @param numerator Scale numerator.
/// @param denominator Scale denominator (must be non-zero).
void bakeScale(int32_t numerator, int32_t denominator);
private:
};
} // namespace Renderer
#endif // OBJECT_HPP