rev |
line source |
nuclear@0
|
1 #include <cassert>
|
nuclear@0
|
2 #include "3dgeom.h"
|
nuclear@0
|
3 #include "3dengine.h"
|
nuclear@0
|
4
|
nuclear@0
|
5 using std::vector;
|
nuclear@0
|
6
|
nuclear@0
|
7 TexCoord::TexCoord(float u, float v) {
|
nuclear@0
|
8 this->u = u;
|
nuclear@0
|
9 this->v = v;
|
nuclear@0
|
10 }
|
nuclear@0
|
11
|
nuclear@0
|
12 // Vertex class implementation
|
nuclear@0
|
13
|
nuclear@0
|
14 Vertex::Vertex() {
|
nuclear@0
|
15 color = 0x00ffffff;
|
nuclear@0
|
16 memset(tex, 0, 4*sizeof(TexCoord));
|
nuclear@0
|
17 }
|
nuclear@0
|
18
|
nuclear@0
|
19 Vertex::Vertex(const Vector3 &position, float tu, float tv, dword color) {
|
nuclear@0
|
20 pos = position;
|
nuclear@0
|
21 tex[0].u = tex[1].u = tex[2].u = tex[3].u = tu;
|
nuclear@0
|
22 tex[0].v = tex[1].v = tex[2].v = tex[3].v = tv;
|
nuclear@0
|
23 this->color = color;
|
nuclear@0
|
24 }
|
nuclear@0
|
25
|
nuclear@0
|
26 void Vertex::CalculateNormal(const Vertex *vbuffer, const Triangle *triangles, long trinum) {
|
nuclear@0
|
27
|
nuclear@0
|
28 // find the position of the curent vertex in the vertex buffer
|
nuclear@0
|
29 dword index = (dword)(this - vbuffer);
|
nuclear@0
|
30
|
nuclear@0
|
31 normal = Vector3(0, 0, 0);
|
nuclear@0
|
32 const Triangle *tri = triangles;
|
nuclear@0
|
33 for(int i=0; i<trinum; i++, tri++) {
|
nuclear@0
|
34 if(tri->vertices[0] == index || tri->vertices[1] == index || tri->vertices[2] == index) {
|
nuclear@0
|
35 normal += tri->normal;
|
nuclear@0
|
36 }
|
nuclear@0
|
37 }
|
nuclear@0
|
38
|
nuclear@0
|
39 normal.Normalize();
|
nuclear@0
|
40 }
|
nuclear@0
|
41
|
nuclear@0
|
42 /////////// Edge class implementation ///////////
|
nuclear@0
|
43
|
nuclear@0
|
44 Edge::Edge() {
|
nuclear@0
|
45 vertices[0] = vertices[1] = adjfaces[0] = adjfaces[1] = 0;
|
nuclear@0
|
46 }
|
nuclear@0
|
47
|
nuclear@0
|
48 Edge::Edge(Index v1, Index v2, Index af1, Index af2) {
|
nuclear@0
|
49 vertices[0] = v1;
|
nuclear@0
|
50 vertices[1] = v2;
|
nuclear@0
|
51 adjfaces[0] = af1;
|
nuclear@0
|
52 adjfaces[1] = af2;
|
nuclear@0
|
53 }
|
nuclear@0
|
54
|
nuclear@0
|
55 /////////// Triangle class implementation /////////////
|
nuclear@0
|
56 Triangle::Triangle(Index v1, Index v2, Index v3) {
|
nuclear@0
|
57 vertices[0] = v1;
|
nuclear@0
|
58 vertices[1] = v2;
|
nuclear@0
|
59 vertices[2] = v3;
|
nuclear@0
|
60 }
|
nuclear@0
|
61
|
nuclear@0
|
62 void Triangle::CalculateNormal(Vertex *vbuffer, bool normalize) {
|
nuclear@0
|
63 Vector3 v1 = vbuffer[vertices[1]].pos - vbuffer[vertices[0]].pos;
|
nuclear@0
|
64 Vector3 v2 = vbuffer[vertices[2]].pos - vbuffer[vertices[0]].pos;
|
nuclear@0
|
65 normal = v1.CrossProduct(v2);
|
nuclear@0
|
66 if(normalize) normal.Normalize();
|
nuclear@0
|
67 }
|
nuclear@0
|
68
|
nuclear@0
|
69
|
nuclear@0
|
70 /////////////// Triangular Mesh implementation /////////////
|
nuclear@0
|
71
|
nuclear@0
|
72 TriMesh::TriMesh(byte LODLevels, GraphicsContext *gc) {
|
nuclear@0
|
73 memset(this, 0, sizeof(TriMesh));
|
nuclear@0
|
74 this->gc = gc;
|
nuclear@0
|
75 Levels = LODLevels;
|
nuclear@0
|
76
|
nuclear@0
|
77 varray = new Vertex*[Levels];
|
nuclear@0
|
78 memset(varray, 0, Levels * sizeof(Vertex*));
|
nuclear@0
|
79
|
nuclear@0
|
80 triarray = new Triangle*[Levels];
|
nuclear@0
|
81 memset(triarray, 0, Levels * sizeof(Triangle*));
|
nuclear@0
|
82
|
nuclear@0
|
83 vbuffer = new VertexBuffer*[Levels];
|
nuclear@0
|
84 memset(vbuffer, 0, Levels * sizeof(VertexBuffer*));
|
nuclear@0
|
85
|
nuclear@0
|
86 ibuffer = new IndexBuffer*[Levels];
|
nuclear@0
|
87 memset(ibuffer, 0, Levels * sizeof(IndexBuffer*));
|
nuclear@0
|
88
|
nuclear@0
|
89 AdjTriangles = new std::vector<dword>*[Levels];
|
nuclear@0
|
90 memset(AdjTriangles, 0, Levels * sizeof(std::vector<dword>*));
|
nuclear@0
|
91
|
nuclear@0
|
92 VertexCount = new dword[Levels];
|
nuclear@0
|
93 TriCount = new dword[Levels];
|
nuclear@0
|
94
|
nuclear@0
|
95 BuffersValid = new bool[Levels];
|
nuclear@0
|
96 memset(BuffersValid, 0, Levels * sizeof(bool));
|
nuclear@0
|
97
|
nuclear@0
|
98 AdjValid = new bool[Levels];
|
nuclear@0
|
99 memset(AdjValid, 0, Levels * sizeof(bool));
|
nuclear@0
|
100 }
|
nuclear@0
|
101
|
nuclear@0
|
102 TriMesh::TriMesh(const TriMesh &mesh) {
|
nuclear@0
|
103
|
nuclear@0
|
104 memcpy(this, &mesh, sizeof(TriMesh));
|
nuclear@0
|
105
|
nuclear@0
|
106 BuffersValid = new bool[Levels];
|
nuclear@0
|
107 memset(BuffersValid, 0, Levels * sizeof(bool));
|
nuclear@0
|
108
|
nuclear@0
|
109 varray = new Vertex*[Levels];
|
nuclear@0
|
110 triarray = new Triangle*[Levels];
|
nuclear@0
|
111 vbuffer = new VertexBuffer*[Levels];
|
nuclear@0
|
112 ibuffer = new IndexBuffer*[Levels];
|
nuclear@0
|
113
|
nuclear@0
|
114 VertexCount = new dword[Levels];
|
nuclear@0
|
115 TriCount = new dword[Levels];
|
nuclear@0
|
116
|
nuclear@0
|
117 for(int i=0; i<Levels; i++) {
|
nuclear@0
|
118
|
nuclear@0
|
119 VertexCount[i] = mesh.VertexCount[i];
|
nuclear@0
|
120 TriCount[i] = mesh.TriCount[i];
|
nuclear@0
|
121
|
nuclear@0
|
122 varray[i] = new Vertex[VertexCount[i]];
|
nuclear@0
|
123 triarray[i] = new Triangle[TriCount[i]];
|
nuclear@0
|
124
|
nuclear@0
|
125 memcpy(varray[i], mesh.varray[i], VertexCount[i] * sizeof(Vertex));
|
nuclear@0
|
126 memcpy(triarray[i], mesh.triarray[i], TriCount[i] * sizeof(Triangle));
|
nuclear@0
|
127
|
nuclear@0
|
128 vbuffer[i] = 0;
|
nuclear@0
|
129 ibuffer[i] = 0;
|
nuclear@0
|
130
|
nuclear@0
|
131 UpdateSystemBuffers(i);
|
nuclear@0
|
132 }
|
nuclear@0
|
133 }
|
nuclear@0
|
134
|
nuclear@0
|
135 TriMesh::~TriMesh() {
|
nuclear@0
|
136 if(varray) {
|
nuclear@0
|
137 for(int i=0; i<Levels; i++) {
|
nuclear@0
|
138 delete [] varray[i];
|
nuclear@0
|
139 }
|
nuclear@0
|
140 delete [] varray;
|
nuclear@0
|
141 }
|
nuclear@0
|
142
|
nuclear@0
|
143 if(triarray) {
|
nuclear@0
|
144 for(int i=0; i<Levels; i++) {
|
nuclear@0
|
145 delete [] triarray[i];
|
nuclear@0
|
146 }
|
nuclear@0
|
147 delete triarray;
|
nuclear@0
|
148 }
|
nuclear@0
|
149
|
nuclear@0
|
150 if(vbuffer) {
|
nuclear@0
|
151 for(int i=0; i<Levels; i++) {
|
nuclear@0
|
152 if(vbuffer[i]) vbuffer[i]->Release();
|
nuclear@0
|
153 }
|
nuclear@0
|
154 }
|
nuclear@0
|
155 if(ibuffer) {
|
nuclear@0
|
156 for(int i=0; i<Levels; i++) {
|
nuclear@0
|
157 if(ibuffer[i]) ibuffer[i]->Release();
|
nuclear@0
|
158 }
|
nuclear@0
|
159 }
|
nuclear@0
|
160
|
nuclear@0
|
161 if(AdjTriangles) {
|
nuclear@0
|
162 for(int i=0; i<Levels; i++) {
|
nuclear@0
|
163 delete [] AdjTriangles[i];
|
nuclear@0
|
164 }
|
nuclear@0
|
165 delete AdjTriangles;
|
nuclear@0
|
166 }
|
nuclear@0
|
167 }
|
nuclear@0
|
168
|
nuclear@0
|
169 const TriMesh &TriMesh::operator =(const TriMesh &mesh) {
|
nuclear@0
|
170 memcpy(this, &mesh, sizeof(TriMesh));
|
nuclear@0
|
171
|
nuclear@0
|
172 BuffersValid = new bool[Levels];
|
nuclear@0
|
173 memset(BuffersValid, 0, Levels * sizeof(bool));
|
nuclear@0
|
174
|
nuclear@0
|
175 varray = new Vertex*[Levels];
|
nuclear@0
|
176 triarray = new Triangle*[Levels];
|
nuclear@0
|
177 vbuffer = new VertexBuffer*[Levels];
|
nuclear@0
|
178 ibuffer = new IndexBuffer*[Levels];
|
nuclear@0
|
179
|
nuclear@0
|
180 VertexCount = new dword[Levels];
|
nuclear@0
|
181 TriCount = new dword[Levels];
|
nuclear@0
|
182
|
nuclear@0
|
183 for(int i=0; i<Levels; i++) {
|
nuclear@0
|
184
|
nuclear@0
|
185 VertexCount[i] = mesh.VertexCount[i];
|
nuclear@0
|
186 TriCount[i] = mesh.TriCount[i];
|
nuclear@0
|
187
|
nuclear@0
|
188 varray[i] = new Vertex[VertexCount[i]];
|
nuclear@0
|
189 triarray[i] = new Triangle[TriCount[i]];
|
nuclear@0
|
190
|
nuclear@0
|
191 memcpy(varray[i], mesh.varray[i], VertexCount[i] * sizeof(Vertex));
|
nuclear@0
|
192 memcpy(triarray[i], mesh.triarray[i], TriCount[i] * sizeof(Triangle));
|
nuclear@0
|
193
|
nuclear@0
|
194 vbuffer[i] = 0;
|
nuclear@0
|
195 ibuffer[i] = 0;
|
nuclear@0
|
196
|
nuclear@0
|
197 UpdateSystemBuffers(i);
|
nuclear@0
|
198 }
|
nuclear@0
|
199 return mesh;
|
nuclear@0
|
200 }
|
nuclear@0
|
201
|
nuclear@0
|
202
|
nuclear@0
|
203 const Vertex *TriMesh::GetVertexArray(byte level) const {
|
nuclear@0
|
204 if(level >= Levels) return 0;
|
nuclear@0
|
205 return varray[level];
|
nuclear@0
|
206 }
|
nuclear@0
|
207
|
nuclear@0
|
208 const Triangle *TriMesh::GetTriangleArray(byte level) const {
|
nuclear@0
|
209 if(level >= Levels) return 0;
|
nuclear@0
|
210 return triarray[level];
|
nuclear@0
|
211 }
|
nuclear@0
|
212
|
nuclear@0
|
213
|
nuclear@0
|
214 Vertex *TriMesh::GetModVertexArray() {
|
nuclear@0
|
215 memset(BuffersValid, 0, Levels * sizeof(bool));
|
nuclear@0
|
216 return varray[0];
|
nuclear@0
|
217 }
|
nuclear@0
|
218
|
nuclear@0
|
219 Triangle *TriMesh::GetModTriangleArray() {
|
nuclear@0
|
220 memset(BuffersValid, 0, Levels * sizeof(bool));
|
nuclear@0
|
221 memset(AdjValid, 0, Levels * sizeof(bool));
|
nuclear@0
|
222 return triarray[0];
|
nuclear@0
|
223 }
|
nuclear@0
|
224
|
nuclear@0
|
225 const VertexBuffer *TriMesh::GetVertexBuffer(byte level) const {
|
nuclear@0
|
226 if(level >= Levels) return 0;
|
nuclear@0
|
227
|
nuclear@0
|
228 if(!BuffersValid[level]) {
|
nuclear@0
|
229 const_cast<TriMesh*>(this)->UpdateSystemBuffers(level);
|
nuclear@0
|
230 }
|
nuclear@0
|
231 return vbuffer[level];
|
nuclear@0
|
232 }
|
nuclear@0
|
233
|
nuclear@0
|
234 const IndexBuffer *TriMesh::GetIndexBuffer(byte level) const {
|
nuclear@0
|
235 if(level >= Levels) return 0;
|
nuclear@0
|
236
|
nuclear@0
|
237 if(!BuffersValid[level]) {
|
nuclear@0
|
238 const_cast<TriMesh*>(this)->UpdateSystemBuffers(level);
|
nuclear@0
|
239 }
|
nuclear@0
|
240
|
nuclear@0
|
241 return ibuffer[level];
|
nuclear@0
|
242 }
|
nuclear@0
|
243
|
nuclear@0
|
244
|
nuclear@0
|
245 dword TriMesh::GetVertexCount(byte level) const {
|
nuclear@0
|
246 if(level >= Levels) return 0xdeadbeef;
|
nuclear@0
|
247 return VertexCount[level];
|
nuclear@0
|
248 }
|
nuclear@0
|
249
|
nuclear@0
|
250 dword TriMesh::GetTriangleCount(byte level) const {
|
nuclear@0
|
251 if(level >= Levels) return 0xdeadbeef;
|
nuclear@0
|
252 return TriCount[level];
|
nuclear@0
|
253 }
|
nuclear@0
|
254
|
nuclear@0
|
255 byte TriMesh::GetLevelCount() const {
|
nuclear@0
|
256 return Levels;
|
nuclear@0
|
257 }
|
nuclear@0
|
258
|
nuclear@0
|
259 void TriMesh::SetGraphicsContext(GraphicsContext *gc) {
|
nuclear@0
|
260 this->gc = gc;
|
nuclear@0
|
261 memset(BuffersValid, 0, Levels * sizeof(bool)); // invalidate all system buffers in all levels
|
nuclear@0
|
262 }
|
nuclear@0
|
263
|
nuclear@0
|
264 void TriMesh::SetData(const Vertex *vdata, const Triangle *tridata, dword vcount, dword tricount) {
|
nuclear@0
|
265
|
nuclear@0
|
266 memset(BuffersValid, 0, Levels * sizeof(bool));
|
nuclear@0
|
267 memset(AdjValid, 0, Levels * sizeof(bool));
|
nuclear@0
|
268
|
nuclear@0
|
269 if(varray[0]) delete [] varray[0];
|
nuclear@0
|
270 if(triarray[0]) delete [] triarray[0];
|
nuclear@0
|
271 varray[0] = new Vertex[vcount];
|
nuclear@0
|
272 triarray[0] = new Triangle[tricount];
|
nuclear@0
|
273
|
nuclear@0
|
274 if(vdata) memcpy(varray[0], vdata, vcount * sizeof(Vertex));
|
nuclear@0
|
275 if(tridata) memcpy(triarray[0], tridata, tricount * sizeof(Triangle));
|
nuclear@0
|
276 VertexCount[0] = vcount;
|
nuclear@0
|
277 TriCount[0] = tricount;
|
nuclear@0
|
278
|
nuclear@0
|
279 UpdateLODChain();
|
nuclear@0
|
280 }
|
nuclear@0
|
281
|
nuclear@0
|
282 bool TriMesh::UpdateSystemBuffers(byte level) {
|
nuclear@0
|
283
|
nuclear@0
|
284 if(!gc || level >= Levels) return false;
|
nuclear@0
|
285
|
nuclear@0
|
286 if(vbuffer[level]) {
|
nuclear@0
|
287 D3DVERTEXBUFFER_DESC vbdesc;
|
nuclear@0
|
288 vbuffer[level]->GetDesc(&vbdesc);
|
nuclear@0
|
289 if(vbdesc.Size / sizeof(Vertex) != VertexCount[level]) {
|
nuclear@0
|
290 vbuffer[level]->Release();
|
nuclear@0
|
291
|
nuclear@0
|
292 if(gc->D3DDevice->CreateVertexBuffer(VertexCount[level] * sizeof(Vertex), dynamic ? D3DUSAGE_DYNAMIC : 0, VertexFormat, D3DPOOL_DEFAULT, &vbuffer[level]) != D3D_OK) {
|
nuclear@0
|
293 return false;
|
nuclear@0
|
294 }
|
nuclear@0
|
295 }
|
nuclear@0
|
296 } else {
|
nuclear@0
|
297 if(gc->D3DDevice->CreateVertexBuffer(VertexCount[level] * sizeof(Vertex), dynamic ? D3DUSAGE_DYNAMIC : 0, VertexFormat, D3DPOOL_DEFAULT, &vbuffer[level]) != D3D_OK) {
|
nuclear@0
|
298 return false;
|
nuclear@0
|
299 }
|
nuclear@0
|
300 }
|
nuclear@0
|
301
|
nuclear@0
|
302 Vertex *vbdata;
|
nuclear@0
|
303 Lock(vbuffer[level], &vbdata);
|
nuclear@0
|
304 memcpy(vbdata, varray[level], VertexCount[level] * sizeof(Vertex));
|
nuclear@0
|
305 Unlock(vbuffer[level]);
|
nuclear@0
|
306
|
nuclear@0
|
307 if(ibuffer[level]) {
|
nuclear@0
|
308 D3DINDEXBUFFER_DESC ibdesc;
|
nuclear@0
|
309 ibuffer[level]->GetDesc(&ibdesc);
|
nuclear@0
|
310 if(ibdesc.Size / IndexSize != TriCount[level] * 3) {
|
nuclear@0
|
311 ibuffer[level]->Release();
|
nuclear@0
|
312
|
nuclear@0
|
313 if(gc->D3DDevice->CreateIndexBuffer(TriCount[level] * 3 * IndexSize, dynamic ? D3DUSAGE_DYNAMIC : 0, IndexFormat, D3DPOOL_DEFAULT, &ibuffer[level]) != D3D_OK) {
|
nuclear@0
|
314 return false;
|
nuclear@0
|
315 }
|
nuclear@0
|
316 }
|
nuclear@0
|
317 } else {
|
nuclear@0
|
318 if(gc->D3DDevice->CreateIndexBuffer(TriCount[level] * 3 * IndexSize, dynamic ? D3DUSAGE_DYNAMIC : 0, IndexFormat, D3DPOOL_DEFAULT, &ibuffer[level]) != D3D_OK) {
|
nuclear@0
|
319 return false;
|
nuclear@0
|
320 }
|
nuclear@0
|
321 }
|
nuclear@0
|
322
|
nuclear@0
|
323
|
nuclear@0
|
324 Index *ibdata;
|
nuclear@0
|
325 Lock(ibuffer[level], &ibdata);
|
nuclear@0
|
326 for(dword i=0; i<TriCount[level]; i++) {
|
nuclear@0
|
327 *ibdata++ = triarray[level][i].vertices[0];
|
nuclear@0
|
328 *ibdata++ = triarray[level][i].vertices[1];
|
nuclear@0
|
329 *ibdata++ = triarray[level][i].vertices[2];
|
nuclear@0
|
330 }
|
nuclear@0
|
331 Unlock(ibuffer[level]);
|
nuclear@0
|
332
|
nuclear@0
|
333 BuffersValid[level] = true;
|
nuclear@0
|
334 return true;
|
nuclear@0
|
335 }
|
nuclear@0
|
336
|
nuclear@0
|
337 void TriMesh::UpdateLODChain() {
|
nuclear@0
|
338 for(byte i=1; i<Levels; i++) {
|
nuclear@0
|
339 // TODO: apply mesh optimization, for now, just copy as it is
|
nuclear@0
|
340 VertexCount[i] = VertexCount[0];
|
nuclear@0
|
341 TriCount[i] = TriCount[0];
|
nuclear@0
|
342
|
nuclear@0
|
343 if(!varray[i]) varray[i] = new Vertex[VertexCount[i]];
|
nuclear@0
|
344 memcpy(varray[i], varray[0], VertexCount[i] * sizeof(Vertex));
|
nuclear@0
|
345
|
nuclear@0
|
346 if(!triarray[i]) triarray[i] = new Triangle[TriCount[i]];
|
nuclear@0
|
347 memcpy(triarray[i], triarray[0], TriCount[i] * sizeof(Triangle));
|
nuclear@0
|
348
|
nuclear@0
|
349 UpdateSystemBuffers(i);
|
nuclear@0
|
350 }
|
nuclear@0
|
351
|
nuclear@0
|
352 if(!BuffersValid[0]) UpdateSystemBuffers(0);
|
nuclear@0
|
353 }
|
nuclear@0
|
354
|
nuclear@0
|
355 // TODO: this will brake currently with multiple LOD levels, revise LOD normal calculation
|
nuclear@0
|
356 // and revise UpdateLODChain() too
|
nuclear@0
|
357 void TriMesh::CalculateNormals() {
|
nuclear@0
|
358 memset(BuffersValid, 0, Levels * sizeof(bool));
|
nuclear@0
|
359
|
nuclear@0
|
360 Triangle *tri = triarray[0];
|
nuclear@0
|
361 Triangle *tend = tri + TriCount[0];
|
nuclear@0
|
362
|
nuclear@0
|
363 while(tri != tend) {
|
nuclear@0
|
364 (*tri++).CalculateNormal(varray[0], false);
|
nuclear@0
|
365 }
|
nuclear@0
|
366
|
nuclear@0
|
367 /*
|
nuclear@0
|
368 Vertex *vert = varray[0];
|
nuclear@0
|
369 Vertex *vend = vert + VertexCount[0];
|
nuclear@0
|
370
|
nuclear@0
|
371 while(vert != vend) {
|
nuclear@0
|
372 (*vert++).CalculateNormal(varray[0], triarray[0], TriCount[0]);
|
nuclear@0
|
373 }
|
nuclear@0
|
374 */
|
nuclear@0
|
375
|
nuclear@0
|
376 if(!AdjValid[0]) {
|
nuclear@0
|
377 if(AdjTriangles[0]) delete [] AdjTriangles[0];
|
nuclear@0
|
378 AdjTriangles[0] = new std::vector<dword>[VertexCount[0]];
|
nuclear@0
|
379 }
|
nuclear@0
|
380
|
nuclear@0
|
381 for(dword i=0; i<VertexCount[0]; i++) {
|
nuclear@0
|
382 if(AdjValid[0]) {
|
nuclear@0
|
383 assert(AdjTriangles[0]);
|
nuclear@0
|
384 Vector3 normal(0.0f, 0.0f, 0.0f);
|
nuclear@0
|
385 for(dword j=0; j<AdjTriangles[0][i].size(); j++) {
|
nuclear@0
|
386 normal += triarray[0][AdjTriangles[0][i][j]].normal;
|
nuclear@0
|
387 }
|
nuclear@0
|
388 normal.Normalize();
|
nuclear@0
|
389 varray[0][i].normal = normal;
|
nuclear@0
|
390 } else {
|
nuclear@0
|
391
|
nuclear@0
|
392 AdjTriangles[0][i].erase(AdjTriangles[0][i].begin(), AdjTriangles[0][i].end());
|
nuclear@0
|
393 Vector3 normal(0.0f, 0.0f, 0.0f);
|
nuclear@0
|
394 for(dword j=0; j<TriCount[0]; j++) {
|
nuclear@0
|
395 if(triarray[0][j].vertices[0] == i || triarray[0][j].vertices[1] == i || triarray[0][j].vertices[2] == i) {
|
nuclear@0
|
396 AdjTriangles[0][i].push_back(j);
|
nuclear@0
|
397 normal += triarray[0][j].normal;
|
nuclear@0
|
398 }
|
nuclear@0
|
399 }
|
nuclear@0
|
400 normal.Normalize();
|
nuclear@0
|
401 varray[0][i].normal = normal;
|
nuclear@0
|
402 }
|
nuclear@0
|
403 }
|
nuclear@0
|
404
|
nuclear@0
|
405 AdjValid[0] = true;
|
nuclear@0
|
406
|
nuclear@0
|
407 UpdateLODChain();
|
nuclear@0
|
408 }
|
nuclear@0
|
409
|
nuclear@0
|
410 void TriMesh::CalculateNormalsFast() {
|
nuclear@0
|
411 memset(BuffersValid, 0, Levels * sizeof(bool));
|
nuclear@0
|
412
|
nuclear@0
|
413 Triangle *tri = triarray[0];
|
nuclear@0
|
414 Triangle *tend = tri + TriCount[0];
|
nuclear@0
|
415
|
nuclear@0
|
416 while(tri != tend) {
|
nuclear@0
|
417 tri->CalculateNormal(varray[0], true);
|
nuclear@0
|
418 varray[0][tri->vertices[0]].normal = tri->normal;
|
nuclear@0
|
419 varray[0][tri->vertices[1]].normal = tri->normal;
|
nuclear@0
|
420 varray[0][tri->vertices[2]].normal = tri->normal;
|
nuclear@0
|
421 tri++;
|
nuclear@0
|
422 }
|
nuclear@0
|
423
|
nuclear@0
|
424 UpdateLODChain();
|
nuclear@0
|
425 }
|
nuclear@0
|
426
|
nuclear@0
|
427 void TriMesh::ChangeMode(TriMeshMode mode) {
|
nuclear@0
|
428 dynamic = mode == TriMeshDynamic;
|
nuclear@0
|
429 }
|
nuclear@0
|
430
|
nuclear@0
|
431 /*
|
nuclear@0
|
432
|
nuclear@0
|
433 void TriMesh::CalculateEdges() {
|
nuclear@0
|
434
|
nuclear@0
|
435 //build a list of triangles that share each vertex
|
nuclear@0
|
436 std::list<Triangle*> *ShareTris = new std::list<Triangle*>[VertexCount[0]];
|
nuclear@0
|
437
|
nuclear@0
|
438 for(dword i=0; i<VertexCount[0]; i++) {
|
nuclear@0
|
439 for(dword j=0; j<TriCount[0]; j++) {
|
nuclear@0
|
440 Index VertexIndex = (Index)((Vertex*)&varray[0][i] - (Vertex*)&varray[0][0]);
|
nuclear@0
|
441 if(triarray[0][j].vertices[0] == VertexIndex || triarray[0][j].vertices[1] == VertexIndex || triarray[0][j].vertices[2] == VertexIndex) {
|
nuclear@0
|
442 ShareTris[i].push_back(&triarray[0][j]); // if it references this vertex add it
|
nuclear@0
|
443 }
|
nuclear@0
|
444 }
|
nuclear@0
|
445 }
|
nuclear@0
|
446
|
nuclear@0
|
447 // find the adjacent triangles of each edge
|
nuclear@0
|
448 for(dword i=0; i<TriCount[0]; i++) {
|
nuclear@0
|
449 Triangle *tri = &triarray[0][i];
|
nuclear@0
|
450
|
nuclear@0
|
451 for(int j=0; j<3; j++) {
|
nuclear@0
|
452 tri->edges[j].vertices[0] = tri->vertices[j];
|
nuclear@0
|
453 tri->edges[j].vertices[1] = tri->vertices[(j+1) % 3];
|
nuclear@0
|
454 tri->edges[j].adjfaces[0] = (Index)i;
|
nuclear@0
|
455 }
|
nuclear@0
|
456
|
nuclear@0
|
457 for(int j=0; j<3; j++) {
|
nuclear@0
|
458 Index v0 = (Index)((Vertex*)&varray[0][tri->edges[j].vertices[0]] - (Vertex*)&varray[0][0]);
|
nuclear@0
|
459 Index v1 = (Index)((Vertex*)&varray[0][tri->edges[j].vertices[1]] - (Vertex*)&varray[0][0]);
|
nuclear@0
|
460
|
nuclear@0
|
461 std::list<Triangle*>::iterator iter = ShareTris[v0].begin();
|
nuclear@0
|
462 while(iter != ShareTris[v0].end()) {
|
nuclear@0
|
463 Index TriIndex = (Index)(*iter - &triarray[0][0]);
|
nuclear@0
|
464
|
nuclear@0
|
465 if((TriIndex != i) && ((*iter)->vertices[0] == v1 || (*iter)->vertices[1] == v1 || (*iter)->vertices[2] == v1)) {
|
nuclear@0
|
466 tri->edges[j].adjfaces[1] = TriIndex;
|
nuclear@0
|
467 break;
|
nuclear@0
|
468 }
|
nuclear@0
|
469 iter++;
|
nuclear@0
|
470 }
|
nuclear@0
|
471 if(iter == ShareTris[v0].end()) tri->edges[j].adjfaces[1] = (Index)0xffffffff;
|
nuclear@0
|
472 }
|
nuclear@0
|
473 }
|
nuclear@0
|
474
|
nuclear@0
|
475 // TODO: wield duplicate edges
|
nuclear@0
|
476 }
|
nuclear@0
|
477
|
nuclear@0
|
478 */ |