MAKE.C 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480
  1. /******************************************************************************
  2. Plush Version 1.2
  3. make.c
  4. Object Primitives
  5. Copyright (c) 1996-2000, Justin Frankel
  6. *******************************************************************************
  7. Notes:
  8. Most of these routines are highly unoptimized.
  9. They could all use some work, such as more capable divisions (Box is
  10. most notable), etc... The mapping coordinates are all set up nicely,
  11. though.
  12. ******************************************************************************/
  13. #include "plush.h"
  14. pl_Obj *plMakeTorus(pl_Float r1, pl_Float r2, pl_uInt divrot, pl_uInt divrad,
  15. pl_Mat *m) {
  16. pl_Obj *o;
  17. pl_Vertex *v;
  18. pl_Face *f;
  19. pl_uInt x, y;
  20. double ravg, rt, a, da, al, dal;
  21. pl_sInt32 U,V,dU,dV;
  22. if (divrot < 3) divrot = 3;
  23. if (divrad < 3) divrad = 3;
  24. ravg = (r1+r2)*0.5;
  25. rt = (r2-r1)*0.5;
  26. o = plObjCreate(divrad*divrot,divrad*divrot*2);
  27. if (!o) return 0;
  28. v = o->Vertices;
  29. a = 0.0;
  30. da = 2*PL_PI/divrot;
  31. for (y = 0; y < divrot; y ++) {
  32. al = 0.0;
  33. dal = 2*PL_PI/divrad;
  34. for (x = 0; x < divrad; x ++) {
  35. v->x = (pl_Float) (cos((double) a)*(ravg + cos((double) al)*rt));
  36. v->z = (pl_Float) (sin((double) a)*(ravg + cos((double) al)*rt));
  37. v->y = (pl_Float) (sin((double) al)*rt);
  38. v++;
  39. al += dal;
  40. }
  41. a += da;
  42. }
  43. v = o->Vertices;
  44. f = o->Faces;
  45. dV = 65535/divrad;
  46. dU = 65535/divrot;
  47. U = 0;
  48. for (y = 0; y < divrot; y ++) {
  49. V = -32768;
  50. for (x = 0; x < divrad; x ++) {
  51. f->Vertices[0] = v+x+y*divrad;
  52. f->MappingU[0] = U;
  53. f->MappingV[0] = V;
  54. f->Vertices[1] = v+(x+1==divrad?0:x+1)+y*divrad;
  55. f->MappingU[1] = U;
  56. f->MappingV[1] = V+dV;
  57. f->Vertices[2] = v+x+(y+1==divrot?0:(y+1)*divrad);
  58. f->MappingU[2] = U+dU;
  59. f->MappingV[2] = V;
  60. f->Material = m;
  61. f++;
  62. f->Vertices[0] = v+x+(y+1==divrot?0:(y+1)*divrad);
  63. f->MappingU[0] = U+dU;
  64. f->MappingV[0] = V;
  65. f->Vertices[1] = v+(x+1==divrad?0:x+1)+y*divrad;
  66. f->MappingU[1] = U;
  67. f->MappingV[1] = V+dV;
  68. f->Vertices[2] = v+(x+1==divrad?0:x+1)+(y+1==divrot?0:(y+1)*divrad);
  69. f->MappingU[2] = U+dU;
  70. f->MappingV[2] = V+dV;
  71. f->Material = m;
  72. f++;
  73. V += dV;
  74. }
  75. U += dU;
  76. }
  77. plObjCalcNormals(o);
  78. return (o);
  79. }
  80. pl_Obj *plMakeSphere(pl_Float r, pl_uInt divr, pl_uInt divh, pl_Mat *m) {
  81. pl_Obj *o;
  82. pl_Vertex *v;
  83. pl_Face *f;
  84. pl_uInt x, y;
  85. double a, da, yp, ya, yda, yf;
  86. pl_sInt32 U,V,dU,dV;
  87. if (divh < 3) divh = 3;
  88. if (divr < 3) divr = 3;
  89. o = plObjCreate(2+(divh-2)*(divr),2*divr+(divh-3)*divr*2);
  90. if (!o) return 0;
  91. v = o->Vertices;
  92. v->x = v->z = 0.0; v->y = r; v++;
  93. v->x = v->z = 0.0; v->y = -r; v++;
  94. ya = 0.0;
  95. yda = PL_PI/(divh-1);
  96. da = (PL_PI*2.0)/divr;
  97. for (y = 0; y < divh - 2; y ++) {
  98. ya += yda;
  99. yp = cos((double) ya)*r;
  100. yf = sin((double) ya)*r;
  101. a = 0.0;
  102. for (x = 0; x < divr; x ++) {
  103. v->y = (pl_Float) yp;
  104. v->x = (pl_Float) (cos((double) a)*yf);
  105. v->z = (pl_Float) (sin((double) a)*yf);
  106. v++;
  107. a += da;
  108. }
  109. }
  110. f = o->Faces;
  111. v = o->Vertices + 2;
  112. a = 0.0;
  113. U = 0;
  114. dU = 65535/divr;
  115. dV = V = 65535/divh;
  116. for (x = 0; x < divr; x ++) {
  117. f->Vertices[0] = o->Vertices;
  118. f->Vertices[1] = v + (x+1==divr ? 0 : x+1);
  119. f->Vertices[2] = v + x;
  120. f->MappingU[0] = U;
  121. f->MappingV[0] = 0;
  122. f->MappingU[1] = U+dU;
  123. f->MappingV[1] = V;
  124. f->MappingU[2] = U;
  125. f->MappingV[2] = V;
  126. f->Material = m;
  127. f++;
  128. U += dU;
  129. }
  130. da = 1.0/(divr+1);
  131. v = o->Vertices + 2;
  132. for (x = 0; x < (divh-3); x ++) {
  133. U = 0;
  134. for (y = 0; y < divr; y ++) {
  135. f->Vertices[0] = v+y;
  136. f->Vertices[1] = v+divr+(y+1==divr?0:y+1);
  137. f->Vertices[2] = v+y+divr;
  138. f->MappingU[0] = U;
  139. f->MappingV[0] = V;
  140. f->MappingU[1] = U+dU;
  141. f->MappingV[1] = V+dV;
  142. f->MappingU[2] = U;
  143. f->MappingV[2] = V+dV;
  144. f->Material = m; f++;
  145. f->Vertices[0] = v+y;
  146. f->Vertices[1] = v+(y+1==divr?0:y+1);
  147. f->Vertices[2] = v+(y+1==divr?0:y+1)+divr;
  148. f->MappingU[0] = U;
  149. f->MappingV[0] = V;
  150. f->MappingU[1] = U+dU;
  151. f->MappingV[1] = V;
  152. f->MappingU[2] = U+dU;
  153. f->MappingV[2] = V+dV;
  154. f->Material = m; f++;
  155. U += dU;
  156. }
  157. V += dV;
  158. v += divr;
  159. }
  160. v = o->Vertices + o->NumVertices - divr;
  161. U = 0;
  162. for (x = 0; x < divr; x ++) {
  163. f->Vertices[0] = o->Vertices + 1;
  164. f->Vertices[1] = v + x;
  165. f->Vertices[2] = v + (x+1==divr ? 0 : x+1);
  166. f->MappingU[0] = U;
  167. f->MappingV[0] = 65535;
  168. f->MappingU[1] = U;
  169. f->MappingV[1] = V;
  170. f->MappingU[2] = U+dU;
  171. f->MappingV[2] = V;
  172. f->Material = m;
  173. f++;
  174. U += dU;
  175. }
  176. plObjCalcNormals(o);
  177. return (o);
  178. }
  179. pl_Obj *plMakeCylinder(pl_Float r, pl_Float h, pl_uInt divr, pl_Bool captop,
  180. pl_Bool capbottom, pl_Mat *m) {
  181. pl_Obj *o;
  182. pl_Vertex *v, *topverts, *bottomverts, *topcapvert=0, *bottomcapvert=0;
  183. pl_Face *f;
  184. pl_uInt32 i;
  185. double a, da;
  186. if (divr < 3) divr = 3;
  187. o = plObjCreate(divr*2+((divr==3)?0:(captop?1:0)+(capbottom?1:0)),
  188. divr*2+(divr==3 ? (captop ? 1 : 0) + (capbottom ? 1 : 0) :
  189. (captop ? divr : 0) + (capbottom ? divr : 0)));
  190. if (!o) return 0;
  191. a = 0.0;
  192. da = (2.0*PL_PI)/divr;
  193. v = o->Vertices;
  194. topverts = v;
  195. for (i = 0; i < divr; i ++) {
  196. v->y = h/2.0f;
  197. v->x = (pl_Float) (r*cos((double) a));
  198. v->z = (pl_Float)(r*sin(a));
  199. v->xformedx = (pl_Float) (32768.0 + (32768.0*cos((double) a))); // temp
  200. v->xformedy = (pl_Float) (32768.0 + (32768.0*sin((double) a))); // use xf
  201. v++;
  202. a += da;
  203. }
  204. bottomverts = v;
  205. a = 0.0;
  206. for (i = 0; i < divr; i ++) {
  207. v->y = -h/2.0f;
  208. v->x = (pl_Float) (r*cos((double) a));
  209. v->z = (pl_Float) (r*sin(a));
  210. v->xformedx = (pl_Float) (32768.0 + (32768.0*cos((double) a)));
  211. v->xformedy = (pl_Float) (32768.0 + (32768.0*sin((double) a)));
  212. v++; a += da;
  213. }
  214. if (captop && divr != 3) {
  215. topcapvert = v;
  216. v->y = h / 2.0f;
  217. v->x = v->z = 0.0f;
  218. v++;
  219. }
  220. if (capbottom && divr != 3) {
  221. bottomcapvert = v;
  222. v->y = -h / 2.0f;
  223. v->x = v->z = 0.0f;
  224. v++;
  225. }
  226. f = o->Faces;
  227. for (i = 0; i < divr; i ++) {
  228. f->Vertices[0] = bottomverts + i;
  229. f->Vertices[1] = topverts + i;
  230. f->Vertices[2] = bottomverts + (i == divr-1 ? 0 : i+1);
  231. f->MappingV[0] = f->MappingV[2] = 65535; f->MappingV[1] = 0;
  232. f->MappingU[0] = f->MappingU[1] = (i<<16)/divr;
  233. f->MappingU[2] = ((i+1)<<16)/divr;
  234. f->Material = m; f++;
  235. f->Vertices[0] = bottomverts + (i == divr-1 ? 0 : i+1);
  236. f->Vertices[1] = topverts + i;
  237. f->Vertices[2] = topverts + (i == divr-1 ? 0 : i+1);
  238. f->MappingV[1] = f->MappingV[2] = 0; f->MappingV[0] = 65535;
  239. f->MappingU[0] = f->MappingU[2] = ((i+1)<<16)/divr;
  240. f->MappingU[1] = (i<<16)/divr;
  241. f->Material = m; f++;
  242. }
  243. if (captop) {
  244. if (divr == 3) {
  245. f->Vertices[0] = topverts + 0;
  246. f->Vertices[1] = topverts + 2;
  247. f->Vertices[2] = topverts + 1;
  248. f->MappingU[0] = (pl_sInt32) topverts[0].xformedx;
  249. f->MappingV[0] = (pl_sInt32) topverts[0].xformedy;
  250. f->MappingU[1] = (pl_sInt32) topverts[1].xformedx;
  251. f->MappingV[1] = (pl_sInt32) topverts[1].xformedy;
  252. f->MappingU[2] = (pl_sInt32) topverts[2].xformedx;
  253. f->MappingV[2] = (pl_sInt32) topverts[2].xformedy;
  254. f->Material = m; f++;
  255. } else {
  256. for (i = 0; i < divr; i ++) {
  257. f->Vertices[0] = topverts + (i == divr-1 ? 0 : i + 1);
  258. f->Vertices[1] = topverts + i;
  259. f->Vertices[2] = topcapvert;
  260. f->MappingU[0] = (pl_sInt32) topverts[(i==divr-1?0:i+1)].xformedx;
  261. f->MappingV[0] = (pl_sInt32) topverts[(i==divr-1?0:i+1)].xformedy;
  262. f->MappingU[1] = (pl_sInt32) topverts[i].xformedx;
  263. f->MappingV[1] = (pl_sInt32) topverts[i].xformedy;
  264. f->MappingU[2] = f->MappingV[2] = 32768;
  265. f->Material = m; f++;
  266. }
  267. }
  268. }
  269. if (capbottom) {
  270. if (divr == 3) {
  271. f->Vertices[0] = bottomverts + 0;
  272. f->Vertices[1] = bottomverts + 1;
  273. f->Vertices[2] = bottomverts + 2;
  274. f->MappingU[0] = (pl_sInt32) bottomverts[0].xformedx;
  275. f->MappingV[0] = (pl_sInt32) bottomverts[0].xformedy;
  276. f->MappingU[1] = (pl_sInt32) bottomverts[1].xformedx;
  277. f->MappingV[1] = (pl_sInt32) bottomverts[1].xformedy;
  278. f->MappingU[2] = (pl_sInt32) bottomverts[2].xformedx;
  279. f->MappingV[2] = (pl_sInt32) bottomverts[2].xformedy;
  280. f->Material = m; f++;
  281. } else {
  282. for (i = 0; i < divr; i ++) {
  283. f->Vertices[0] = bottomverts + i;
  284. f->Vertices[1] = bottomverts + (i == divr-1 ? 0 : i + 1);
  285. f->Vertices[2] = bottomcapvert;
  286. f->MappingU[0] = (pl_sInt32) bottomverts[i].xformedx;
  287. f->MappingV[0] = (pl_sInt32) bottomverts[i].xformedy;
  288. f->MappingU[1] = (pl_sInt32) bottomverts[(i==divr-1?0:i+1)].xformedx;
  289. f->MappingV[1] = (pl_sInt32) bottomverts[(i==divr-1?0:i+1)].xformedy;
  290. f->MappingU[2] = f->MappingV[2] = 32768;
  291. f->Material = m; f++;
  292. }
  293. }
  294. }
  295. plObjCalcNormals(o);
  296. return (o);
  297. }
  298. pl_Obj *plMakeCone(pl_Float r, pl_Float h, pl_uInt div,
  299. pl_Bool cap, pl_Mat *m) {
  300. pl_Obj *o;
  301. pl_Vertex *v;
  302. pl_Face *f;
  303. pl_uInt32 i;
  304. double a, da;
  305. if (div < 3) div = 3;
  306. o = plObjCreate(div + (div == 3 ? 1 : (cap ? 2 : 1)),
  307. div + (div == 3 ? 1 : (cap ? div : 0)));
  308. if (!o) return 0;
  309. v = o->Vertices;
  310. v->x = v->z = 0; v->y = h/2;
  311. v->xformedx = 1<<15;
  312. v->xformedy = 1<<15;
  313. v++;
  314. a = 0.0;
  315. da = (2.0*PL_PI)/div;
  316. for (i = 1; i <= div; i ++) {
  317. v->y = h/-2.0f;
  318. v->x = (pl_Float) (r*cos((double) a));
  319. v->z = (pl_Float) (r*sin((double) a));
  320. v->xformedx = (pl_Float) (32768.0 + (cos((double) a)*32768.0));
  321. v->xformedy = (pl_Float) (32768.0 + (sin((double) a)*32768.0));
  322. a += da;
  323. v++;
  324. }
  325. if (cap && div != 3) {
  326. v->y = h / -2.0f;
  327. v->x = v->z = 0.0f;
  328. v->xformedx = (pl_Float) (1<<15);
  329. v->xformedy = (pl_Float) (1<<15);
  330. v++;
  331. }
  332. f = o->Faces;
  333. for (i = 1; i <= div; i ++) {
  334. f->Vertices[0] = o->Vertices;
  335. f->Vertices[1] = o->Vertices + (i == div ? 1 : i + 1);
  336. f->Vertices[2] = o->Vertices + i;
  337. f->MappingU[0] = (pl_sInt32) o->Vertices[0].xformedx;
  338. f->MappingV[0] = (pl_sInt32) o->Vertices[0].xformedy;
  339. f->MappingU[1] = (pl_sInt32) o->Vertices[(i==div?1:i+1)].xformedx;
  340. f->MappingV[1] = (pl_sInt32) o->Vertices[(i==div?1:i+1)].xformedy;
  341. f->MappingU[2] = (pl_sInt32) o->Vertices[i].xformedx;
  342. f->MappingV[2] = (pl_sInt32) o->Vertices[i].xformedy;
  343. f->Material = m;
  344. f++;
  345. }
  346. if (cap) {
  347. if (div == 3) {
  348. f->Vertices[0] = o->Vertices + 1;
  349. f->Vertices[1] = o->Vertices + 2;
  350. f->Vertices[2] = o->Vertices + 3;
  351. f->MappingU[0] = (pl_sInt32) o->Vertices[1].xformedx;
  352. f->MappingV[0] = (pl_sInt32) o->Vertices[1].xformedy;
  353. f->MappingU[1] = (pl_sInt32) o->Vertices[2].xformedx;
  354. f->MappingV[1] = (pl_sInt32) o->Vertices[2].xformedy;
  355. f->MappingU[2] = (pl_sInt32) o->Vertices[3].xformedx;
  356. f->MappingV[2] = (pl_sInt32) o->Vertices[3].xformedy;
  357. f->Material = m;
  358. f++;
  359. } else {
  360. for (i = 1; i <= div; i ++) {
  361. f->Vertices[0] = o->Vertices + div + 1;
  362. f->Vertices[1] = o->Vertices + i;
  363. f->Vertices[2] = o->Vertices + (i==div ? 1 : i+1);
  364. f->MappingU[0] = (pl_sInt32) o->Vertices[div+1].xformedx;
  365. f->MappingV[0] = (pl_sInt32) o->Vertices[div+1].xformedy;
  366. f->MappingU[1] = (pl_sInt32) o->Vertices[i].xformedx;
  367. f->MappingV[1] = (pl_sInt32) o->Vertices[i].xformedy;
  368. f->MappingU[2] = (pl_sInt32) o->Vertices[i==div?1:i+1].xformedx;
  369. f->MappingV[2] = (pl_sInt32) o->Vertices[i==div?1:i+1].xformedy;
  370. f->Material = m;
  371. f++;
  372. }
  373. }
  374. }
  375. plObjCalcNormals(o);
  376. return (o);
  377. }
  378. static pl_uChar verts[6*6] = {
  379. 0,4,1, 1,4,5, 0,1,2, 3,2,1, 2,3,6, 3,7,6,
  380. 6,7,4, 4,7,5, 1,7,3, 7,1,5, 2,6,0, 4,0,6
  381. };
  382. static pl_uChar map[24*2*3] = {
  383. 1,0, 1,1, 0,0, 0,0, 1,1, 0,1,
  384. 0,0, 1,0, 0,1, 1,1, 0,1, 1,0,
  385. 0,0, 1,0, 0,1, 1,0, 1,1, 0,1,
  386. 0,0, 1,0, 0,1, 0,1, 1,0, 1,1,
  387. 1,0, 0,1, 0,0, 0,1, 1,0, 1,1,
  388. 1,0, 1,1, 0,0, 0,1, 0,0, 1,1
  389. };
  390. pl_Obj *plMakeBox(pl_Float w, pl_Float d, pl_Float h, pl_Mat *m) {
  391. pl_uChar *mm = map;
  392. pl_uChar *vv = verts;
  393. pl_Obj *o;
  394. pl_Vertex *v;
  395. pl_Face *f;
  396. pl_uInt x;
  397. o = plObjCreate(8,12);
  398. if (!o) return 0;
  399. v = o->Vertices;
  400. v->x = -w/2; v->y = h/2; v->z = d/2; v++;
  401. v->x = w/2; v->y = h/2; v->z = d/2; v++;
  402. v->x = -w/2; v->y = h/2; v->z = -d/2; v++;
  403. v->x = w/2; v->y = h/2; v->z = -d/2; v++;
  404. v->x = -w/2; v->y = -h/2; v->z = d/2; v++;
  405. v->x = w/2; v->y = -h/2; v->z = d/2; v++;
  406. v->x = -w/2; v->y = -h/2; v->z = -d/2; v++;
  407. v->x = w/2; v->y = -h/2; v->z = -d/2; v++;
  408. f = o->Faces;
  409. for (x = 0; x < 12; x ++) {
  410. f->Vertices[0] = o->Vertices + *vv++;
  411. f->Vertices[1] = o->Vertices + *vv++;
  412. f->Vertices[2] = o->Vertices + *vv++;
  413. f->MappingU[0] = (pl_sInt32) ((double)*mm++ * 65535.0);
  414. f->MappingV[0] = (pl_sInt32) ((double)*mm++ * 65535.0);
  415. f->MappingU[1] = (pl_sInt32) ((double)*mm++ * 65535.0);
  416. f->MappingV[1] = (pl_sInt32) ((double)*mm++ * 65535.0);
  417. f->MappingU[2] = (pl_sInt32) ((double)*mm++ * 65535.0);
  418. f->MappingV[2] = (pl_sInt32) ((double)*mm++ * 65535.0);
  419. f->Material = m;
  420. f++;
  421. }
  422. plObjCalcNormals(o);
  423. return (o);
  424. }
  425. pl_Obj *plMakePlane(pl_Float w, pl_Float d, pl_uInt res, pl_Mat *m) {
  426. pl_Obj *o;
  427. pl_Vertex *v;
  428. pl_Face *f;
  429. pl_uInt x, y;
  430. o = plObjCreate((res+1)*(res+1),res*res*2);
  431. if (!o) return 0;
  432. v = o->Vertices;
  433. for (y = 0; y <= res; y ++) {
  434. for (x = 0; x <= res; x ++) {
  435. v->y = 0;
  436. v->x = ((x*w)/res) - w/2;
  437. v->z = ((y*d)/res) - d/2;
  438. v++;
  439. }
  440. }
  441. f = o->Faces;
  442. for (y = 0; y < res; y ++) {
  443. for (x = 0; x < res; x ++) {
  444. f->Vertices[0] = o->Vertices + x+(y*(res+1));
  445. f->MappingU[0] = (x<<16)/res;
  446. f->MappingV[0] = (y<<16)/res;
  447. f->Vertices[2] = o->Vertices + x+1+(y*(res+1));
  448. f->MappingU[2] = ((x+1)<<16)/res;
  449. f->MappingV[2] = (y<<16)/res;
  450. f->Vertices[1] = o->Vertices + x+((y+1)*(res+1));
  451. f->MappingU[1] = (x<<16)/res;
  452. f->MappingV[1] = ((y+1)<<16)/res;
  453. f->Material = m;
  454. f++;
  455. f->Vertices[0] = o->Vertices + x+((y+1)*(res+1));
  456. f->MappingU[0] = (x<<16)/res;
  457. f->MappingV[0] = ((y+1)<<16)/res;
  458. f->Vertices[2] = o->Vertices + x+1+(y*(res+1));
  459. f->MappingU[2] = ((x+1)<<16)/res;
  460. f->MappingV[2] = (y<<16)/res;
  461. f->Vertices[1] = o->Vertices + x+1+((y+1)*(res+1));
  462. f->MappingU[1] = ((x+1)<<16)/res;
  463. f->MappingV[1] = ((y+1)<<16)/res;
  464. f->Material = m;
  465. f++;
  466. }
  467. }
  468. plObjCalcNormals(o);
  469. return (o);
  470. }