aboutsummaryrefslogtreecommitdiff
path: root/Spear/Render/RenderModel.c
diff options
context:
space:
mode:
Diffstat (limited to 'Spear/Render/RenderModel.c')
-rw-r--r--Spear/Render/RenderModel.c232
1 files changed, 232 insertions, 0 deletions
diff --git a/Spear/Render/RenderModel.c b/Spear/Render/RenderModel.c
new file mode 100644
index 0000000..3d18a4b
--- /dev/null
+++ b/Spear/Render/RenderModel.c
@@ -0,0 +1,232 @@
1#include "RenderModel.h"
2#include <stdlib.h> // free
3#include <string.h> // memcpy
4#include <stdio.h>
5
6
7static void safe_free (void* ptr)
8{
9 if (ptr)
10 {
11 free (ptr);
12 ptr = 0;
13 }
14}
15
16
17/// Populate elements of an animated model to be rendered from
18/// start to end in a loop.
19/*int populate_elements_animated (Model* model_asset, RenderModel* model)
20{
21 size_t nverts = model_asset->numVertices;
22 size_t ntriangles = model_asset->numTriangles;
23 size_t nframes = model_asset->numFrames;
24 size_t n = nframes * ntriangles * 3;
25
26 model->elements = malloc (56 * n);
27 if (!model->elements) return -1;
28
29 // Populate elements.
30
31 size_t f, i;
32
33 char* elem = (char*) model->elements;
34 vec3* v1 = model_asset->vertices;
35 vec3* v2 = v1 + nverts;
36 vec3* n1 = model_asset->normals;
37 vec3* n2 = n1 + nverts;
38 texCoord* tex = model_asset->texCoords;
39
40 for (f = 0; f < nframes; ++f)
41 {
42 triangle* t = model_asset->triangles;
43
44 for (i = 0; i < ntriangles; ++i)
45 {
46 *((vec3*) elem) = v1[t->vertexIndices[0]];
47 *((vec3*) (elem + 12)) = v2[t->vertexIndices[0]];
48 *((vec3*) (elem + 24)) = n1[t->vertexIndices[0]];
49 *((vec3*) (elem + 36)) = n2[t->vertexIndices[0]];
50 *((texCoord*) (elem + 48)) = tex[t->textureIndices[0]];
51 elem += 56;
52
53 *((vec3*) elem) = v1[t->vertexIndices[1]];
54 *((vec3*) (elem + 12)) = v2[t->vertexIndices[1]];
55 *((vec3*) (elem + 24)) = n1[t->vertexIndices[1]];
56 *((vec3*) (elem + 36)) = n2[t->vertexIndices[1]];
57 *((texCoord*) (elem + 48)) = tex[t->textureIndices[1]];
58 elem += 56;
59
60 *((vec3*) elem) = v1[t->vertexIndices[2]];
61 *((vec3*) (elem + 12)) = v2[t->vertexIndices[2]];
62 *((vec3*) (elem + 24)) = n1[t->vertexIndices[2]];
63 *((vec3*) (elem + 36)) = n2[t->vertexIndices[2]];
64 *((texCoord*) (elem + 48)) = tex[t->textureIndices[2]];
65 elem += 56;
66
67 t++;
68 }
69
70 v1 += nverts;
71 v2 += nverts;
72 n1 += nverts;
73 n2 += nverts;
74
75 if (f == nframes-2)
76 {
77 v2 = model_asset->vertices;
78 n2 = model_asset->normals;
79 }
80 }
81
82 return 0;
83}*/
84
85
86/// Populate elements of an animated model according to its frames
87/// of animation.
88int populate_elements_animated (Model* model_asset, RenderModel* model)
89{
90 size_t nverts = model_asset->numVertices;
91 size_t ntriangles = model_asset->numTriangles;
92 size_t nframes = model_asset->numFrames;
93 size_t n = nframes * ntriangles * 3;
94
95 model->elements = malloc (56 * n);
96 if (!model->elements) return -1;
97
98 // Populate elements.
99
100 unsigned f, i, j, u;
101
102 char* elem = (char*) model->elements;
103 animation* anim = model_asset->animations;
104
105 for (i = 0; i < model_asset->numAnimations; ++i, anim++)
106 {
107 unsigned start = anim->start;
108 unsigned end = anim->end;
109
110 char singleFrameAnim = start == end;
111
112 vec3* v1 = model_asset->vertices + start*nverts;
113 vec3* v2 = singleFrameAnim ? v1 : v1 + nverts;
114 vec3* n1 = model_asset->normals + start*nverts;
115 vec3* n2 = singleFrameAnim ? n1 : n1 + nverts;
116 texCoord* tex = model_asset->texCoords;
117
118 for (u = start; u <= end; ++u)
119 {
120 triangle* t = model_asset->triangles;
121
122 for (j = 0; j < ntriangles; ++j, t++)
123 {
124 *((vec3*) elem) = v1[t->vertexIndices[0]];
125 *((vec3*) (elem + 12)) = v2[t->vertexIndices[0]];
126 *((vec3*) (elem + 24)) = n1[t->vertexIndices[0]];
127 *((vec3*) (elem + 36)) = n2[t->vertexIndices[0]];
128 *((texCoord*) (elem + 48)) = tex[t->textureIndices[0]];
129 elem += 56;
130
131 *((vec3*) elem) = v1[t->vertexIndices[1]];
132 *((vec3*) (elem + 12)) = v2[t->vertexIndices[1]];
133 *((vec3*) (elem + 24)) = n1[t->vertexIndices[1]];
134 *((vec3*) (elem + 36)) = n2[t->vertexIndices[1]];
135 *((texCoord*) (elem + 48)) = tex[t->textureIndices[1]];
136 elem += 56;
137
138 *((vec3*) elem) = v1[t->vertexIndices[2]];
139 *((vec3*) (elem + 12)) = v2[t->vertexIndices[2]];
140 *((vec3*) (elem + 24)) = n1[t->vertexIndices[2]];
141 *((vec3*) (elem + 36)) = n2[t->vertexIndices[2]];
142 *((texCoord*) (elem + 48)) = tex[t->textureIndices[2]];
143 elem += 56;
144 }
145
146 // Advance to the next frame of animation of the current
147 // animation.
148 v1 += nverts;
149 v2 += nverts;
150 n1 += nverts;
151 n2 += nverts;
152
153 // Reset the secondary pointers to the beginning of the
154 // animation when we are about to reach the last frame.
155 if (u == end-1)
156 {
157 v2 = model_asset->vertices + start*nverts;
158 n2 = model_asset->normals + start*nverts;
159 }
160 }
161 }
162
163 return 0;
164}
165
166
167int populate_elements_static (Model* model_asset, RenderModel* model)
168{
169 size_t nverts = model_asset->numVertices;
170 size_t ntriangles = model_asset->numTriangles;
171 size_t n = ntriangles * 3;
172
173 model->elements = malloc (32 * n);
174 if (!model->elements) return -1;
175
176 // Populate elements.
177
178 size_t f, i;
179
180 char* elem = (char*) model->elements;
181 vec3* vert = model_asset->vertices;
182 vec3* norm = model_asset->normals;
183 texCoord* tex = model_asset->texCoords;
184
185 triangle* t = model_asset->triangles;
186
187 for (i = 0; i < ntriangles; ++i)
188 {
189 *((vec3*) elem) = vert[t->vertexIndices[0]];
190 *((vec3*) (elem + 12)) = norm[t->vertexIndices[0]];
191 *((texCoord*) (elem + 24)) = tex[t->textureIndices[0]];
192 elem += 32;
193
194 *((vec3*) elem) = vert[t->vertexIndices[1]];
195 *((vec3*) (elem + 12)) = norm[t->vertexIndices[1]];
196 *((texCoord*) (elem + 24)) = tex[t->textureIndices[1]];
197 elem += 32;
198
199 *((vec3*) elem) = vert[t->vertexIndices[2]];
200 *((vec3*) (elem + 12)) = norm[t->vertexIndices[2]];
201 *((texCoord*) (elem + 24)) = tex[t->textureIndices[2]];
202 elem += 32;
203
204 t++;
205 }
206
207 return 0;
208}
209
210
211int render_model_from_model_asset (Model* model_asset, RenderModel* model)
212{
213 U32 ntriangles = model_asset->numTriangles;
214 U32 nframes = model_asset->numFrames;
215
216 int result;
217 if (nframes > 1) result = populate_elements_animated (model_asset, model);
218 else result = populate_elements_static (model_asset, model);
219
220 if (result != 0) return result;
221
222 model->numFrames = nframes;
223 model->numVertices = ntriangles * 3; // Number of vertices per frame.
224
225 return 0;
226}
227
228
229void render_model_free (RenderModel* model)
230{
231 safe_free (model->elements);
232}