OBJECTS.PAS 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938
  1. Unit Objects;
  2. Interface
  3. {$DEFINE Bilinear}
  4. Uses Matrices,UVector,GTypes;
  5. TYPE
  6. {----------- [OBJECTS] --------------}
  7. PObject = ^TObject;
  8. TObject = object
  9. Pos : tVec;
  10. ID : ObjID;
  11. OType : string;
  12. Constructor Init;
  13. Function ISect(aRay : PRay):float;virtual;
  14. Procedure GetNormal(var Norm:TVec;aPos : TVec);virtual;
  15. Destructor Done;virtual;
  16. end;
  17. PFileObj = ^TFileObj;
  18. TFileObj = object (TObject)
  19. Constructor Init;
  20. Constructor Load(var F:FILE);
  21. Procedure Save(var F:FILE);virtual;
  22. end;
  23. PColObj = ^TColObj;
  24. TColObj = object (TFileObj)
  25. Color : RGB;
  26. Constructor Init;
  27. end;
  28. PSurfObj = ^TSurfObj;
  29. TSurfObj = object (TColObj)
  30. Surface : PSurfDesc;
  31. Texture : PTexture;
  32. TexTrans : TTransform;
  33. Procedure SetSurf(aKd,aKs,aNs:float);
  34. Constructor Init;
  35. Destructor Done;virtual;
  36. Procedure Transform(tr:TTRANSFORM);virtual;
  37. Procedure SetTexture(aPT:PTexture;aR,aLen:real);virtual;
  38. Procedure GetColor(var aC : RGB;aV:tVec);virtual;
  39. end;
  40. CONE_INTER_TYPE = (SIDE_HIT,BASE_HIT,CAP_HIT);
  41. tConeInters = array [0..3] of record
  42. d : float;
  43. t : CONE_INTER_TYPE;
  44. end;
  45. PCone = ^TCone;
  46. TCone = object (TSurfObj)
  47. trans,pt : TTRANSFORM;
  48. apex,base : tVec;
  49. apex_rad,base_rad,dist : float;
  50. FlagCyl : boolean;
  51. LastInter : CONE_INTER_TYPE;
  52. Constructor Init(aApex,aBase:tVec;aBaseRad,aApexRad : float; aCol:RGB);
  53. Constructor Load(var F:FILE);
  54. Procedure Save(var F:FILE);virtual;
  55. Procedure Transform(tr:TTRANSFORM);virtual;
  56. Function ISect(aRay : PRay):float;virtual;
  57. Function Inside(aP:tVec):boolean;
  58. Procedure GetNormal(var Norm:TVec;aPos : TVec);virtual;
  59. private
  60. Procedure ComputeConeData;
  61. Procedure ComputeCylData;
  62. Function ISectCone(aRay:tRay;var aI:tConeInters):INTEGER;
  63. end;
  64. PSphere = ^TSphere;
  65. TSphere = object (TSurfObj)
  66. Radius : float;
  67. Constructor Init(ax,ay,az,arad : float; aCol:RGB);
  68. Constructor Load(var F:FILE);
  69. Procedure Save(var F:FILE);virtual;
  70. Procedure Transform(tr:TTRANSFORM);virtual;
  71. Function ISect(aRay : PRay):float;virtual;
  72. Function Inside(aP:tVec):boolean;
  73. Procedure GetNormal(var Norm:TVec;aPos : TVec);virtual;
  74. end;
  75. PSurfPlane = ^TSurfPlane;
  76. TSurfPLane = object (TSurfObj)
  77. Pl : TPlane;
  78. Procedure Transform(tr:TTRANSFORM);virtual;
  79. Constructor Init(av1,av2,av3 : tVec; aCol:RGB);
  80. Constructor Load(var F:FILE);
  81. Constructor TriLoad(var F:FILE);
  82. Procedure Save(var F:FILE);virtual;
  83. Function ISect(aRay:PRay):float;virtual;
  84. Function Inside(aP:tVec):boolean;
  85. Procedure SetTexture(aPT:PTexture;aR,aLen:real);virtual;
  86. Procedure GetNormal(var Norm:TVec; aPos:TVec);virtual;
  87. end;
  88. PTriangle = ^TTriangle;
  89. TTriangle = object (TSurfObj)
  90. v1, v2, v3 : tVec;
  91. pl : TPlane;
  92. Constructor Init(av1,av2,av3 : tVec; aCol:RGB);
  93. Constructor Load(var F:FILE);
  94. Procedure Save(var F:FILE);virtual;
  95. Procedure Transform(tr:TTRANSFORM);virtual;
  96. Function ISect(aRay:PRay):float;virtual;
  97. Procedure GetNormal(var Norm:TVec; aPos:TVec);virtual;
  98. Procedure SetTexture(aPT:PTexture;aR,aLen:real);virtual;
  99. end;
  100. PQuad = ^TQuad;
  101. TQuad = object (TSurfObj)
  102. v1, v2, v3, v4 : tVec;
  103. pl : TPlane;
  104. Constructor Init(av1,av2,av3,aV4 : tVec; aCol:RGB);
  105. Procedure Transform(tr:TTRANSFORM);virtual;
  106. Constructor Load(var F:FILE);
  107. Procedure Save(var F:FILE);virtual;
  108. Function ISect(aRay:PRay):float;virtual;
  109. Procedure GetNormal(var Norm:TVec; aPos:TVec);virtual;
  110. Procedure SetTexture(aPT:PTexture;aR,aLen:real);virtual;
  111. end;
  112. PInterS = ^TInterS;
  113. TInterS = object (TSurfObj)
  114. Sp : PSphere;
  115. Pl : PSurfPlane;
  116. Inv : float;
  117. Constructor Load(var F:FILE);
  118. Procedure Save(var F:FILE);virtual;
  119. Function ISect(aRay:PRay):float;virtual;
  120. Procedure GetNormal(var Norm:TVec; aPos:TVec);virtual;
  121. Procedure Transform(tr:TTRANSFORM);virtual;
  122. end;
  123. {------------- [LIGHT] -----------------}
  124. PLight = ^TLight;
  125. TLight = object (TFileObj)
  126. Constructor Init;
  127. end;
  128. POmni = ^TOmni;
  129. TOmni = object (TLight)
  130. Color : RGB;
  131. Constructor Load(var F:FILE);
  132. Procedure Save(var F:FILE);virtual;
  133. Constructor Init(ax,ay,az:float;aCol:RGB);
  134. end;
  135. PSpot = ^TSpot;
  136. TSpot = object (TLight)
  137. Target : tVec;
  138. FOV : float;
  139. Color : RGB;
  140. Constructor Load(var F:FILE);
  141. Procedure Save(var F:FILE);virtual;
  142. Constructor Init(ax,ay,az,axo,ayo,azo,aFov:float;aCol:RGB);
  143. end;
  144. IMPLEMENTATION
  145. {TObject}
  146. Constructor TObject.Init;
  147. begin
  148. Pos := ZeroVec;
  149. OType := 'OBJ';
  150. end;{TObject.Init}
  151. Function TObject.ISect;
  152. begin
  153. ISect := INF;
  154. end;{TObject.ISect}
  155. Procedure TObject.GetNormal;
  156. begin
  157. end;{TObject.GetNormal}
  158. Destructor TObject.Done;
  159. begin
  160. end;{TObject.Done}
  161. {TFileObject}
  162. Constructor TFileObj.Init;
  163. begin
  164. Inherited Init;
  165. ID := F_NULL;
  166. OType:=OType+'_FILE';
  167. end;
  168. Constructor TFileObj.Load(var F:FILE);
  169. begin
  170. end;
  171. Procedure TFileObj.Save(var F:FILE);
  172. begin;
  173. end;
  174. {TColObj}
  175. Constructor TColObj.Init;
  176. begin
  177. Inherited Init;
  178. OType := OType + '_COL';
  179. end;
  180. {TSurfObj}
  181. Constructor TSurfObj.Init;
  182. begin
  183. Inherited Init;
  184. Texture := Nil;
  185. OType := OType+'_SURF';
  186. New(Surface);
  187. With Surface^ do begin
  188. Ks := 0; Kd := 0; Ns := 0;
  189. end;
  190. end;
  191. Procedure TSurfObj.SetSurf(aKd,aKs,aNs:float);
  192. begin
  193. with Surface^ do begin
  194. Ks := aKs; Kd := aKd; Ns := aNs;
  195. end;
  196. end;
  197. Procedure TSurfObj.GetColor;
  198. var
  199. v2:tVec;
  200. sx,sy,x,y : word;
  201. fx,fy : float;
  202. cc,cc1,cc2,cc3 : BRGB;
  203. A,B : RGB;
  204. begin
  205. if Texture = nil then
  206. begin
  207. aC := Color;
  208. end
  209. else
  210. begin
  211. MInvTransPoint(v2,av,TexTrans);
  212. sx := Texture^.SizeX; sy:=Texture^.SizeY;
  213. while v2.X < 0 do v2.X := v2.X + SX;
  214. while v2.Y < 0 do v2.Y := v2.Y + SY;
  215. {$IFNDEF Bilinear}
  216. x:=round(v2.X);y:=round(v2.Y);
  217. CC := Texture^.Bits^[(SY-1-(Y mod SY)) * SX + (X mod SX)];
  218. aC.R := cc.R / 255 * Color.R;
  219. aC.G := cc.G / 255 * Color.G;
  220. aC.B := cc.B / 255 * Color.B;
  221. {$ELSE}
  222. fx := frac(v2.X);fy:=frac(v2.y);x:=trunc(v2.X);y:=trunc(v2.Y);
  223. CC := Texture^.Bits^[(SY-1-(Y mod SY)) * SX + (X mod SX)];
  224. CC1 := Texture^.Bits^[(SY-1-(Y mod SY)) * SX + ((X+1) mod SX)];
  225. CC2 := Texture^.Bits^[(SY-1-((Y+1) mod SY)) * SX + (X mod SX)];
  226. CC3 := Texture^.Bits^[(SY-1-((Y+1) mod SY)) * SX + ((X+1) mod SX)];
  227. A.R := (CC.R + (CC2.R-CC.R)*fy)/255;
  228. A.G := (CC.G + (CC2.G-CC.G)*fy)/255;
  229. A.B := (CC.B + (CC2.B-CC.B)*fy)/255;
  230. B.R := (CC1.R + (CC3.R-CC1.R)*fy)/255;
  231. B.G := (CC1.G + (CC3.G-CC1.G)*fy)/255;
  232. B.B := (CC1.B + (CC3.B-CC1.B)*fy)/255;
  233. aC.R := (A.R + (B.R-A.R)*fx)*Color.R;
  234. aC.G := (A.G + (B.G-A.G)*fx)*Color.G;
  235. aC.B := (A.B + (B.B-A.B)*fx)*Color.B;
  236. {$ENDIF}
  237. end;
  238. end;
  239. Procedure TSurfObj.Transform;
  240. begin
  241. MTransPoint(Pos,Pos,tr);
  242. Compose_Transforms(TexTrans,tr);
  243. end;
  244. Procedure TSurfObj.SetTexture;
  245. begin
  246. Texture := aPT;
  247. end;
  248. Destructor TSurfObj.Done;
  249. begin
  250. Dispose(Surface);
  251. Inherited Done;
  252. end;
  253. {-------------------------------------------------------------}
  254. {-------------------------------------------------------------}
  255. {--------------------- REAL OBJECTS --------------------------}
  256. {-------------------------------------------------------------}
  257. {-------------------------------------------------------------}
  258. {TCone}
  259. Constructor TCone.Init;
  260. begin
  261. Inherited Init;
  262. OType := OType + '_CONE';
  263. ID := F_CONE;
  264. Apex := aApex;Base:=aBase;
  265. Apex_Rad := aApexRad;Base_Rad:=aBaseRad;
  266. Color := aCol;
  267. ComputeConeData;
  268. end;
  269. Constructor TCone.Load;
  270. begin
  271. Inherited Init;
  272. OType := OType + '_CONE';
  273. ID := F_CONE;
  274. BlockRead(F,Apex,vecsize);
  275. BlockRead(F,Base,vecsize);
  276. BlockRead(F,Apex_Rad,sizeof(float));
  277. BlockRead(F,Base_Rad,sizeof(float));
  278. LoadRGB(F,Color);
  279. BlockRead(F,Surface^,vecsize);
  280. ComputeConeData;
  281. end;
  282. Procedure TCone.Save;
  283. begin
  284. BlockWrite(F,ID,1);
  285. BlockWrite(F,Apex,vecsize);
  286. BlockWrite(F,Base,vecsize);
  287. BlockWrite(F,Apex_Rad,sizeof(float));
  288. BlockWrite(F,Base_Rad,sizeof(float));
  289. SaveRGB(F,Color);
  290. BlockWrite(F,Surface^,vecsize);
  291. end;
  292. Procedure TCone.ComputeConeData;
  293. var
  294. tlen,len,tmpf:float;
  295. axis,tmpv,origin:tVec;
  296. begin
  297. if abs(Apex_Rad-Base_Rad)<EPS then
  298. begin FlagCyl := true; ComputeCylData; exit;
  299. end;
  300. FlagCyl := False;
  301. if Apex_rad < Base_Rad then
  302. begin
  303. tmpv := Apex;tmpf:=Apex_rad;
  304. Apex := Base;Apex_Rad:=Base_Rad;
  305. Base := tmpv;Base_Rad:=tmpf;
  306. end;
  307. VLinear(axis,Apex,Base,1,-1);
  308. len := VLength(axis);
  309. if len < EPS then
  310. begin WriteLn('Sucked cone!');Halt(101);end
  311. else VNorm(Axis,1);
  312. tmpf := Base_Rad*Len / (Apex_Rad-Base_Rad);
  313. VLinear(Origin,Axis,axis,tmpf,0);
  314. VLinear(Origin,Base,Origin,1,-1);
  315. tlen := tmpf + len;
  316. Dist := tmpf /tlen;
  317. Compute_Coordinate_Transform(Trans,origin,axis,Apex_Rad,tLen);
  318. end;{ComputeConeData}
  319. Procedure TCone.ComputeCylData;
  320. var
  321. tmpf:float;
  322. tr2:TTRANSFORM;
  323. ax2:tVec;
  324. axis:tVec;
  325. begin
  326. VLinear(axis,Apex,Base,1,-1);
  327. tmpf:=VLength(axis);
  328. if tmpf<EPS then
  329. begin WriteLn('Sucked cylinder!');Halt(101);end;
  330. VNorm(Axis,1);
  331. Compute_Coordinate_Transform(Trans,Base,axis,Apex_Rad,tmpf);
  332. Dist:=0.0;
  333. end;
  334. Procedure TCone.Transform;
  335. begin
  336. Compose_TransForms(trans,tr);
  337. end;
  338. Function TCone.ISect;
  339. var
  340. i,count : integer;
  341. IS : tConeInters;
  342. min : integer;
  343. begin
  344. ISect:=INF;
  345. count := ISectCone(aRay^,IS);
  346. if count = 0 then exit;
  347. min := 0;
  348. for i := 1 to count-1 do if abs(IS[i].d) < abs(IS[min].d) then min:=i;
  349. ISect := IS[min].d;
  350. LastInter:=IS[MIN].t;
  351. end;
  352. function TCone.ISectCone;
  353. var
  354. i : integer;
  355. a,b,c,z,t1,t2,len:float;
  356. d,tmpf:float;
  357. P,Dir : tVec;
  358. begin
  359. i:=0;
  360. MInvTransPoint(P,aRay.Org,trans);
  361. MInvTransDirection(Dir,aRay.Dir,trans);
  362. len := VLength(Dir);
  363. VNorm(Dir,1);
  364. if FlagCyl then
  365. begin {Calculate cylinder equations}
  366. a := dir.x*dir.x+dir.y*dir.y;
  367. if a > EPS then begin
  368. b := p.x*dir.x+p.y*dir.y;
  369. c := p.x*p.x+p.y*p.y-1;
  370. d := b*b-a*c;
  371. if d >= 0 then
  372. begin
  373. d := sqrt(d);
  374. t1 := (-b+d)/a;
  375. t2 := (-b-d)/a;
  376. z := p.z + t1*dir.z;
  377. if (Z>=0) and (z<=1) and (t1>=0) then
  378. begin
  379. aI[i].d:=t1/len;
  380. aI[i].t:=SIDE_HIT;
  381. inc(i);
  382. end;
  383. z := p.z + t2*dir.z;
  384. if (Z>=0) and (z<=1) and (t2>=0) then
  385. begin
  386. aI[i].d:=t2/len;
  387. aI[i].t:=SIDE_HIT;
  388. inc(i);
  389. end;
  390. end;
  391. end;
  392. end
  393. else {Solve cone intersections}
  394. begin
  395. a:=dir.x*dir.x+dir.y*dir.y-dir.z*dir.z;
  396. b:=dir.x*p.x+dir.y*p.y-dir.z*p.z;
  397. c:=p.x*p.x+p.y*p.y-p.z*p.z;
  398. if abs(a) < EPS then
  399. begin
  400. if abs(b) > EPS then
  401. begin
  402. t1 := 0.5*c/b;
  403. z := p.z + t1*dir.z;
  404. if (t1>=0) and (z>=Dist) and (Z<=1) then
  405. begin
  406. aI[i].d:=t1/len;
  407. aI[i].t:=SIDE_HIT;
  408. inc(i);
  409. end;
  410. end;
  411. end
  412. else
  413. begin
  414. d := b*b-a*c;
  415. if d>=0 then
  416. begin
  417. d:=sqrt(d);
  418. t1 := (-b+d)/a;
  419. t2 := (-b-d)/a;
  420. z := p.z + t1*dir.z;
  421. if (Z>=Dist) and (z<=1) and (t1>=0) then
  422. begin
  423. aI[i].d:=t1/len;
  424. aI[i].t:=SIDE_HIT;
  425. inc(i);
  426. end;
  427. z := p.z + t2*dir.z;
  428. if (Z>=Dist) and (z<=1) and (t2>=0) then
  429. begin
  430. aI[i].d:=t2/len;
  431. aI[i].t:=SIDE_HIT;
  432. inc(i);
  433. end;
  434. end;
  435. end;
  436. end;
  437. if abs(Dir.Z) > EPS then
  438. begin
  439. d:=(1-p.z)/dir.z;
  440. a:=p.x+d*dir.x;
  441. b:=p.y+d*dir.y;
  442. if ((sqr(a)+sqr(b)) <= 1) and (D>=0) then
  443. begin
  444. aI[i].d:=d/len;
  445. aI[i].t:=CAP_HIT;
  446. inc(i);
  447. end;
  448. d := (Dist - p.z)/dir.z;
  449. a := p.x+d*dir.x;
  450. b := p.y+d*dir.y;
  451. if FlagCyl then tmpf:=1 else tmpf := sqr(Dist);
  452. if ((sqr(a)+sqr(b)) <= tmpf) and (D>=0) then
  453. begin
  454. aI[i].d:=d/len;
  455. aI[i].t:=BASE_HIT;
  456. end;
  457. end;
  458. ISectCone:=i;
  459. end; {ISectCone}
  460. Procedure TCone.GetNormal;
  461. begin
  462. MInvTransPoint(Norm,aPos,Trans);
  463. case LastInter of
  464. SIDE_HIT: if FlagCyl then Norm.z := 0
  465. else Norm.Z := -Norm.Z;
  466. BASE_HIT: VSet(Norm,0,0,-1);
  467. CAP_HIT: VSet(Norm,0,0,1);
  468. end;
  469. MTransNormal(Norm,Norm,Trans);
  470. VNorm(Norm,1);
  471. end;
  472. Function TCone.Inside;
  473. var
  474. NP : tVec;
  475. w2,z2:float;
  476. begin
  477. MInvTransPoint(NP,aP,Trans);
  478. w2 := NP.x*NP.x +NP.y*NP.y;
  479. if FlagCyl then
  480. begin
  481. if (w2 > 1+EPS) or (NP.Z<0-EPS) or (NP.Z > 1 + EPS) then
  482. begin Inside := false;exit;end
  483. else
  484. begin Inside := true;exit;end;
  485. end
  486. else
  487. begin
  488. z2 := np.z*np.z;
  489. if (w2 > z2+EPS) or (NP.Z<Dist-EPS) or (NP.Z > 1 + EPS) then
  490. begin Inside := false;exit;end
  491. else
  492. begin Inside := true;exit;end;
  493. end;
  494. end;
  495. {TSphere}
  496. Constructor TSphere.Init(ax,ay,az,arad : float; aCol:RGB);
  497. begin
  498. Inherited Init;
  499. OType := OType + '_SPHERE';
  500. ID := F_OBJ_SPHERE;
  501. VSet(Pos,ax,ay,az);
  502. Radius := aRad;
  503. Color := aCol;
  504. end;{TSphere.Init}
  505. Procedure TSphere.Transform;
  506. var
  507. vr : tVec;
  508. begin
  509. vr := Pos;
  510. vr.Y := vr.Y + radius;
  511. Inherited Transform(tr);
  512. MTransPoint(vr,vr,tr);
  513. VLinear(vr,vr,Pos,1,-1);
  514. Radius := sqrt(VDot(vr,vr));
  515. end;
  516. Procedure TSphere.Save;
  517. begin
  518. BlockWrite(F,ID,sizeof(ObjID));
  519. BlockWrite(F,Pos,sizeof(float)*3);
  520. BlockWrite(F,Radius,sizeof(float));
  521. SaveRGB(F,Color);
  522. BlockWrite(F,Surface^,vecsize);
  523. end;
  524. Constructor TSphere.Load;
  525. begin
  526. Inherited Init;
  527. OType := OType + '_SPHERE';
  528. ID := F_OBJ_SPHERE;
  529. BlockRead(F,Pos,sizeof(float)*3);
  530. BlockRead(F,Radius,sizeof(float));
  531. LoadRGB(F,Color);
  532. BlockRead(F,Surface^,vecsize);
  533. end;
  534. Function TSphere.ISect(aRay : PRay):float;
  535. var
  536. a,b,c,d,t1,t2 : float;
  537. tmp : tvec;
  538. begin
  539. ISect := INF;
  540. a := VDot(aRay^.Dir,aRay^.Dir);
  541. VLinear(tmp,aRay^.Org,Pos,1,-1);
  542. b := 2*VDot(aRay^.Dir,tmp);
  543. c := VDot(tmp,tmp) - Radius*Radius;
  544. d := b*b-4*a*c;
  545. if d < 0 then exit;
  546. d := sqrt(d);
  547. t1 := (-b-d) / (2*a);
  548. t2 := (-b+d) / (2*a);
  549. if t2 < 0 then Exit;
  550. if t1 > 0 then ISect:=t1 else Isect:=t2;
  551. end;{TSphere.ISect}
  552. Function TSphere.Inside;
  553. begin
  554. VLinear(aP,aP,Pos,1,-1);
  555. Inside := VDot(aP,aP) <= Radius*Radius;
  556. end;
  557. Procedure TSphere.GetNormal(var Norm:TVec;aPos : TVec);
  558. begin
  559. VLinear(Norm,aPos,Pos,1,-1);
  560. VNorm(Norm,1);
  561. end;{TSphere.GetNormal}
  562. {TTRiangle}
  563. Constructor TTriangle.Init;
  564. begin
  565. Inherited Init;
  566. OType := OType + '_TRI';
  567. ID := F_TRI;
  568. v1 := aV1;
  569. v2 := aV2;
  570. v3 := aV3;
  571. SetPlane(Pl,v1,v2,v3);
  572. Color := aCol;
  573. end;
  574. Procedure TTriangle.Transform;
  575. begin
  576. Inherited Transform(tr);
  577. MTransPoint(v1,v1,tr);
  578. MTransPoint(v2,v2,tr);
  579. MTransPoint(v3,v3,tr);
  580. SetPlane(Pl,v1,v2,v3);
  581. end;
  582. Procedure TTriangle.SetTexture(aPT:PTexture;aR,aLen:real);
  583. begin
  584. Inherited SetTexture(aPT,aR,aLen);
  585. CalcTransform(TexTrans,V1,V2,V3,aR,aLen);
  586. end;
  587. Procedure TTriangle.GetNormal;
  588. begin
  589. Norm := Pl.N;
  590. end;
  591. Function TTriangle.ISect;
  592. var
  593. del, delit : float;
  594. P : tVec;
  595. p1,p2,p3 : TPlane;
  596. begin
  597. del := -(VDot(Pl.N,aRay^.Org)+Pl.D);
  598. delit := VDot(Pl.N,aRay^.Dir);
  599. if abs(del)<EPS then DEL := +0;
  600. if (abs(delit) < EPS) or (del*delit<0) then exit;
  601. VLinear(P,aRay^.Org,aRay^.Dir,1,del/delit);
  602. SetPlane(p1,v1,aRay^.Org,v2);
  603. SetPlane(p2,v2,aRay^.Org,v3);
  604. SetPlane(p3,v3,aRay^.Org,v1);
  605. ISect := del/delit;
  606. if (
  607. (VDot(p1.N,p)>-p1.D) and (VDot(p2.N,p)>-p2.D) and (VDot(p3.N,p)>-p3.D)
  608. ) or
  609. (
  610. (VDot(p1.N,p)<-p1.D) and (VDot(p2.N,p)<-p2.D) and (VDot(p3.N,p)<-p3.D)
  611. )
  612. then Exit;
  613. ISect := INF;
  614. end;
  615. Constructor TTriangle.Load;
  616. begin
  617. BlockRead(F,v1,vecsize);
  618. BlockRead(F,v2,vecsize);
  619. BlockRead(F,v3,vecsize);
  620. LoadRGB(F,Color);
  621. Init(v1,v2,v3,Color);
  622. BlockRead(F,Surface^,vecsize);
  623. end;
  624. Procedure TTriangle.Save;
  625. begin
  626. BlockWrite(F,ID,1);
  627. BlockWrite(F,v1,vecsize);
  628. BlockWrite(F,v2,vecsize);
  629. BlockWrite(F,v3,vecsize);
  630. SaveRGB(F,Color);
  631. BlockWrite(F,Surface^,vecsize);
  632. end;
  633. {TQuad}
  634. Constructor TQuad.Init;
  635. begin
  636. Inherited Init;
  637. OType := OType + '_Quad';
  638. ID := F_QUAD;
  639. v1 := aV1;
  640. v2 := aV2;
  641. v3 := aV3;
  642. v4 := aV4;
  643. SetPlane(Pl,v1,v2,v3);
  644. Color := aCol;
  645. end;
  646. Procedure TQuad.SetTexture(aPT:PTexture;aR,aLen:real);
  647. begin
  648. Inherited SetTexture(aPT,aR,aLen);
  649. CalcTransform(TexTrans,V1,V2,V3,aR,aLen);
  650. end;
  651. Procedure TQuad.Transform;
  652. begin
  653. Inherited Transform(tr);
  654. MTransPoint(v1,v1,tr);
  655. MTransPoint(v2,v2,tr);
  656. MTransPoint(v3,v3,tr);
  657. MTransPoint(v4,v4,tr);
  658. SetPlane(Pl,v1,v2,v3);
  659. end;
  660. Procedure TQuad.GetNormal;
  661. begin
  662. Norm := Pl.N;
  663. end;
  664. Function TQuad.ISect;
  665. var
  666. del, delit : float;
  667. P : tVec;
  668. p1,p2,p3,p4 : TPlane;
  669. begin
  670. del := -(VDot(Pl.N,aRay^.Org)+Pl.D);
  671. delit := VDot(Pl.N,aRay^.Dir);
  672. if (abs(delit) < EPS) or (del*delit<0) then exit;
  673. ISect := del/delit;
  674. VLinear(P,aRay^.Org,aRay^.Dir,1,del/delit);
  675. SetPlane(p1,v1,aRay^.Org,v2);
  676. SetPlane(p2,v2,aRay^.Org,v3);
  677. SetPlane(p3,v3,aRay^.Org,v4);
  678. SetPlane(p4,v4,aRay^.Org,v1);
  679. if ((VDot(p1.N,p)>-p1.D) and (VDot(p2.N,p)>-p2.D) and (VDot(p3.N,p)>-p3.D) and (VDot(p4.N,p)>-p4.D))
  680. or ((VDot(p1.N,p)<-p1.D) and (VDot(p2.N,p)<-p2.D) and (VDot(p3.N,p)<-p3.D) and (VDot(p4.N,p)<-p4.D))
  681. then Exit;
  682. ISect := INF;
  683. end;
  684. Constructor TQuad.Load;
  685. begin
  686. BlockRead(F,v1,vecsize);
  687. BlockRead(F,v2,vecsize);
  688. BlockRead(F,v3,vecsize);
  689. BlockRead(F,v4,vecsize);
  690. LoadRGB(F,Color);
  691. Init(v1,v2,v3,v4,Color);
  692. BlockRead(F,Surface^,vecsize);
  693. end;
  694. Procedure TQuad.Save;
  695. begin
  696. BlockWrite(F,ID,1);
  697. BlockWrite(F,v1,vecsize);
  698. BlockWrite(F,v2,vecsize);
  699. BlockWrite(F,v3,vecsize);
  700. BlockWrite(F,v4,vecsize);
  701. SaveRGB(F,Color);
  702. BlockWrite(F,Surface^,vecsize);
  703. end;
  704. {TSurfPlane}
  705. Constructor TSurfPlane.Init;
  706. begin
  707. Inherited Init;
  708. OType := OType + '_PLANE';
  709. ID := F_OBJ_SURF_PLANE;
  710. SetPlane(Pl,aV1,AV2,aV3);
  711. Color := aCol;
  712. end;{TSurfPlane.Init}
  713. Procedure TSurfPlane.Transform;
  714. var
  715. v1:tVec;
  716. begin
  717. if Pl.N.Y <> 0 then
  718. VSet(v1,0,-Pl.D/Pl.N.Y,0)
  719. else
  720. if Pl.N.Z <> 0 then
  721. VSet(v1,0,0,-Pl.D/Pl.N.Z)
  722. else VSet(v1,-Pl.D/Pl.N.X,0,0);
  723. MTransPoint(v1,v1,tr);
  724. MTransDirection(Pl.N,Pl.N,tr);
  725. Pl.D := -VDot(PL.N,v1);
  726. end;
  727. Procedure TSurfPlane.Save;
  728. begin
  729. BlockWrite(F,ID,1);
  730. BlockWrite(F,Pl.N,vecsize);
  731. BlockWrite(F,Pl.D,sizeof(float));
  732. SaveRGB(F,Color);
  733. BlockWrite(F,Surface^,vecsize);
  734. end;{TFilePlane.Save}
  735. Constructor TSurfPlane.Load;
  736. begin
  737. Inherited Init;
  738. ID := F_OBJ_SURF_PLANE;
  739. OType := OType+ '_PLANE';
  740. BlockRead(F,Pl.N,vecsize);
  741. BlockRead(F,Pl.D,sizeof(float));
  742. LoadRGB(F,Color);
  743. BlockRead(F,Surface^,vecsize);
  744. end;{TSurfPlane.Load}
  745. Constructor TSurfPlane.TriLoad;
  746. var
  747. v1,v2,v3 : tVec;
  748. ac : RGB;
  749. begin
  750. BlockRead(F,v1,vecsize);
  751. BlockRead(F,v2,vecsize);
  752. BlockRead(F,v3,vecsize);
  753. LoadRGB(F,aC);
  754. Init(v1,v2,v3,aC);
  755. BlockRead(F,Surface^,vecsize);
  756. end;
  757. Function TSurfPlane.Inside;
  758. begin
  759. Inside := abs(VDot(Pl.N,aP)+Pl.D) < EPS;
  760. end;
  761. Procedure TSurfPlane.SetTexture(aPT:PTexture;aR,aLen:real);
  762. var
  763. v1,v2,v3 : tVec;
  764. begin
  765. Inherited SetTexture(aPT,aR,aLen);
  766. if Pl.N.Y <> 0 then
  767. VSet(v1,0,-Pl.D/Pl.N.Y,0)
  768. else
  769. if Pl.N.Z <> 0 then
  770. VSet(v1,0,0,-Pl.D/Pl.N.Z)
  771. else VSet(v1,-Pl.D/Pl.N.X,0,0);
  772. Compute_Coordinate_Transform(TexTrans,V1,Pl.N,aR,aLen);
  773. end;
  774. Function TSurfPlane.ISect;
  775. var
  776. del, delit : float;
  777. begin
  778. ISect := INF;
  779. del := -(VDot(Pl.N,aRay^.Org)+Pl.D);
  780. delit := VDot(Pl.N,aRay^.Dir);
  781. if (abs(delit) < EPS) or (del*delit<0) then exit;
  782. ISect := del/delit;
  783. end;{TSurfPlane.ISect}
  784. Procedure TSurfPlane.GetNormal;
  785. begin
  786. Norm := Pl.N;
  787. end;{TSurfPlane.GetNormal}
  788. {----------------------}
  789. {TInterS}
  790. Constructor TInterS.Load;
  791. var
  792. m_ID : OBjID;
  793. begin
  794. Inherited Init;
  795. ID := F_INTER_SPHERE;
  796. OType := OType+ '_INTERSPHERE';
  797. BlockRead(F,Inv,sizeof(float));
  798. LoadRGB(F,Color);
  799. BlockRead(F,Surface^,vecsize);
  800. BlockRead(F,m_ID,1);
  801. if m_ID = F_OBJ_SPHERE then
  802. begin
  803. New(Sp,Load(F));
  804. BlockRead(F,m_ID,1);
  805. if m_ID = F_TRI_PLANE then New(Pl,TriLoad(F))
  806. else New(Pl,Load(F))
  807. end
  808. else
  809. begin
  810. if m_ID = F_TRI_PLANE then New(Pl,TriLoad(F))
  811. else New(Pl,Load(F));
  812. BlockRead(F,m_ID,1);
  813. New(Sp,Load(F));
  814. end;
  815. end;{TInterS.Load}
  816. {-=-=-=-=-=-=-=-=-=-=-=-}
  817. Procedure TInterS.Save;
  818. begin
  819. BlockWrite(F,ID,1);
  820. BlockWrite(F,Inv,sizeof(float));
  821. SaveRGB(F,Color);
  822. BlockWrite(F,Surface^,vecsize);
  823. Sp^.Save(F);
  824. Pl^.Save(F);
  825. end;{TInterS.Save}
  826. {-=-=-=-=-=-=-=-=-=-=-=-}
  827. Function TInterS.ISect;
  828. var
  829. T : float;
  830. P : tVec;
  831. begin
  832. ISect:=INF;
  833. T := Sp^.ISect(aRay);
  834. if abs(T-INF) < EPS then
  835. exit;
  836. aRay^.GetPoint(P,T);
  837. if (VDot(PL^.Pl.N,P)+PL^.Pl.D)*Inv >= 0 then
  838. ISect := T
  839. else
  840. begin
  841. T := Pl^.ISect(aRay);
  842. aRay^.GetPoint(P,T);
  843. if Sp^.Inside(P) then ISect := T;
  844. end;
  845. end;
  846. {-=-=-=-=-=-=-=-=-=-=-=-}
  847. Procedure TInterS.GetNormal;
  848. begin
  849. if Not Pl^.Inside(aPos) then
  850. Sp^.GetNormal(Norm,aPos)
  851. else
  852. if Inv > 0 then
  853. VLinear(Norm,Pl^.Pl.N,Pl^.Pl.N,0,-1)
  854. else
  855. Norm := Pl^.Pl.N;
  856. end;
  857. {-=-=-=-=-=-=-=-=-=-=-=-}
  858. Procedure TInterS.Transform;
  859. begin
  860. Sp^.Transform(tr);
  861. Pl^.Transform(tr);
  862. end;
  863. {---------------------- LIGHTS -----------------------}
  864. {TLight}
  865. Constructor TLight.Init;
  866. begin
  867. Inherited Init;
  868. OType := OType + '_LIGHT';
  869. end;
  870. {TOmni}
  871. Constructor TOmni.Init;
  872. begin
  873. Inherited Init;
  874. OType := Otype + '_OMNI';
  875. ID := F_LIGHT_OMNI;
  876. VSet(Pos,ax,ay,az);
  877. Color := aCol;
  878. end;
  879. Constructor TOmni.Load;
  880. begin
  881. Inherited Init;
  882. ID := F_LIGHT_OMNI;
  883. OType := Otype + '_OMNI';
  884. BlockRead(F,Pos,sizeof(float)*3);
  885. LoadRGB(F,Color);
  886. end;
  887. Procedure TOmni.Save;
  888. begin
  889. BlockWrite(F,ID,SizeOf(OBjID));
  890. BlockWrite(F,Pos,sizeof(float)*3);
  891. SaveRGB(F,Color);
  892. end;
  893. {---------------------}
  894. {TSpot}
  895. Constructor TSpot.Init;
  896. begin
  897. Inherited Init;
  898. OType := Otype + '_SPOT';
  899. ID := F_SPOTLIGHT;
  900. FOV := aFov;
  901. VSet(Target,ax,ay,az);
  902. VSet(Pos,axo,ayo,azo);
  903. Color := aCol;
  904. end;
  905. Constructor TSpot.Load;
  906. begin
  907. Inherited Init;
  908. ID := F_LIGHT_OMNI;
  909. OType := Otype + '_SPOT';
  910. BlockRead(F,Pos,sizeof(float)*3);
  911. BlockRead(F,Target,sizeof(float)*3);
  912. BlockRead(F,FOV,sizeof(float));
  913. LoadRGB(F,Color);
  914. end;
  915. Procedure TSpot.Save;
  916. begin
  917. BlockWrite(F,ID,SizeOf(OBjID));
  918. BlockWrite(F,Pos,sizeof(float)*3);
  919. BlockWrite(F,Target,sizeof(float)*3);
  920. BlockWrite(F,FOV,sizeof(float));
  921. SaveRGB(F,Color);
  922. end;
  923. END.