mathematics.cpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947
  1. #include "Hunt.h"
  2. Vector3d TraceA, TraceB, TraceNv;
  3. int TraceRes;
  4. //====================================================
  5. void NormVector(Vector3d& v, float Scale)
  6. {
  7. double n;
  8. n=v.x*v.x + v.y*v.y + v.z*v.z;
  9. if (n<0.000000001) n=0.000000001;
  10. n=(double)Scale / sqrt(n);
  11. v.x=v.x*n;
  12. v.y=v.y*n;
  13. v.z=v.z*n;
  14. }
  15. float SGN(float f)
  16. {
  17. if (f<0) return -1.f;
  18. else return 1.f;
  19. }
  20. void DeltaFunc(float &a, float b, float d)
  21. {
  22. if (b > a) {
  23. a+=d; if (a > b) a = b;
  24. } else {
  25. a-=d; if (a < b) a = b;
  26. }
  27. }
  28. void MulVectorsScal(Vector3d& v1,Vector3d& v2, float& r)
  29. {
  30. r = v1.x*v2.x + v1.y*v2.y + v1.z*v2.z;
  31. }
  32. void MulVectorsVect(Vector3d& v1, Vector3d& v2, Vector3d& r )
  33. {
  34. r.x= v1.y*v2.z - v2.y*v1.z;
  35. r.y=-v1.x*v2.z + v2.x*v1.z;
  36. r.z= v1.x*v2.y - v2.x*v1.y;
  37. }
  38. Vector3d RotateVector(Vector3d& v)
  39. {
  40. Vector3d vv;
  41. float vx = v.x * ca + v.z * sa;
  42. float vz = v.z * ca - v.x * sa;
  43. float vy = v.y;
  44. vv.x = vx;
  45. vv.y = vy * cb - vz * sb;
  46. vv.z = vz * cb + vy * sb;
  47. return vv;
  48. }
  49. Vector3d SubVectors( Vector3d& v1, Vector3d& v2 )
  50. {
  51. Vector3d res;
  52. res.x = v1.x-v2.x;
  53. res.y = v1.y-v2.y;
  54. res.z = v1.z-v2.z;
  55. return res;
  56. }
  57. Vector3d AddVectors( Vector3d& v1, Vector3d& v2 )
  58. {
  59. Vector3d res;
  60. res.x = v1.x+v2.x;
  61. res.y = v1.y+v2.y;
  62. res.z = v1.z+v2.z;
  63. return res;
  64. }
  65. float VectorLength(Vector3d v)
  66. {
  67. return (float)sqrt(v.x*v.x + v.y*v.y + v.z*v.z);
  68. }
  69. int siRand(int R)
  70. {
  71. return (rand() * (R * 2 +1)) / RAND_MAX - R;
  72. }
  73. int rRand(int r)
  74. {
  75. if (!r) return 0;
  76. int res = rand() % (r+1);// / (RAND_MAX);
  77. //if (res > r) res = r;
  78. return res;
  79. }
  80. void CalcHitPoint(CLIPPLANE& C, Vector3d& a, Vector3d& b, Vector3d& hp)
  81. {
  82. float SCLN,SCVN;
  83. Vector3d lv = SubVectors(b,a);
  84. NormVector(lv, 1.0);
  85. MulVectorsScal(a, C.nv, SCLN);
  86. MulVectorsScal(lv,C.nv, SCVN);
  87. SCLN/=SCVN; SCLN=(float)fabs(SCLN);
  88. hp.x = a.x + lv.x * SCLN;
  89. hp.y = a.y + lv.y * SCLN;
  90. hp.z = a.z + lv.z * SCLN;
  91. }
  92. float PointToVectorD(Vector3d A, Vector3d AB, Vector3d C)
  93. {
  94. Vector3d AC = SubVectors(C,A);
  95. Vector3d vm;
  96. MulVectorsVect(AB, AC, vm);
  97. return VectorLength(vm);
  98. }
  99. float Mul2dVectors(float vx, float vy, float ux, float uy)
  100. {
  101. return vx*uy - ux*vy;
  102. }
  103. float FindVectorAlpha(float vx, float vy)
  104. {
  105. float adx, ady, alpha, dalpha;
  106. adx=(float)fabs(vx);
  107. ady=(float)fabs(vy);
  108. alpha = pi / 4.f;
  109. dalpha = pi / 8.f;
  110. for (int i=1; i<=10; i++) {
  111. alpha=alpha-dalpha*SGN(Mul2dVectors(adx,ady, (float)cos(alpha), (float)sin(alpha)));
  112. dalpha/=2;
  113. }
  114. if (vx<0) if (vy<0) alpha+=pi; else alpha=pi-alpha;
  115. else if (vy<0) alpha=2.f*pi-alpha;
  116. return alpha;
  117. }
  118. void CheckBoundCollision(float &px, float &py, float cx, float cy, float oy, TBound *bound, int angle)
  119. {
  120. float ppx=px-cx;
  121. float ppy=py-cy;
  122. float ca = (float) cos(angle*pi / 2.f);
  123. float sa = (float) sin(angle*pi / 2.f);
  124. float w,h;
  125. for (int o=0; o<8; o++) {
  126. if (bound[o].a<0) continue;
  127. if (bound[o].y2 + oy < PlayerY + 128) continue;
  128. if (bound[o].y1 + oy > PlayerY + 256) continue;
  129. float ccx = bound[o].cx*ca + bound[o].cy*sa;
  130. float ccy = bound[o].cy*ca - bound[o].cx*sa;
  131. if (angle & 1) {
  132. w = bound[o].b+2.f;
  133. h = bound[o].a+2.f;
  134. } else {
  135. w = bound[o].a+2.f;
  136. h = bound[o].b+2.f;
  137. }
  138. float dw = fabs(ppx - ccx) - w;
  139. float dh = fabs(ppy - ccy) - h;
  140. if ( (dw > 0) || (dh > 0) ) continue;
  141. if (dw > dh) {
  142. px = cx+ccx + w * SGN(ppx-ccx);
  143. } else {
  144. py = cy+ccy + h * SGN(ppy-ccy);
  145. }
  146. }
  147. }
  148. void CheckCollision(float &cx, float &cz)
  149. {
  150. if (cx < 36*256) cx = 36*256;
  151. if (cz < 36*256) cz = 36*256;
  152. if (cx >980*256) cx =980*256;
  153. if (cz >980*256) cz =980*256;
  154. int ccx = (int)cx / 256;
  155. int ccz = (int)cz / 256;
  156. for (int z=-4; z<=4; z++)
  157. for (int x=-4; x<=4; x++)
  158. if (OMap[ccz+z][ccx+x]!=255) {
  159. int ob = OMap[ccz+z][ccx+x];
  160. float CR = (float)MObjects[ob].info.Radius;
  161. float oz = (ccz+z) * 256.f + 128.f;
  162. float ox = (ccx+x) * 256.f + 128.f;
  163. float LandY = GetLandOH(ccx+x, ccz+z);
  164. if (!(MObjects[ob].info.flags & ofBOUND)) {
  165. if (MObjects[ob].info.YHi + LandY < PlayerY + 128) continue;
  166. if (MObjects[ob].info.YLo + LandY > PlayerY + 256) continue;
  167. }
  168. if (MObjects[ob].info.flags & ofBOUND) {
  169. CheckBoundCollision(cx, cz, ox, oz, LandY, MObjects[ob].bound, ((FMap[ccz+z][ccx+x] >> 2) & 3) );
  170. }
  171. else
  172. if (MObjects[ob].info.flags & ofCIRCLE) {
  173. float r = (float) sqrt( (ox-cx)*(ox-cx) + (oz-cz)*(oz-cz) );
  174. if (r<CR) {
  175. cx = cx - (ox - cx) * (CR-r)/r;
  176. cz = cz - (oz - cz) * (CR-r)/r; }
  177. } else {
  178. float r = (float) max( fabs(ox-cx) , fabs(oz-cz) );
  179. if (r<CR) {
  180. if (fabs(ox-cx) > fabs(oz-cz) )
  181. cx = cx - (ox - cx) * (CR-r)/r;
  182. else
  183. cz = cz - (oz - cz) * (CR-r)/r;
  184. }
  185. }
  186. }
  187. if (!TrophyMode) return;
  188. for (int c=0; c<ChCount; c++) {
  189. float px = Characters[c].pos.x;
  190. float pz = Characters[c].pos.z;
  191. float CR = DinoInfo[ Characters[c].CType ].Radius;
  192. float r = (float) sqrt( (px-cx)*(px-cx) + (pz-cz)*(pz-cz) );
  193. if (r<CR) {
  194. cx = cx - (px - cx) * (CR-r)/r;
  195. cz = cz - (pz - cz) * (CR-r)/r;
  196. }
  197. }
  198. }
  199. int TraceCheckPlane(Vector3d a, Vector3d b, Vector3d c)
  200. {
  201. Vector3d pnv,hp;
  202. float sa, sb;
  203. MulVectorsVect(SubVectors(b,a), SubVectors(c,a), pnv);
  204. NormVector(pnv, 1.f);
  205. MulVectorsScal(SubVectors(TraceA,a), pnv, sa);
  206. MulVectorsScal(SubVectors(TraceB,a), pnv, sb);
  207. if (sa*sb>-1.f) return 0;
  208. //========= calc hit point =======//
  209. float SCLN,SCVN;
  210. MulVectorsScal(SubVectors(TraceA,a), pnv, SCLN);
  211. MulVectorsScal(TraceNv, pnv, SCVN);
  212. SCLN/=SCVN; SCLN=(float)fabs(SCLN);
  213. hp.x = TraceA.x + TraceNv.x * SCLN;
  214. hp.y = TraceA.y + TraceNv.y * SCLN;
  215. hp.z = TraceA.z + TraceNv.z * SCLN;
  216. Vector3d vm;
  217. MulVectorsVect( SubVectors(b,a), SubVectors(hp,a), vm);
  218. MulVectorsScal( vm, pnv, sa); if (sa<0) return 0;
  219. MulVectorsVect( SubVectors(c,b), SubVectors(hp,b), vm);
  220. MulVectorsScal( vm, pnv, sa); if (sa<0) return 0;
  221. MulVectorsVect( SubVectors(a,c), SubVectors(hp,c), vm);
  222. MulVectorsScal( vm, pnv, sa); if (sa<0) return 0;
  223. if (VectorLength(SubVectors(hp, TraceA)) <
  224. VectorLength(SubVectors(TraceB, TraceA)) ) {
  225. TraceB = hp;
  226. return 1; }
  227. return 0;
  228. }
  229. void TraceModel(int xx, int zz, int o)
  230. {
  231. TModel *mptr = MObjects[o].model;
  232. v[0].x = xx * 256.f + 128.f;
  233. v[0].z = zz * 256.f + 128.f;
  234. v[0].y = (float)(HMapO[zz][xx]) * ctHScale;
  235. v[0].y+=700.f;
  236. if (PointToVectorD(TraceA, TraceNv, v[0]) >1400.f) return;
  237. v[0].y-=700.f;
  238. float malp = (float)((FMap[zz][xx] >> 2) & 7) * 2.f*pi / 8.f;
  239. float ca = (float)cos(malp);
  240. float sa = (float)sin(malp);
  241. for (int vv=0; vv<mptr->VCount; vv++) {
  242. rVertex[vv].x = mptr->gVertex[vv].x * ca + mptr->gVertex[vv].z * sa + v[0].x;
  243. rVertex[vv].y = mptr->gVertex[vv].y + v[0].y;
  244. rVertex[vv].z = mptr->gVertex[vv].z * ca - mptr->gVertex[vv].x * sa + v[0].z;
  245. }
  246. for (int f=0; f<mptr->FCount; f++) {
  247. TFace *fptr = &mptr->gFace[f];
  248. if (fptr->Flags & (sfOpacity + sfTransparent) ) continue;
  249. v[0] = rVertex[fptr->v1];
  250. v[1] = rVertex[fptr->v2];
  251. v[2] = rVertex[fptr->v3];
  252. if (TraceCheckPlane(v[0], v[1], v[2]) )
  253. TraceRes = tresModel;
  254. }
  255. }
  256. void TraceCharacter(int c)
  257. {
  258. TCharacter *cptr = &Characters[c];
  259. if (PointToVectorD(TraceA, TraceNv, cptr->pos) > 1024.f) return;
  260. TModel *mptr = cptr->pinfo->mptr;
  261. CreateChMorphedModel(cptr);
  262. float ca = (float)cos(-cptr->alpha + pi / 2.f);
  263. float sa = (float)sin(-cptr->alpha + pi / 2.f);
  264. for (int vv=0; vv<mptr->VCount; vv++) {
  265. rVertex[vv].x = mptr->gVertex[vv].x * ca + mptr->gVertex[vv].z * sa + cptr->pos.x;
  266. rVertex[vv].y = mptr->gVertex[vv].y + cptr->pos.y;
  267. rVertex[vv].z = mptr->gVertex[vv].z * ca - mptr->gVertex[vv].x * sa + cptr->pos.z;
  268. }
  269. for (int f=0; f<mptr->FCount; f++) {
  270. TFace *fptr = &mptr->gFace[f];
  271. if (fptr->Flags & (sfOpacity + sfTransparent) ) continue;
  272. v[0] = rVertex[fptr->v1];
  273. v[1] = rVertex[fptr->v2];
  274. v[2] = rVertex[fptr->v3];
  275. if (TraceCheckPlane(v[0], v[1], v[2]) ) {
  276. TraceRes = tresChar; ShotDino = c;
  277. if (fptr->Flags & sfMortal) TraceRes |= 0x8000;
  278. }
  279. }
  280. }
  281. void FillVGround(Vector3d &v, int xx, int zz)
  282. {
  283. v.x = xx*256.f;
  284. v.z = zz*256.f;
  285. v.y = (float)HMap[zz][xx]*ctHScale;
  286. }
  287. void FillWGround(Vector3d &v, int xx, int zz)
  288. {
  289. v.x = xx*256.f;
  290. v.z = zz*256.f;
  291. v.y = (float)WaterList[ WMap[zz][xx] ].wlevel*ctHScale;
  292. }
  293. int TraceLook(float ax, float ay, float az,
  294. float bx, float by, float bz)
  295. {
  296. TraceA.x = ax; TraceA.y = ay; TraceA.z = az;
  297. TraceB.x = bx; TraceB.y = by; TraceB.z = bz;
  298. TraceNv = SubVectors(TraceB, TraceA);
  299. Vector3d TraceNvP;
  300. TraceNvP = TraceNv;
  301. TraceNvP.y = 0;
  302. NormVector(TraceNv, 1.0f);
  303. NormVector(TraceNvP, 1.0f);
  304. ObjectsOnLook=0;
  305. int axi = (int)(ax/256.f);
  306. int azi = (int)(az/256.f);
  307. int bxi = (int)(bx/256.f);
  308. int bzi = (int)(bz/256.f);
  309. int xm1 = min(axi, bxi) - 2;
  310. int xm2 = max(axi, bxi) + 2;
  311. int zm1 = min(azi, bzi) - 2;
  312. int zm2 = max(azi, bzi) + 2;
  313. //======== trace ground model and static objects ============//
  314. for (int zz=zm1; zz<=zm2; zz++)
  315. for (int xx=xm1; xx<=xm2; xx++) {
  316. if (xx<2 || xx>1010) continue;
  317. if (zz<2 || zz>1010) continue;
  318. BOOL ReverseOn = (FMap[zz][xx] & fmReverse);
  319. FillVGround(v[0], xx, zz);
  320. FillVGround(v[1], xx+1, zz);
  321. if (ReverseOn) FillVGround(v[2], xx, zz+1);
  322. else FillVGround(v[2], xx+1, zz+1);
  323. if (TraceCheckPlane(v[0], v[1], v[2])) return 1;
  324. if (ReverseOn) { v[0] = v[2]; FillVGround(v[2], xx+1, zz+1); }
  325. else { v[1] = v[2]; FillVGround(v[2], xx, zz+1); }
  326. if (TraceCheckPlane(v[0], v[1], v[2])) return 1;
  327. int o = OMap[zz][xx];
  328. if ( o!=255) {
  329. float s1,s2;
  330. v[0].x = xx * 256.f + 128.f;
  331. v[0].z = zz * 256.f + 128.f;
  332. v[0].y = TraceB.y;
  333. MulVectorsScal( SubVectors(v[0], TraceB), TraceNv, s1); s1*=-1;
  334. v[0].y = TraceA.y;
  335. MulVectorsScal( SubVectors(v[0], TraceA), TraceNv, s2);
  336. if (s1>0 && s2>0)
  337. if (PointToVectorD(TraceA, TraceNvP, v[0]) < 180.f) {
  338. ObjectsOnLook++;
  339. if (MObjects[o].info.Radius > 32) ObjectsOnLook++;
  340. }
  341. }
  342. }
  343. return 0;
  344. }
  345. int TraceShot(float ax, float ay, float az,
  346. float &bx, float &by, float &bz)
  347. {
  348. TraceA.x = ax; TraceA.y = ay; TraceA.z = az;
  349. TraceB.x = bx; TraceB.y = by; TraceB.z = bz;
  350. TraceNv = SubVectors(TraceB, TraceA);
  351. NormVector(TraceNv, 1.0f);
  352. TraceRes = -1;
  353. int axi = (int)(ax/256.f);
  354. int azi = (int)(az/256.f);
  355. int bxi = (int)(bx/256.f);
  356. int bzi = (int)(bz/256.f);
  357. int xm1 = min(axi, bxi) - 2;
  358. int xm2 = max(axi, bxi) + 2;
  359. int zm1 = min(azi, bzi) - 2;
  360. int zm2 = max(azi, bzi) + 2;
  361. //======== trace ground model and static objects ============//
  362. for (int zz=zm1; zz<=zm2; zz++)
  363. for (int xx=xm1; xx<=xm2; xx++) {
  364. if (xx<2 || xx>1010) continue;
  365. if (zz<2 || zz>1010) continue;
  366. BOOL ReverseOn = (FMap[zz][xx] & fmReverse);
  367. FillVGround(v[0], xx, zz);
  368. FillVGround(v[1], xx+1, zz);
  369. if (ReverseOn) FillVGround(v[2], xx, zz+1);
  370. else FillVGround(v[2], xx+1, zz+1);
  371. if (TraceCheckPlane(v[0], v[1], v[2])) TraceRes = tresGround;
  372. if (ReverseOn) { v[0] = v[2]; FillVGround(v[2], xx+1, zz+1); }
  373. else { v[1] = v[2]; FillVGround(v[2], xx, zz+1); }
  374. if (TraceCheckPlane(v[0], v[1], v[2])) TraceRes = tresGround;
  375. if ( (FMap[zz][xx] & fmWaterA)>0) {
  376. FillWGround(v[0], xx, zz);
  377. FillWGround(v[1], xx+1, zz);
  378. FillWGround(v[2], xx+1, zz+1);
  379. if (TraceCheckPlane(v[0], v[1], v[2])) TraceRes = tresWater;
  380. v[1] = v[2]; FillWGround(v[2], xx, zz+1);
  381. if (TraceCheckPlane(v[0], v[1], v[2])) TraceRes = tresWater;
  382. }
  383. if (OMap[zz][xx] !=255)
  384. TraceModel(xx, zz, OMap[zz][xx]);
  385. }
  386. //======== trace characters ============//
  387. for (int c=0; c<ChCount; c++)
  388. TraceCharacter(c);
  389. float l;
  390. if ((TraceRes & 0xFF)==tresChar) l = 32.f; else l=16.f;
  391. bx = TraceB.x - TraceNv.x * l;
  392. by = TraceB.y - TraceNv.y * l;
  393. bz = TraceB.z - TraceNv.z * l;
  394. return TraceRes;
  395. }
  396. void InitClips2()
  397. {
  398. ClipA.v1.x = - (float)sin(pi/4-0.11); // 0.741
  399. ClipA.v1.y = 0;
  400. ClipA.v1.z = (float)cos(pi/4-0.11); // 0.820
  401. ClipA.v2.x = 0; ClipA.v2.y = 1; ClipA.v2.z = 0;
  402. MulVectorsVect(ClipA.v1, ClipA.v2, ClipA.nv);
  403. ClipC.v1.x = + (float)sin(pi/4-0.11);
  404. ClipC.v1.y = 0;
  405. ClipC.v1.z = (float)cos(pi/4-0.11);
  406. ClipC.v2.x = 0; ClipC.v2.y =-1; ClipC.v2.z = 0;
  407. MulVectorsVect(ClipC.v1, ClipC.v2, ClipC.nv);
  408. ClipB.v1.x = 0;
  409. ClipB.v1.y = (float)sin(pi/5-.02);
  410. ClipB.v1.z = (float)cos(pi/5-.02);
  411. ClipB.v2.x = 1; ClipB.v2.y = 0; ClipB.v2.z = 0;
  412. MulVectorsVect(ClipB.v1, ClipB.v2, ClipB.nv);
  413. ClipD.v1.x = 0;
  414. ClipD.v1.y = - (float)sin(pi/5-.02);
  415. ClipD.v1.z = (float)cos(pi/5-.02);
  416. ClipD.v2.x =-1; ClipD.v2.y = 0; ClipD.v2.z = 0;
  417. MulVectorsVect(ClipD.v1, ClipD.v2, ClipD.nv);
  418. ClipZ.v1.x = 0; ClipZ.v1.y = 1; ClipZ.v1.z = 0;
  419. ClipZ.v2.x = 1; ClipZ.v2.y = 0; ClipZ.v2.z = 0;
  420. MulVectorsVect(ClipZ.v1, ClipZ.v2, ClipZ.nv);
  421. }
  422. void InitClips()
  423. {
  424. // float XFOV = atan(CameraW , VideoCX); //1.6
  425. // float YFOV = atan(CameraH , VideoCY);
  426. float xx = (VideoCX+1) / (CameraW);
  427. float yy = (VideoCY+2) / (CameraH);
  428. float LX = sqrt(1.0 + xx * xx);
  429. float LY = sqrt(1.0 + yy * yy);
  430. ClipA.v1.x = - (float)xx / LX;
  431. ClipA.v1.y = 0;
  432. ClipA.v1.z = (float)1 / LX;
  433. ClipA.v2.x = 0; ClipA.v2.y = 1; ClipA.v2.z = 0;
  434. MulVectorsVect(ClipA.v1, ClipA.v2, ClipA.nv);
  435. ClipC.v1.x = + (float)xx / LX;
  436. ClipC.v1.y = 0;
  437. ClipC.v1.z = (float)1 / LX;
  438. ClipC.v2.x = 0; ClipC.v2.y =-1; ClipC.v2.z = 0;
  439. MulVectorsVect(ClipC.v1, ClipC.v2, ClipC.nv);
  440. ClipB.v1.x = 0;
  441. ClipB.v1.y = (float)yy / LY;
  442. ClipB.v1.z = (float)1 / LY;
  443. ClipB.v2.x = 1; ClipB.v2.y = 0; ClipB.v2.z = 0;
  444. MulVectorsVect(ClipB.v1, ClipB.v2, ClipB.nv);
  445. ClipD.v1.x = 0;
  446. ClipD.v1.y = - (float)yy / LY;
  447. ClipD.v1.z = (float)1 / LY;
  448. ClipD.v2.x =-1; ClipD.v2.y = 0; ClipD.v2.z = 0;
  449. MulVectorsVect(ClipD.v1, ClipD.v2, ClipD.nv);
  450. ClipZ.v1.x = 0; ClipZ.v1.y = 1; ClipZ.v1.z = 0;
  451. ClipZ.v2.x = 1; ClipZ.v2.y = 0; ClipZ.v2.z = 0;
  452. MulVectorsVect(ClipZ.v1, ClipZ.v2, ClipZ.nv);
  453. ClipW.nv.x = 0;
  454. ClipW.nv.y = cb;
  455. ClipW.nv.z = sb;
  456. }
  457. void CalcLights(TModel* mptr)
  458. {
  459. int VCount = mptr->VCount;
  460. int FCount = mptr->FCount;
  461. int FUsed;
  462. float c;
  463. Vector3d norms[1024];
  464. Vector3d a, b, nv, rv;
  465. Vector3d slight;
  466. slight.x =-Sun3dPos.x;
  467. slight.y =-Sun3dPos.y/2;
  468. slight.z =-Sun3dPos.z;
  469. NormVector(slight, 1.0f);
  470. for (int f=0; f<FCount; f++) {
  471. int v1 = mptr->gFace[f].v1;
  472. int v2 = mptr->gFace[f].v2;
  473. int v3 = mptr->gFace[f].v3;
  474. a.x = mptr->gVertex[v2].x - mptr->gVertex[v1].x;
  475. a.y = mptr->gVertex[v2].y - mptr->gVertex[v1].y;
  476. a.z = mptr->gVertex[v2].z - mptr->gVertex[v1].z;
  477. b.x = mptr->gVertex[v3].x - mptr->gVertex[v1].x;
  478. b.y = mptr->gVertex[v3].y - mptr->gVertex[v1].y;
  479. b.z = mptr->gVertex[v3].z - mptr->gVertex[v1].z;
  480. MulVectorsVect(a, b, norms[f]);
  481. NormVector(norms[f], 1.0f);
  482. }
  483. for (int VT=0; VT<4; VT++) {
  484. float ca = (float)cos (VT * pi / 2);
  485. float sa = (float)sin (VT * pi / 2);
  486. for (int v=0; v<VCount; v++) {
  487. FUsed = 0;
  488. nv.x=0; nv.y=0; nv.z=0;
  489. for (f=0; f<FCount; f++)
  490. if (!(mptr->gFace[f].Flags & sfDoubleSide) )
  491. if (mptr->gFace[f].v1 == v || mptr->gFace[f].v2 == v || mptr->gFace[f].v3 == v )
  492. { FUsed++; nv = AddVectors(nv, norms[f]); }
  493. if (!FUsed) mptr->VLight[VT][v] = 0;
  494. else {
  495. NormVector(nv, 1.0f);
  496. rv.y = nv.y;
  497. rv.x = nv.x * sa + nv.z * ca;
  498. rv.z = nv.z * sa - nv.x * ca;
  499. MulVectorsScal(rv, slight, c);
  500. c = c * 64;
  501. //if (c>64) c=64;
  502. //if (c<-64) c=-64;
  503. mptr->VLight[VT][v] = c;
  504. }
  505. }
  506. }
  507. }
  508. /*
  509. void CalcGouraud(TModel* mptr, Vecto3d *nvs[])
  510. {
  511. int VCount = mptr->VCount;
  512. int FCount = mptr->FCount;
  513. int FUsed;
  514. float c;
  515. Vector3d norms[1024];
  516. Vector3d a, b, nv, rv;
  517. Vector3d slight;
  518. slight.x =-Sun3dPos.x;
  519. slight.y =-Sun3dPos.y;
  520. slight.z =-Sun3dPos.z;
  521. NormVector(slight, 1.0f);
  522. for (int f=0; f<FCount; f++) {
  523. int v1 = mptr->gFace[f].v1;
  524. int v2 = mptr->gFace[f].v2;
  525. int v3 = mptr->gFace[f].v3;
  526. a.x = mptr->gVertex[v2].x - mptr->gVertex[v1].x;
  527. a.y = mptr->gVertex[v2].y - mptr->gVertex[v1].y;
  528. a.z = mptr->gVertex[v2].z - mptr->gVertex[v1].z;
  529. b.x = mptr->gVertex[v3].x - mptr->gVertex[v1].x;
  530. b.y = mptr->gVertex[v3].y - mptr->gVertex[v1].y;
  531. b.z = mptr->gVertex[v3].z - mptr->gVertex[v1].z;
  532. MulVectorsVect(a, b, norms[f]);
  533. NormVector(norms[f], 1.0f);
  534. }
  535. for (int v=0; v<VCount; v++) {
  536. FUsed = 0;
  537. nv.x=0; nv.y=0; nv.z=0;
  538. for (f=0; f<FCount; f++)
  539. if (!(mptr->gFace[f].Flags & sfDoubleSide) )
  540. if (mptr->gFace[f].v1 == v || mptr->gFace[f].v2 == v || mptr->gFace[f].v3 == v )
  541. { FUsed++; nv = AddVectors(nv, norms[f]); }
  542. if (!FUsed) mptr->VLight[0][v] = 0;
  543. else {
  544. NormVector(nv, 1.0f);
  545. MulVectorsScal(nv, slight, c);
  546. if (c<0) c=0; c=(c-0.5)*2;
  547. c=c*c*c;
  548. c = c * 98;
  549. if (c>96) c=96;
  550. if (c<-96) c=-96;
  551. mptr->VLight[0][v] = c;
  552. }
  553. }
  554. }
  555. */
  556. void CalcGouraud(TModel* mptr, Vector3d *nvs)
  557. {
  558. int VCount = mptr->VCount;
  559. float c;
  560. Vector3d slight;
  561. slight.x =-Sun3dPos.x;
  562. slight.y =-Sun3dPos.y;
  563. slight.z =-Sun3dPos.z;
  564. NormVector(slight, 1.0f);
  565. for (int v=0; v<VCount; v++) {
  566. MulVectorsScal(nvs[v], slight, c);
  567. if (c<0) c=0; c=(c-0.5)*2;
  568. c=c*c*c;
  569. c = c * 96;
  570. if (c>96) c=96;
  571. if (c<-64) c=-64;
  572. mptr->VLight[0][v] = c;
  573. }
  574. }
  575. void CalcNormals(TModel* mptr, Vector3d *nvs)
  576. {
  577. int VCount = mptr->VCount;
  578. int FCount = mptr->FCount;
  579. float c;
  580. Vector3d a, b, nv, rv;
  581. FillMemory(nvs, 3*4*VCount, 0);
  582. for (int f=0; f<FCount; f++) {
  583. if (mptr->gFace[f].Flags & sfDoubleSide) continue;
  584. int v1 = mptr->gFace[f].v1;
  585. int v2 = mptr->gFace[f].v2;
  586. int v3 = mptr->gFace[f].v3;
  587. a.x = mptr->gVertex[v2].x - mptr->gVertex[v1].x;
  588. a.y = mptr->gVertex[v2].y - mptr->gVertex[v1].y;
  589. a.z = mptr->gVertex[v2].z - mptr->gVertex[v1].z;
  590. b.x = mptr->gVertex[v3].x - mptr->gVertex[v1].x;
  591. b.y = mptr->gVertex[v3].y - mptr->gVertex[v1].y;
  592. b.z = mptr->gVertex[v3].z - mptr->gVertex[v1].z;
  593. MulVectorsVect(a, b, nv);
  594. NormVector(nv, 1000.0f);
  595. nvs[v1]=AddVectors(nvs[v1], nv);
  596. nvs[v2]=AddVectors(nvs[v2], nv);
  597. nvs[v3]=AddVectors(nvs[v3], nv);
  598. }
  599. for (int v=0; v<VCount; v++)
  600. NormVector(nvs[v], 1.0);
  601. }
  602. /*
  603. void CalcNormals(TModel* mptr, Vector3d *nvs)
  604. {
  605. int VCount = mptr->VCount;
  606. int FCount = mptr->FCount;
  607. int FUsed;
  608. float c;
  609. Vector3d norms[1024];
  610. Vector3d a, b, nv, rv;
  611. Vector3d slight;
  612. slight.x =-Sun3dPos.x;
  613. slight.y =-Sun3dPos.y;
  614. slight.z =-Sun3dPos.z;
  615. NormVector(slight, 1.0f);
  616. for (int f=0; f<FCount; f++) {
  617. int v1 = mptr->gFace[f].v1;
  618. int v2 = mptr->gFace[f].v2;
  619. int v3 = mptr->gFace[f].v3;
  620. a.x = mptr->gVertex[v2].x - mptr->gVertex[v1].x;
  621. a.y = mptr->gVertex[v2].y - mptr->gVertex[v1].y;
  622. a.z = mptr->gVertex[v2].z - mptr->gVertex[v1].z;
  623. b.x = mptr->gVertex[v3].x - mptr->gVertex[v1].x;
  624. b.y = mptr->gVertex[v3].y - mptr->gVertex[v1].y;
  625. b.z = mptr->gVertex[v3].z - mptr->gVertex[v1].z;
  626. MulVectorsVect(a, b, norms[f]);
  627. NormVector(norms[f], 1.0f);
  628. }
  629. for (int v=0; v<VCount; v++) {
  630. FUsed = 0;
  631. nv.x=0; nv.y=0; nv.z=0;
  632. for (f=0; f<FCount; f++)
  633. if (!(mptr->gFace[f].Flags & sfDoubleSide) )
  634. if (mptr->gFace[f].v1 == v || mptr->gFace[f].v2 == v || mptr->gFace[f].v3 == v )
  635. { FUsed++; nv = AddVectors(nv, norms[f]); }
  636. if (!FUsed) { nv.x=0; nv.y=1; nv.z=0; }
  637. NormVector(nv, 1.0f);
  638. nvs[v] = nv;
  639. }
  640. } */
  641. void CalcPhongMapping(TModel* mptr, Vector3d *nv)
  642. {
  643. Vector3d l,v,m, tx, ty, tv;
  644. float x,y;
  645. l.x =-Sun3dPos.x;
  646. l.y =-Sun3dPos.y;
  647. l.z =-Sun3dPos.z;
  648. tv.z = 0;
  649. tv.x = 1;
  650. tv.y = 1;
  651. NormVector(l, 1.0f);
  652. for (int i=0; i<mptr->VCount; i++) {
  653. v.x = mptr->gVertex[i].x;
  654. v.y = mptr->gVertex[i].y;
  655. v.z = mptr->gVertex[i].z;
  656. NormVector(v, 1.0f);
  657. m = AddVectors(l, v);
  658. NormVector(m, 1.0f);
  659. if (l.z < 0) MulVectorsVect(m, tv, tx);
  660. else MulVectorsVect(m, v, tx);
  661. NormVector(tx, 1.0f);
  662. MulVectorsVect(m, tx, ty); NormVector(ty, 1.0f);
  663. MulVectorsScal(tx, nv[i], x);
  664. MulVectorsScal(ty, nv[i], y);
  665. PhongMapping[i].x = 128 + x *127;
  666. PhongMapping[i].y = 128 + y *127;
  667. }
  668. }
  669. void CalcEnvMapping(TModel* mptr, Vector3d *nv)
  670. {
  671. Vector3d l,v,m, tx, ty;
  672. float x,y,s;
  673. float cc = cos((PlayerX + PlayerZ) / 500);
  674. float ss = sin((PlayerX + PlayerZ) / 500);
  675. tx.x = cc; tx.y = 0.0f; tx.z =-ss;
  676. ty.x = ss; ty.y = 0.0f; ty.z = cc;
  677. tx = RotateVector(tx);
  678. ty = RotateVector(ty);
  679. NormVector(l, 1.0f);
  680. for (int i=0; i<mptr->VCount; i++) {
  681. v.x = mptr->gVertex[i].x;
  682. v.y = mptr->gVertex[i].y;
  683. v.z = mptr->gVertex[i].z;
  684. MulVectorsScal(v, nv[i], s);
  685. m = nv[i];
  686. NormVector(m, s*2);
  687. m = AddVectors(m, v);
  688. NormVector(m, 1.0f);
  689. MulVectorsScal(tx, m, x);
  690. MulVectorsScal(ty, m, y);
  691. PhongMapping[i].x = 128 + x * 122;
  692. PhongMapping[i].y = 128 + y * 122;
  693. }
  694. }
  695. void CalcBoundBox(TModel* mptr, TBound *bound)
  696. {
  697. float x1, x2, y1, y2, z1, z2;
  698. BOOL first;
  699. for (int o=0; o<8; o++) {
  700. first = TRUE;
  701. bound[o].a=-1;
  702. for (int v=0; v<mptr->VCount; v++) {
  703. TPoint3d p = mptr->gVertex[v];
  704. if (p.hide) continue;
  705. if (p.owner!=o) continue;
  706. if (first) {
  707. x1 = p.x-1.0f; x2 = p.x+1.0f;
  708. y1 = p.y-1.0f; y2 = p.y+1.0f;
  709. z1 = p.z-1.0f; z2 = p.z+1.0f;
  710. first = FALSE;
  711. }
  712. if (p.x < x1) x1=p.x;
  713. if (p.x > x2) x2=p.x;
  714. if (p.y < y1) y1=p.y;
  715. if (p.y > y2) y2=p.y;
  716. if (p.z < z1) z1=p.z;
  717. if (p.z > z2) z2=p.z;
  718. }
  719. if (first) continue;
  720. x1-=72.f;
  721. x2+=72.f;
  722. z1-=72.f;
  723. z2+=72.f;
  724. bound[o].y1 = y1;
  725. bound[o].y2 = y2;
  726. bound[o].cx = (x1+x2) / 2;
  727. bound[o].cy = (z1+z2) / 2;
  728. bound[o].a = (x2-x1) / 2;
  729. bound[o].b = (z2-z1) / 2;
  730. }
  731. }