From 8898ad9b25fca6afe2374d293a981db02a83d7e9 Mon Sep 17 00:00:00 2001 From: "FWoltermann@gmail.com" Date: Thu, 31 May 2012 14:46:27 +0000 Subject: Committing the documentation to svn to have it accessible online --- Doc/doxygen/html/_polygon_8cpp_source.html | 861 +++++++++++++++++++++++++++++ 1 file changed, 861 insertions(+) create mode 100644 Doc/doxygen/html/_polygon_8cpp_source.html (limited to 'Doc/doxygen/html/_polygon_8cpp_source.html') diff --git a/Doc/doxygen/html/_polygon_8cpp_source.html b/Doc/doxygen/html/_polygon_8cpp_source.html new file mode 100644 index 0000000..20c2e37 --- /dev/null +++ b/Doc/doxygen/html/_polygon_8cpp_source.html @@ -0,0 +1,861 @@ + + + + + +Starshatter_Open: D:/SRC/StarshatterSVN/nGenEx/Polygon.cpp Source File + + + + + + + + + + + + + +
+
+ + + + + + +
+
Starshatter_Open +
+
Open source Starshatter engine
+
+
+ + + + + +
+
+ +
+
+
+ +
+ + + + +
+ +
+ +
+
+
Polygon.cpp
+
+
+Go to the documentation of this file.
1 /* Project nGenEx
+
2  Destroyer Studios LLC
+
3  Copyright © 1997-2004. All Rights Reserved.
+
4 
+
5  SUBSYSTEM: nGenEx.lib
+
6  FILE: Polygon.cpp
+
7  AUTHOR: John DiCamillo
+
8 
+
9 
+
10  OVERVIEW
+
11  ========
+
12  Polygon and VertexSet structures for 3D rendering
+
13 */
+
14 
+
15 #include "MemDebug.h"
+
16 #include "Polygon.h"
+
17 #include "Bitmap.h"
+
18 
+
19 // +--------------------------------------------------------------------+
+
20 
+ +
22 : nverts(0), space(OBJECT_SPACE),
+
23 tu1(0), tv1(0), tangent(0), binormal(0)
+
24 {
+
25  Resize(m);
+
26 }
+
27 
+
28 // +--------------------------------------------------------------------+
+
29 
+ +
31 {
+
32  Delete();
+
33 }
+
34 
+
35 // +--------------------------------------------------------------------+
+
36 
+
37 void
+
38 VertexSet::Resize(int m, bool preserve)
+
39 {
+
40  // easy cases (no data will be preserved):
+
41  if (!m || !nverts || !preserve) {
+
42  bool additional_tex_coords = (tu1 != 0);
+
43 
+
44  Delete();
+
45 
+
46  nverts = m;
+
47 
+
48  if (nverts <= 0) {
+
49  ZeroMemory(this, sizeof(VertexSet));
+
50  }
+
51 
+
52  else {
+
53  loc = new(__FILE__,__LINE__) Vec3[nverts];
+
54  nrm = new(__FILE__,__LINE__) Vec3[nverts];
+
55  s_loc = new(__FILE__,__LINE__) Vec3[nverts];
+
56  tu = new(__FILE__,__LINE__) float[nverts];
+
57  tv = new(__FILE__,__LINE__) float[nverts];
+
58  rw = new(__FILE__,__LINE__) float[nverts];
+
59  diffuse = new(__FILE__,__LINE__) DWORD[nverts];
+
60  specular = new(__FILE__,__LINE__) DWORD[nverts];
+
61 
+
62  if (additional_tex_coords)
+ +
64 
+
65  if (!loc || !nrm || !s_loc || !rw || !tu || !tv || !diffuse || !specular) {
+
66  nverts = 0;
+
67 
+
68  delete [] loc;
+
69  delete [] nrm;
+
70  delete [] s_loc;
+
71  delete [] rw;
+
72  delete [] tu;
+
73  delete [] tv;
+
74  delete [] tu1;
+
75  delete [] tv1;
+
76  delete [] diffuse;
+
77  delete [] specular;
+
78 
+
79  ZeroMemory(this, sizeof(VertexSet));
+
80  }
+
81  }
+
82  }
+
83 
+
84  // actually need to copy data:
+
85  else {
+
86  int np = nverts;
+
87 
+
88  nverts = m;
+
89 
+
90  if (nverts < np)
+
91  np = nverts;
+
92 
+
93  Vec3* new_loc = new(__FILE__,__LINE__) Vec3[nverts];
+
94  Vec3* new_nrm = new(__FILE__,__LINE__) Vec3[nverts];
+
95  Vec3* new_s_loc = new(__FILE__,__LINE__) Vec3[nverts];
+
96  float* new_rw = new(__FILE__,__LINE__) float[nverts];
+
97  float* new_tu = new(__FILE__,__LINE__) float[nverts];
+
98  float* new_tv = new(__FILE__,__LINE__) float[nverts];
+
99  float* new_tu1 = 0;
+
100  float* new_tv1 = 0;
+
101  DWORD* new_diffuse = new(__FILE__,__LINE__) DWORD[nverts];
+
102  DWORD* new_specular = new(__FILE__,__LINE__) DWORD[nverts];
+
103 
+
104  if (tu1)
+
105  new_tu1 = new(__FILE__,__LINE__) float[nverts];
+
106 
+
107  if (tv1)
+
108  new_tv1 = new(__FILE__,__LINE__) float[nverts];
+
109 
+
110  if (new_loc) {
+
111  CopyMemory(new_loc, loc, np * sizeof(Vec3));
+
112  delete [] loc;
+
113  loc = new_loc;
+
114  }
+
115 
+
116  if (new_nrm) {
+
117  CopyMemory(new_nrm, nrm, np * sizeof(Vec3));
+
118  delete [] nrm;
+
119  nrm = new_nrm;
+
120  }
+
121 
+
122  if (new_s_loc) {
+
123  CopyMemory(new_s_loc, s_loc, np * sizeof(Vec3));
+
124  delete [] s_loc;
+
125  s_loc = new_s_loc;
+
126  }
+
127 
+
128  if (new_tu) {
+
129  CopyMemory(new_tu, tu, np * sizeof(float));
+
130  delete [] tu;
+
131  tu = new_tu;
+
132  }
+
133 
+
134  if (new_tv) {
+
135  CopyMemory(new_tv, tv, np * sizeof(float));
+
136  delete [] tv;
+
137  tv = new_tv;
+
138  }
+
139 
+
140  if (new_tu1) {
+
141  CopyMemory(new_tu1, tu1, np * sizeof(float));
+
142  delete [] tu1;
+
143  tu = new_tu1;
+
144  }
+
145 
+
146  if (new_tv1) {
+
147  CopyMemory(new_tv1, tv1, np * sizeof(float));
+
148  delete [] tv1;
+
149  tv = new_tv1;
+
150  }
+
151 
+
152  if (new_diffuse) {
+
153  CopyMemory(new_diffuse, diffuse, np * sizeof(DWORD));
+
154  delete [] diffuse;
+
155  diffuse = new_diffuse;
+
156  }
+
157 
+
158  if (new_specular) {
+
159  CopyMemory(new_specular, specular, np * sizeof(DWORD));
+
160  delete [] specular;
+
161  specular = new_specular;
+
162  }
+
163 
+
164  if (!loc || !nrm || !s_loc || !rw || !tu || !tv || !diffuse || !specular) {
+
165  Delete();
+
166  ZeroMemory(this, sizeof(VertexSet));
+
167  }
+
168  }
+
169 }
+
170 
+
171 // +--------------------------------------------------------------------+
+
172 
+
173 void
+ +
175 {
+
176  if (nverts) {
+
177  delete [] loc;
+
178  delete [] nrm;
+
179  delete [] s_loc;
+
180  delete [] rw;
+
181  delete [] tu;
+
182  delete [] tv;
+
183  delete [] tu1;
+
184  delete [] tv1;
+
185  delete [] diffuse;
+
186  delete [] specular;
+
187  delete [] tangent;
+
188  delete [] binormal;
+
189 
+
190  tangent = 0;
+
191  binormal = 0;
+
192  }
+
193 }
+
194 
+
195 // +--------------------------------------------------------------------+
+
196 
+
197 void
+ +
199 {
+
200  if (nverts) {
+
201  ZeroMemory(loc, sizeof(Vec3) * nverts);
+
202  ZeroMemory(nrm, sizeof(Vec3) * nverts);
+
203  ZeroMemory(s_loc, sizeof(Vec3) * nverts);
+
204  ZeroMemory(tu, sizeof(float) * nverts);
+
205  ZeroMemory(tv, sizeof(float) * nverts);
+
206  ZeroMemory(rw, sizeof(float) * nverts);
+
207  ZeroMemory(diffuse, sizeof(DWORD) * nverts);
+
208  ZeroMemory(specular, sizeof(DWORD) * nverts);
+
209 
+
210  if (tu1)
+
211  ZeroMemory(tu1, sizeof(float) * nverts);
+
212 
+
213  if (tv1)
+
214  ZeroMemory(tv1, sizeof(float) * nverts);
+
215 
+
216  if (tangent)
+
217  ZeroMemory(tangent, sizeof(Vec3) * nverts);
+
218 
+
219  if (binormal)
+
220  ZeroMemory(binormal, sizeof(Vec3) * nverts);
+
221  }
+
222 }
+
223 
+
224 // +--------------------------------------------------------------------+
+
225 
+
226 void
+ +
228 {
+
229  if (tangent) delete [] tangent;
+
230  if (binormal) delete [] binormal;
+
231 
+
232  tangent = 0;
+
233  binormal = 0;
+
234 
+
235  if (nverts) {
+
236  tangent = new(__FILE__,__LINE__) Vec3[nverts];
+
237  binormal = new(__FILE__,__LINE__) Vec3[nverts];
+
238  }
+
239 }
+
240 
+
241 // +--------------------------------------------------------------------+
+
242 
+
243 void
+ +
245 {
+
246  if (tu1) delete [] tu1;
+
247  if (tv1) delete [] tv1;
+
248 
+
249  tu1 = 0;
+
250  tv1 = 0;
+
251 
+
252  if (nverts) {
+
253  tu1 = new(__FILE__,__LINE__) float[nverts];
+
254  tv1 = new(__FILE__,__LINE__) float[nverts];
+
255  }
+
256 }
+
257 
+
258 // +--------------------------------------------------------------------+
+
259 
+
260 bool
+
261 VertexSet::CopyVertex(int dst, int src)
+
262 {
+
263  if (src >= 0 && src < nverts && dst >= 0 && dst < nverts) {
+
264  loc[dst] = loc[src];
+
265  nrm[dst] = nrm[src];
+
266  s_loc[dst] = s_loc[src];
+
267  tu[dst] = tu[src];
+
268  tv[dst] = tv[src];
+
269  diffuse[dst] = diffuse[src];
+
270  specular[dst] = specular[src];
+
271 
+
272  if (tu1)
+
273  tu1[dst] = tu1[src];
+
274 
+
275  if (tv1)
+
276  tv1[dst] = tv1[src];
+
277 
+
278  if (tangent)
+
279  tangent[dst] = tangent[src];
+
280 
+
281  if (binormal)
+
282  binormal[dst] = binormal[src];
+
283 
+
284  return true;
+
285  }
+
286 
+
287  return false;
+
288 }
+
289 
+
290 VertexSet*
+ +
292 {
+
293  VertexSet* result = new(__FILE__,__LINE__) VertexSet(nverts);
+
294 
+
295  CopyMemory(result->loc, loc, nverts * sizeof(Vec3));
+
296  CopyMemory(result->nrm, nrm, nverts * sizeof(Vec3));
+
297  CopyMemory(result->s_loc, s_loc, nverts * sizeof(Vec3));
+
298  CopyMemory(result->rw, rw, nverts * sizeof(float));
+
299  CopyMemory(result->tu, tu, nverts * sizeof(float));
+
300  CopyMemory(result->tv, tv, nverts * sizeof(float));
+
301  CopyMemory(result->diffuse, diffuse, nverts * sizeof(DWORD));
+
302  CopyMemory(result->specular, specular, nverts * sizeof(DWORD));
+
303 
+
304  if (tu1) {
+
305  if (!result->tu1)
+
306  result->tu1 = new(__FILE__,__LINE__) float[nverts];
+
307 
+
308  CopyMemory(result->tu1, tu1, nverts * sizeof(float));
+
309  }
+
310 
+
311  if (tv1) {
+
312  if (!result->tv1)
+
313  result->tv1 = new(__FILE__,__LINE__) float[nverts];
+
314 
+
315  CopyMemory(result->tv1, tv1, nverts * sizeof(float));
+
316  }
+
317 
+
318  if (tangent) {
+
319  if (!result->tangent)
+
320  result->tangent = new(__FILE__,__LINE__) Vec3[nverts];
+
321 
+
322  CopyMemory(result->tangent, tangent, nverts * sizeof(Vec3));
+
323  }
+
324 
+
325  if (binormal) {
+
326  if (!result->binormal)
+
327  result->binormal = new(__FILE__,__LINE__) Vec3[nverts];
+
328 
+
329  CopyMemory(result->binormal, binormal, nverts * sizeof(Vec3));
+
330  }
+
331 
+
332  return result;
+
333 }
+
334 
+
335 void
+ +
337 {
+
338  plus = Point(-1e6, -1e6, -1e6);
+
339  minus = Point( 1e6, 1e6, 1e6);
+
340 
+
341  for (int i = 0; i < nverts; i++) {
+
342  if (loc[i].x > plus.x) plus.x = loc[i].x;
+
343  if (loc[i].x < minus.x) minus.x = loc[i].x;
+
344  if (loc[i].y > plus.y) plus.y = loc[i].y;
+
345  if (loc[i].y < minus.y) minus.y = loc[i].y;
+
346  if (loc[i].z > plus.z) plus.z = loc[i].z;
+
347  if (loc[i].z < minus.z) minus.z = loc[i].z;
+
348  }
+
349 }
+
350 
+
351 // +--------------------------------------------------------------------+
+
352 // +--------------------------------------------------------------------+
+
353 // +--------------------------------------------------------------------+
+
354 
+
355 Poly::Poly(int init)
+
356 : nverts(0), visible(1), material(0), vertex_set(0), sortval(0), flatness(0)
+
357 { }
+
358 
+
359 // +--------------------------------------------------------------------+
+
360 // Check to see if a test point is within the bounds of the poly.
+
361 // The point is assumed to be coplanar with the poly. Return 1 if
+
362 // the point is inside, 0 if the point is outside.
+
363 
+ +
365 
+
366 static inline double extent3(double a, double b, double c)
+
367 {
+
368  double d1 = fabs(a-b);
+
369  double d2 = fabs(a-c);
+
370  double d3 = fabs(b-c);
+
371 
+
372  if (d1 > d2) {
+
373  if (d1 > d3)
+
374  return d1;
+
375  else
+
376  return d3;
+
377  }
+
378  else {
+
379  if (d2 > d3)
+
380  return d2;
+
381  else
+
382  return d3;
+
383  }
+
384 }
+
385 
+
386 int Poly::Contains(const Vec3& pt) const
+
387 {
+
388  // find largest 2d projection of this 3d Poly:
+
389  int projaxis;
+
390 
+
391  double pnx = fabs(plane.normal.x);
+
392  double pny = fabs(plane.normal.y);
+
393  double pnz = fabs(plane.normal.z);
+
394 
+
395  if (pnx > pny)
+
396  if (pnx > pnz)
+
397  if (plane.normal.x > 0)
+
398  projaxis = 1;
+
399  else
+
400  projaxis = -1;
+
401  else
+
402  if (plane.normal.z > 0)
+
403  projaxis = 3;
+
404  else
+
405  projaxis = -3;
+
406  else
+
407  if (pny > pnz)
+
408  if (plane.normal.y > 0)
+
409  projaxis = 2;
+
410  else
+
411  projaxis = -2;
+
412  else
+
413  if (plane.normal.z > 0)
+
414  projaxis = 3;
+
415  else
+
416  projaxis = -3;
+
417 
+
418  int i;
+
419 
+
420  for (i = 0; i < nverts; i++) {
+
421  Vec3 loc = vertex_set->loc[verts[i]];
+
422  switch (projaxis) {
+
423  case 1: projverts[i] = Vec2(loc.y, loc.z); break;
+
424  case -1: projverts[i] = Vec2(loc.z, loc.y); break;
+
425  case 2: projverts[i] = Vec2(loc.z, loc.x); break;
+
426  case -2: projverts[i] = Vec2(loc.x, loc.z); break;
+
427  case 3: projverts[i] = Vec2(loc.x, loc.y); break;
+
428  case -3: projverts[i] = Vec2(loc.y, loc.x); break;
+
429  }
+
430  }
+
431 
+
432  // now project the test point into the same plane:
+
433  Vec2 test;
+
434  switch (projaxis) {
+
435  case 1: test.x = pt.y; test.y = pt.z; break;
+
436  case -1: test.x = pt.z; test.y = pt.y; break;
+
437  case 2: test.x = pt.z; test.y = pt.x; break;
+
438  case -2: test.x = pt.x; test.y = pt.z; break;
+
439  case 3: test.x = pt.x; test.y = pt.y; break;
+
440  case -3: test.x = pt.y; test.y = pt.x; break;
+
441  }
+
442 
+
443  const float INSIDE_EPSILON = -0.01f;
+
444 
+
445  // if the test point is outside of any segment,
+
446  // it is outside the entire convex Poly.
+
447  for (i = 0; i < nverts-1; i++) {
+
448  if (verts[i] != verts[i+1]) {
+
449  Vec2 segment = projverts[i+1] - projverts[i];
+
450  Vec2 segnorm = segment.normal();
+
451  Vec2 tdelta = projverts[i] - test;
+
452  float inside = segnorm * tdelta;
+
453  if (inside < INSIDE_EPSILON)
+
454  return 0;
+
455  }
+
456  }
+
457 
+
458  // check last segment, too:
+
459  if (verts[0] != verts[nverts-1]) {
+
460  Vec2 segment = projverts[0] - projverts[nverts-1];
+
461  float inside = segment.normal() * (projverts[0] - test);
+
462  if (inside < INSIDE_EPSILON)
+
463  return 0;
+
464  }
+
465 
+
466  // still here? must be inside:
+
467  return 1;
+
468 }
+
469 
+
470 // +--------------------------------------------------------------------+
+
471 // +--------------------------------------------------------------------+
+
472 // +--------------------------------------------------------------------+
+
473 
+ +
475 : power(1.0f), brilliance(1.0f), bump(0.0f), blend(MTL_SOLID),
+
476 shadow(true), luminous(false),
+
477 tex_diffuse(0), tex_specular(0), tex_bumpmap(0), tex_emissive(0),
+
478 tex_alternate(0), tex_detail(0), thumbnail(0)
+
479 {
+
480  ZeroMemory(name, sizeof(name));
+
481  ZeroMemory(shader, sizeof(shader));
+
482 
+
483  ambient_value = 0.2f;
+
484  diffuse_value = 1.0f;
+
485  specular_value = 0.0f;
+
486  emissive_value = 0.0f;
+
487 }
+
488 
+
489 // +--------------------------------------------------------------------+
+
490 
+ +
492 {
+
493  // these objects are owned by the shared
+
494  // bitmap cache, so don't delete them now:
+
495  tex_diffuse = 0;
+
496  tex_specular = 0;
+
497  tex_bumpmap = 0;
+
498  tex_emissive = 0;
+
499  tex_alternate = 0;
+
500  tex_detail = 0;
+
501 
+
502  // the thumbnail is unique to the material,
+
503  // so it is never cached:
+
504  if (thumbnail)
+
505  delete thumbnail;
+
506 }
+
507 
+
508 // +--------------------------------------------------------------------+
+
509 
+
510 int
+ +
512 {
+
513  if (this == &m) return 1;
+
514 
+
515  if (Ka != m.Ka) return 0;
+
516  if (Kd != m.Kd) return 0;
+
517  if (Ks != m.Ks) return 0;
+
518  if (Ke != m.Ke) return 0;
+
519  if (power != m.power) return 0;
+
520  if (brilliance != m.brilliance) return 0;
+
521  if (bump != m.bump) return 0;
+
522  if (blend != m.blend) return 0;
+
523  if (shadow != m.shadow) return 0;
+
524  if (tex_diffuse != m.tex_diffuse) return 0;
+
525  if (tex_specular != m.tex_specular) return 0;
+
526  if (tex_bumpmap != m.tex_bumpmap) return 0;
+
527  if (tex_emissive != m.tex_emissive) return 0;
+
528  if (tex_alternate != m.tex_alternate) return 0;
+
529  if (tex_detail != m.tex_detail) return 0;
+
530 
+
531  return !strcmp(name, m.name);
+
532 }
+
533 
+
534 // +--------------------------------------------------------------------+
+
535 
+
536 void
+ +
538 {
+
539  Ka = ColorValue();
+
540  Kd = ColorValue();
+
541  Ks = ColorValue();
+
542  Ke = ColorValue();
+
543 
+
544  power = 1.0f;
+
545  bump = 0.0f;
+
546  blend = MTL_SOLID;
+
547  shadow = true;
+
548 
+
549  tex_diffuse = 0;
+
550  tex_specular = 0;
+
551  tex_bumpmap = 0;
+
552  tex_emissive = 0;
+
553  tex_alternate = 0;
+
554  tex_detail = 0;
+
555 }
+
556 
+
557 // +--------------------------------------------------------------------+
+
558 
+
559 static char shader_name[Material::NAMELEN];
+
560 
+
561 const char*
+
562 Material::GetShader(int pass) const
+
563 {
+
564  int level = 0;
+
565  if (pass > 1) pass--;
+
566 
+
567  for (int i = 0; i < NAMELEN; i++) {
+
568  if (shader[i] == '/') {
+
569  level++;
+
570 
+
571  if (level > pass)
+
572  return 0;
+
573  }
+
574 
+
575  else if (shader[i] != 0) {
+
576  if (level == pass) {
+
577  ZeroMemory(shader_name, NAMELEN);
+
578 
+
579  char* s = shader_name;
+
580  while (i < NAMELEN && shader[i] != 0 && shader[i] != '/') {
+
581  *s++ = shader[i++];
+
582  }
+
583 
+
584  return shader_name;
+
585  }
+
586  }
+
587 
+
588  else {
+
589  return 0;
+
590  }
+
591  }
+
592 
+
593  return 0;
+
594 }
+
595 
+
596 // +--------------------------------------------------------------------+
+
597 
+
598 void
+ +
600 {
+
601  if (!thumbnail) {
+
602  thumbnail = new(__FILE__,__LINE__) Bitmap(size, size);
+
603  }
+
604 
+
605  if (!thumbnail || thumbnail->Width() != thumbnail->Height())
+
606  return;
+
607 
+
608  size = thumbnail->Width();
+
609 
+
610  DWORD* image = new(__FILE__,__LINE__) DWORD[size*size];
+
611  DWORD* dst = image;
+
612 
+
613  for (int j = 0; j < size; j++) {
+
614  for (int i = 0; i < size; i++) {
+
615  *dst++ = GetThumbColor(i, j, size);
+
616  }
+
617  }
+
618 
+
619  thumbnail->CopyHighColorImage(size, size, image, Bitmap::BMP_SOLID);
+
620 }
+
621 
+
622 DWORD
+
623 Material::GetThumbColor(int i, int j, int size)
+
624 {
+
625  Color result = Color::LightGray;
+
626 
+
627  double x = i - size/2;
+
628  double y = j - size/2;
+
629  double r = 0.9 * size/2;
+
630  double d = sqrt(x*x + y*y);
+
631 
+
632  if (d <= r) {
+
633  double z = sqrt(r*r - x*x - y*y);
+
634 
+
635  Point loc(x,y,z);
+
636  Point nrm = loc; nrm.Normalize();
+
637  Point light(1,-1,1); light.Normalize();
+
638  Point eye(0,0,1);
+
639 
+
640  ColorValue c = Ka * ColorValue(0.25f, 0.25f, 0.25f); // ambient light
+
641  ColorValue white(1,1,1);
+
642 
+
643  double diffuse = nrm*light;
+
644  double v = 1 - (acos(nrm.y)/PI);
+
645  double u = asin(nrm.x / sin(acos(nrm.y))) / PI + 0.5;
+
646 
+
647  ColorValue cd = Kd;
+
648  ColorValue cs = Ks;
+
649  ColorValue ce = Ke;
+
650 
+
651  if (tex_diffuse) {
+
652  int tu = (int) (u * tex_diffuse->Width());
+
653  int tv = (int) (v * tex_diffuse->Height());
+
654  cd = Kd * tex_diffuse->GetColor(tu,tv);
+
655  }
+
656 
+
657  if (tex_emissive) {
+
658  int tu = (int) (u * tex_emissive->Width());
+
659  int tv = (int) (v * tex_emissive->Height());
+
660  ce = Ke * tex_emissive->GetColor(tu,tv);
+
661  }
+
662 
+
663  if (tex_bumpmap && bump != 0 && nrm.z > 0) {
+
664  // compute derivatives B(u,v)
+
665  int tu = (int) (u * tex_bumpmap->Width());
+
666  int tv = (int) (v * tex_bumpmap->Height());
+
667 
+
668  double du1 = tex_bumpmap->GetColor(tu,tv).Red() -
+
669  tex_bumpmap->GetColor(tu-1,tv).Red();
+
670  double du2 = tex_bumpmap->GetColor(tu+1,tv).Red() -
+
671  tex_bumpmap->GetColor(tu,tv).Red();
+
672 
+
673  double dv1 = tex_bumpmap->GetColor(tu,tv).Red() -
+
674  tex_bumpmap->GetColor(tu,tv-1).Red();
+
675  double dv2 = tex_bumpmap->GetColor(tu,tv+1).Red() -
+
676  tex_bumpmap->GetColor(tu,tv).Red();
+
677 
+
678  double du = (du1 + du2) / 512 * 1e-8;
+
679  double dv = (dv1 + dv2) / 512 * 1e-8;
+
680 
+
681  if (du || dv) {
+
682  Point Nu = nrm.cross(Point(0,-1,0)); Nu.Normalize();
+
683  Point Nv = nrm.cross(Point(1, 0,0)); Nv.Normalize();
+
684 
+
685  nrm += (Nu*du*bump);
+
686  nrm += (Nv*dv*bump);
+
687  nrm.Normalize();
+
688 
+
689  diffuse = nrm*light;
+
690  v = 1 - (acos(nrm.y)/PI);
+
691  u = asin(nrm.x / sin(acos(nrm.y))) / PI + 0.5;
+
692  }
+
693  }
+
694 
+
695  if (tex_specular) {
+
696  int tu = (int) (u * tex_specular->Width());
+
697  int tv = (int) (v * tex_specular->Height());
+
698  cs = Ks * tex_specular->GetColor(tu,tv);
+
699  }
+
700 
+
701  // anisotropic diffuse lighting
+
702  if (brilliance >= 0) {
+
703  diffuse = pow(diffuse, (double)brilliance);
+
704  }
+
705 
+
706  // forward lighting
+
707  if (diffuse > 0) {
+
708  // diffuse
+
709  c += cd * (white * diffuse);
+
710 
+
711  // specular
+
712  if (power > 0) {
+
713  double spec = ((nrm * 2*(nrm*light) - light) * eye);
+
714  if (spec > 0.01) {
+
715  spec = pow(spec, (double)power);
+
716  c += cs * (white * spec);
+
717  }
+
718  }
+
719  }
+
720 
+
721  // back lighting
+
722  else {
+
723  diffuse *= -0.5;
+
724  c += cd * (white * diffuse);
+
725 
+
726  // specular
+
727  if (power > 0) {
+
728  light *= -1;
+
729 
+
730  double spec = ((nrm * 2*(nrm*light) - light) * eye);
+
731  if (spec > 0.01) {
+
732  spec = pow(spec, (double)power);
+
733  c += cs * (white * spec) * 0.7;
+
734  }
+
735  }
+
736  }
+
737 
+
738  c += ce;
+
739 
+
740  result = c.ToColor();
+
741  }
+
742 
+
743  return result.Value();
+
744 }
+
+
+ + + + -- cgit v1.1