mathematics.cpp 23 KB

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