OBJ.C 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. /******************************************************************************
  2. Plush Version 1.2
  3. obj.c
  4. Object control
  5. Copyright (c) 1996-2000, Justin Frankel
  6. ******************************************************************************/
  7. #include "plush.h"
  8. pl_Obj *plObjScale(pl_Obj *o, pl_Float s) {
  9. pl_uInt32 i = o->NumVertices;
  10. pl_Vertex *v = o->Vertices;
  11. while (i--) {
  12. v->x *= s; v->y *= s; v->z *= s; v++;
  13. }
  14. for (i = 0; i < PL_MAX_CHILDREN; i ++)
  15. if (o->Children[i]) plObjScale(o->Children[i],s);
  16. return o;
  17. }
  18. pl_Obj *plObjStretch(pl_Obj *o, pl_Float x, pl_Float y, pl_Float z) {
  19. pl_uInt32 i = o->NumVertices;
  20. pl_Vertex *v = o->Vertices;
  21. while (i--) {
  22. v->x *= x; v->y *= y; v->z *= z; v++;
  23. }
  24. for (i = 0; i < PL_MAX_CHILDREN; i ++)
  25. if (o->Children[i]) plObjStretch(o->Children[i],x,y,z);
  26. return o;
  27. }
  28. pl_Obj *plObjTranslate(pl_Obj *o, pl_Float x, pl_Float y, pl_Float z) {
  29. pl_uInt32 i = o->NumVertices;
  30. pl_Vertex *v = o->Vertices;
  31. while (i--) {
  32. v->x += x; v->y += y; v->z += z; v++;
  33. }
  34. return o;
  35. }
  36. pl_Obj *plObjFlipNormals(pl_Obj *o) {
  37. pl_uInt32 i = o->NumVertices;
  38. pl_Vertex *v = o->Vertices;
  39. pl_Face *f = o->Faces;
  40. while (i--) {
  41. v->nx = - v->nx; v->ny = - v->ny; v->nz = - v->nz; v++;
  42. }
  43. i = o->NumFaces;
  44. while (i--) {
  45. f->nx = - f->nx; f->ny = - f->ny; f->nz = - f->nz;
  46. f++;
  47. }
  48. for (i = 0; i < PL_MAX_CHILDREN; i ++)
  49. if (o->Children[i]) plObjFlipNormals(o->Children[i]);
  50. return o;
  51. }
  52. void plObjDelete(pl_Obj *o) {
  53. pl_uInt i;
  54. if (o) {
  55. for (i = 0; i < PL_MAX_CHILDREN; i ++)
  56. if (o->Children[i]) plObjDelete(o->Children[i]);
  57. if (o->Vertices) free(o->Vertices);
  58. if (o->Faces) free(o->Faces);
  59. free(o);
  60. }
  61. }
  62. pl_Obj *plObjCreate(pl_uInt32 nv, pl_uInt32 nf) {
  63. pl_Obj *o;
  64. if (!(o = (pl_Obj *) malloc(sizeof(pl_Obj)))) return 0;
  65. memset(o,0,sizeof(pl_Obj));
  66. o->GenMatrix = 1;
  67. o->BackfaceCull = 1;
  68. o->NumVertices = nv;
  69. o->NumFaces = nf;
  70. if (nv && !(o->Vertices=(pl_Vertex *) malloc(sizeof(pl_Vertex)*nv))) {
  71. free(o);
  72. return 0;
  73. }
  74. if (nf && !(o->Faces = (pl_Face *) malloc(sizeof(pl_Face)*nf))) {
  75. free(o->Vertices);
  76. free(o);
  77. return 0;
  78. }
  79. memset(o->Vertices,0,sizeof(pl_Vertex)*nv);
  80. memset(o->Faces,0,sizeof(pl_Face)*nf);
  81. return o;
  82. }
  83. pl_Obj *plObjClone(pl_Obj *o) {
  84. pl_Face *iff, *of;
  85. pl_uInt32 i;
  86. pl_Obj *out;
  87. if (!(out = plObjCreate(o->NumVertices,o->NumFaces))) return 0;
  88. for (i = 0; i < PL_MAX_CHILDREN; i ++)
  89. if (o->Children[i]) out->Children[i] = plObjClone(o->Children[i]);
  90. out->Xa = o->Xa; out->Ya = o->Ya; out->Za = o->Za;
  91. out->Xp = o->Xp; out->Yp = o->Yp; out->Zp = o->Zp;
  92. out->BackfaceCull = o->BackfaceCull;
  93. out->BackfaceIllumination = o->BackfaceIllumination;
  94. out->GenMatrix = o->GenMatrix;
  95. memcpy(out->Vertices, o->Vertices, sizeof(pl_Vertex) * o->NumVertices);
  96. iff = o->Faces;
  97. of = out->Faces;
  98. i = out->NumFaces;
  99. while (i--) {
  100. of->Vertices[0] = (pl_Vertex *)
  101. out->Vertices + (iff->Vertices[0] - o->Vertices);
  102. of->Vertices[1] = (pl_Vertex *)
  103. out->Vertices + (iff->Vertices[1] - o->Vertices);
  104. of->Vertices[2] = (pl_Vertex *)
  105. out->Vertices + (iff->Vertices[2] - o->Vertices);
  106. of->MappingU[0] = iff->MappingU[0];
  107. of->MappingV[0] = iff->MappingV[0];
  108. of->MappingU[1] = iff->MappingU[1];
  109. of->MappingV[1] = iff->MappingV[1];
  110. of->MappingU[2] = iff->MappingU[2];
  111. of->MappingV[2] = iff->MappingV[2];
  112. of->nx = iff->nx;
  113. of->ny = iff->ny;
  114. of->nz = iff->nz;
  115. of->Material = iff->Material;
  116. of++;
  117. iff++;
  118. }
  119. return out;
  120. }
  121. void plObjSetMat(pl_Obj *o, pl_Mat *m, pl_Bool th) {
  122. pl_sInt32 i = o->NumFaces;
  123. pl_Face *f = o->Faces;
  124. while (i--) (f++)->Material = m;
  125. if (th) for (i = 0; i < PL_MAX_CHILDREN; i++)
  126. if (o->Children[i]) plObjSetMat(o->Children[i],m,th);
  127. }
  128. void plObjCalcNormals(pl_Obj *obj) {
  129. pl_uInt32 i;
  130. pl_Vertex *v = obj->Vertices;
  131. pl_Face *f = obj->Faces;
  132. double x1, x2, y1, y2, z1, z2;
  133. i = obj->NumVertices;
  134. while (i--) {
  135. v->nx = 0.0; v->ny = 0.0; v->nz = 0.0;
  136. v++;
  137. }
  138. i = obj->NumFaces;
  139. while (i--) {
  140. x1 = f->Vertices[0]->x-f->Vertices[1]->x;
  141. x2 = f->Vertices[0]->x-f->Vertices[2]->x;
  142. y1 = f->Vertices[0]->y-f->Vertices[1]->y;
  143. y2 = f->Vertices[0]->y-f->Vertices[2]->y;
  144. z1 = f->Vertices[0]->z-f->Vertices[1]->z;
  145. z2 = f->Vertices[0]->z-f->Vertices[2]->z;
  146. f->nx = (pl_Float) (y1*z2 - z1*y2);
  147. f->ny = (pl_Float) (z1*x2 - x1*z2);
  148. f->nz = (pl_Float) (x1*y2 - y1*x2);
  149. plNormalizeVector(&f->nx, &f->ny, &f->nz);
  150. f->Vertices[0]->nx += f->nx;
  151. f->Vertices[0]->ny += f->ny;
  152. f->Vertices[0]->nz += f->nz;
  153. f->Vertices[1]->nx += f->nx;
  154. f->Vertices[1]->ny += f->ny;
  155. f->Vertices[1]->nz += f->nz;
  156. f->Vertices[2]->nx += f->nx;
  157. f->Vertices[2]->ny += f->ny;
  158. f->Vertices[2]->nz += f->nz;
  159. f++;
  160. }
  161. v = obj->Vertices;
  162. i = obj->NumVertices;
  163. do {
  164. plNormalizeVector(&v->nx, &v->ny, &v->nz);
  165. v++;
  166. } while (--i);
  167. for (i = 0; i < PL_MAX_CHILDREN; i ++)
  168. if (obj->Children[i]) plObjCalcNormals(obj->Children[i]);
  169. }