forked from zeichensystem/GeBurtstAg
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmodel.h
101 lines (81 loc) · 3.46 KB
/
model.h
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
#ifndef MODEL_H
#define MODEL_H
#include <tonc.h>
#include "math.h"
#include "raster_geometry.h"
#define MAX_MODEL_VERTS 512
#define MAX_MODEL_FACES 512
/*
We want to use object pools to manage our modelInstances, just a thin abstraction on top of static arrays with no dynamic allocations etc.
That means we can add and remove instances in constant time if we want that.
Only disadvantage would be that we have to iterate over empty slots then if we want to draw all and don't want to have a seperate array,
(but if we just keep our pools full, or mostly full, they are equivalent to regular arrays in that regard).
cf. https://gameprogrammingpatterns.com/object-pool.html (last retrieved: 2021-05-11)
*/
typedef enum FaceType {
TriangleFace,
ConvexPlanarQuadFace
} FaceType;
typedef struct Face {
FaceType type;
int vertexIndex[4]; // The faces don't save the vertices explicity, but indices to them (as vertices are usually shared among different faces, we save memory.)
Vec3 normal;
COLOR color;
} Face;
typedef struct Model {
const Vec3 *verts;
const Face *faces;
int numVerts, numFaces;
} Model;
typedef struct LightAttenuationParams {
const FIXED linear, quadratic;
} LightAttenuationParams;
/*
Attenuation parameters for different light ranges. Note: in .8 fixed point.
cf. http://wiki.ogre3d.org/tiki-index.php?page=-Point+Light+Attenuation (last retrieved 2021-05-12)
*/
static const LightAttenuationParams lightAttenuation100 = {.linear=12, .quadratic=2};
static const LightAttenuationParams lightAttenuation160 = {.linear=7, .quadratic=1};
static const LightAttenuationParams lightAttenuation200 = {.linear=6, .quadratic=0};
extern Model cubeModel;
typedef enum LightType {
LIGHT_DIRECTIONAL,
LIGHT_POINT
} LightType;
typedef struct ModelDrawLightingData {
const LightType type;
union {
const Vec3 *directional;
const Vec3 *point;
} light;
const LightAttenuationParams *attenuation; // Attenuation only for point lights.
} ALIGN4 ModelDrawLightingData;
typedef struct ModelInstance { // Different Instances share their vertex/face data, which saves us memory.
bool isEmpty;
union {
struct ModelInstance *__next; // Only neeeded if empty. Note: We could also use ModelInstanceIDs instead of pointers.
struct { // Only need those when the instance is not empty.
Model mod;
Vec3 pos;
Vec3 scale;
ANGLE_FIXED_12 yaw, pitch, roll;
PolygonShadingType shading;
FIXED camSpaceDepth;
bool backfaceCulling;
};
} ALIGN4 state;
} ALIGN4 ModelInstance;
typedef struct ModelInstancePool {
int POOL_CAPACITY;
int instanceCount;
ModelInstance *instances;
ModelInstance *firstAvailable;
} ModelInstancePool;
void modelInit(void);
Model modelNew(const Vec3 *verts, const Face *faces, int numVerts, int numFaces);
ModelInstancePool modelInstancePoolNew(ModelInstance *buffer, int bufferCapacity);
void modelInstancePoolReset(ModelInstancePool *pool);
int modelInstanceRemove(ModelInstancePool *pool, ModelInstance* instance);
ModelInstance* modelInstanceAdd(ModelInstancePool *pool, Model model, const Vec3 *pos, const Vec3 *scale, ANGLE_FIXED_12 yaw, ANGLE_FIXED_12 pitch, ANGLE_FIXED_12 roll, PolygonShadingType shading);
ModelInstance* modelInstanceAddVanilla(ModelInstancePool *pool, Model model, const Vec3 *pos, FIXED scale, PolygonShadingType shading);
#endif