OBJTRACE.PAS 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416
  1. unit ObjTrace;
  2. INTERFACE
  3. Uses UVector,Matrices,GTypes,Objects;
  4. CONST
  5. MaxDeep = 2500;
  6. VisRange = 100;
  7. TRAHeader : string [11] = 'Rod''sTracer';
  8. CurVer : longint = $00010001;
  9. {------------- [TRACER] ---------------}
  10. CONST
  11. MAXOBJS = 3000;
  12. MAXTEXTURES = 10;
  13. TYPE
  14. PObjectArray = ^TObjectArray;
  15. TObjectArray = array [1..MAXOBJS] of PObject;
  16. PTextureArray = ^TTextureArray;
  17. TTextureArray = array [1..MAXTEXTURES] of PTexture;
  18. PViewPlane = ^TViewPlane;
  19. TViewPlane = record
  20. LLpos : tVec;
  21. Up : tVec;
  22. Right : tVec;
  23. CamPos : TVec;
  24. end;
  25. PTracer = ^TTracer;
  26. TTracer = object
  27. ObjectCount : Word;
  28. Objects : PObjectArray;
  29. LightCount : Word;
  30. Lights : PObjectArray;
  31. TextureCount : Word;
  32. Textures : PTextureArray;
  33. Ambient : RGB;
  34. View : TViewPlane;
  35. Constructor Init;
  36. Procedure SetPlane(aLLPos,aUp,aRight : tVec);
  37. Procedure SetCamera(aOrg,aTarg:tVec;aRoll,aFov,aXtoY:float);
  38. Procedure LoadCamera(var F:FILE);
  39. Procedure Load(Inp:string);
  40. Procedure Save(Out:string;aView:Boolean);
  41. Procedure AddObject(aNew : PColObj);virtual;
  42. Procedure AddLight(aNew : PLight);virtual;
  43. Procedure AddTexture(aNew : PTexture);virtual;
  44. Function GetObject(Index:word):PColObj;virtual;
  45. Function GetLight(Index:word):PLight;virtual;
  46. Procedure Trace;
  47. Function FindISect(aRay:TRay;var oT:float):PObject;
  48. Destructor Done;virtual;
  49. end;
  50. {-------------------- MODIFICATIONS ----------------}
  51. Procedure SetRotate(Pivot,Axis:tVec;Ang:float;var ob : PObject);
  52. Procedure SetTranslate(v:tVec;var ob : PObject);
  53. Procedure SetScale(Pivot, V : tVec;var ob : PObject);
  54. IMPLEMENTATION
  55. {TTracer}
  56. Constructor TTracer.Init;
  57. begin
  58. ObjectCount := 0;
  59. New(Objects);
  60. FillChar(Objects^,MAXOBJS*sizeof(Pointer),0);
  61. LightCount := 0;
  62. New(Lights);
  63. FillChar(Lights^,MAXOBJS*sizeof(Pointer),0);
  64. TextureCount := 0;
  65. New(Textures);
  66. FillChar(Textures^,MAXTEXTURES*sizeof(Pointer),0);
  67. end;
  68. Procedure TTracer.AddObject(aNew : PColObj);
  69. begin
  70. If ObjectCount = MaxObjs then
  71. begin
  72. Write('Object array overflow! :(');
  73. exit;
  74. end;
  75. Inc(ObjectCount);
  76. Objects^[ObjectCount] := aNew;
  77. end;
  78. Procedure TTracer.AddTexture(aNew : PTexture);
  79. begin
  80. If TextureCount = MaxTextures then
  81. begin
  82. Write('Texture array overflow! :(');
  83. exit;
  84. end;
  85. Inc(TextureCount);
  86. Textures^[TextureCount] := aNew;
  87. end;
  88. Procedure TTracer.AddLight(aNew : PLight);
  89. begin
  90. If LightCount = MaxObjs then
  91. begin
  92. Write('Object array overflow! :(');
  93. exit;
  94. end;
  95. Inc(LightCount);
  96. Lights^[LightCount] := aNew;
  97. end;
  98. Function TTracer.GetObject(Index:word):PColObj;
  99. begin
  100. if Index > ObjectCount then GetObject := nil
  101. else GetObject := PColObj(Objects^[Index]);
  102. end;
  103. Function TTracer.GetLight(Index:word):PLight;
  104. begin
  105. if Index > LightCount then getLight := nil
  106. else GetLight := PLight(Lights^[Index]);
  107. end;
  108. Procedure TTracer.Trace;
  109. begin
  110. end;
  111. Procedure TTracer.SetPlane(aLLPos,aUp,aRight : tVec);
  112. begin
  113. with View do begin LLPos := aLLPos; Up:=aUp;Right:=aRight;end;
  114. end;
  115. Procedure TTracer.SetCamera;
  116. var
  117. Dist,Ds,Ds2 : tVec;
  118. D,Len : float;
  119. aSx,aCx,aSy,aCy,aSz,aCz : float;
  120. Trans : TTRANSFORM;
  121. begin
  122. VLinear(Dist,aTarg,aOrg,1,-1);
  123. View.CamPos := aOrg;
  124. D := sqrt(VDot(Dist,Dist));
  125. View.LLpos := aTarg;
  126. if (Dist.X = 0) and (Dist.Z=0) then VSet(View.Right,0,0,1)
  127. else VSet(View.Right,Dist.Z,0,-Dist.X);
  128. Compute_Axis_Rotation_Transform(trans,Dist,M_PI_180*aRoll);
  129. MTransPoint(View.Right,View.Right,Trans);
  130. VCross(View.Up,Dist,View.Right);
  131. VNorm(View.Right,D*TAN(PI*aFov/360));
  132. VNorm(View.Up,D*TAN(PI*aFov/360)/aXtoY);
  133. VLinear(View.LLpos,View.LLpos,View.up,1,-1);
  134. VLinear(View.LLpos,View.LLpos,View.Right,1,-1);
  135. VLinear(View.up,View.up,View.up,1,1);
  136. VLinear(View.Right,View.Right,View.Right,1,1);
  137. end;
  138. Procedure TTracer.Load(Inp:string);
  139. var
  140. Header : string;
  141. ID : ObjID;
  142. m_PSph : PSphere;
  143. m_PPl : PSurfPlane;
  144. m_Tri : PTriangle;
  145. m_PLight : POmni;
  146. m_Quad : PQuad;
  147. m_Texture : PTexture;
  148. m_PInterS : PInterS;
  149. m_Cone : PCone;
  150. tName : string[13];
  151. Rad,Len : float;
  152. NeedAdd : boolean;
  153. F : File;
  154. Cur : LongInt;
  155. Ls : longint;
  156. Pivot,Axis : tVec;
  157. Ang : float;
  158. begin
  159. Assign(F,Inp);
  160. {$I-}
  161. Reset(F,1);
  162. if IOResult <> 0 then
  163. begin
  164. WriteLn('Error opening ',Inp);
  165. Halt(250);
  166. end;
  167. BlockRead(F,Header,12);
  168. if Header <> TRAHeader then
  169. begin
  170. WriteLn('Not Our format');
  171. Halt(240);
  172. end;
  173. BlockRead(F,Cur,4);
  174. if Cur <> curver then
  175. begin
  176. WriteLn('Not current version');
  177. Halt(230);
  178. end;
  179. while Not EOF(F) do
  180. begin
  181. BlockRead(F,ID,sizeof(ObjID));
  182. case ID of
  183. F_ROTATE:
  184. begin
  185. BlockRead(F,Ls,sizeof(LongInt));
  186. BlockRead(F,Pivot,vecsize);
  187. BlockRead(F,Axis,vecsize);
  188. BlockRead(F,Ang,sizeof(float));
  189. Ls := ObjectCount+1 - Ls;
  190. if Ls>=0 then for Cur := ObjectCount downto Ls do
  191. SetRotate(Pivot,Axis,Ang,Objects^[Cur]);
  192. end;
  193. F_TRANSLATE:
  194. begin
  195. BlockRead(F,Ls,sizeof(LongInt));
  196. BlockRead(F,Pivot,vecsize);
  197. Ls := ObjectCount+1 - Ls;
  198. if Ls>=0 then for Cur := ObjectCount downto Ls do
  199. SetTranslate(Pivot,Objects^[Cur]);
  200. end;
  201. F_SCALE:
  202. begin
  203. BlockRead(F,Ls,sizeof(LongInt));
  204. BlockRead(F,Pivot,vecsize);
  205. BlockRead(F,Axis,vecsize);
  206. Ls := ObjectCount+1 - Ls;
  207. if Ls>=0 then for Cur := ObjectCount downto Ls do
  208. SetScale(Pivot,Axis,Objects^[Cur]);
  209. end;
  210. F_TEXTURE:
  211. begin
  212. BlockRead(F,Ls,sizeof(LongInt));
  213. BlockRead(F,TName,13);
  214. BlockRead(F,rad,sizeof(float));
  215. BlockRead(F,Len,sizeof(float));
  216. for cur := 1 to TextureCount do
  217. if Textures^[cur]^.Name = TName then break;
  218. if Textures^[cur]^.Name = TName then m_Texture :=Textures^[cur]
  219. else
  220. begin
  221. New(m_Texture,Init(1,1));
  222. m_Texture^.LoadTGA(TName);
  223. AddTexture(m_Texture);
  224. end;
  225. Ls := ObjectCount+1 - Ls;
  226. if Ls>=0 then for Cur := ObjectCount downto Ls do
  227. PSurfObj(Objects^[Cur])^.SetTexture(m_Texture,rad,len);
  228. end;
  229. F_INTER_SPHERE:
  230. begin
  231. New(m_PInterS,Load(F));
  232. AddObject(m_PInterS);
  233. end;
  234. F_CONE:
  235. begin
  236. New(m_Cone,Load(F));
  237. AddObject(m_Cone);
  238. end;
  239. F_OBJ_SPHERE:
  240. begin
  241. New(m_PSph,Load(F));
  242. AddObject(m_PSph);
  243. end;
  244. F_OBJ_SURF_PLANE:
  245. begin
  246. New(m_PPl,Load(F));
  247. AddObject(m_PPl);
  248. end;
  249. F_TRI_PLANE:
  250. begin
  251. New(m_PPl,TriLoad(F));
  252. AddObject(m_PPl);
  253. end;
  254. F_TRI:
  255. begin
  256. New(m_Tri,Load(F));
  257. AddObject(m_Tri);
  258. end;
  259. F_QUAD:
  260. begin
  261. New(m_Quad,Load(F));
  262. AddObject(m_Quad);
  263. end;
  264. F_LIGHT_OMNI:
  265. begin
  266. New(m_PLight,Load(F));
  267. AddLight(m_PLight);
  268. end;
  269. F_VIEWPORT:
  270. begin
  271. BlockRead(F,View.CamPos,vecsize);
  272. BlockRead(F,View.LLPos,vecsize);
  273. BlockRead(F,View.Up,vecsize);
  274. BlockRead(F,View.Right,vecsize);
  275. end;
  276. F_AMBIENT: LoadRGB(F,Ambient);
  277. F_CAMERA : LoadCamera(F);
  278. end;
  279. end;
  280. Close(F);
  281. end;
  282. Procedure TTracer.LoadCamera;
  283. var
  284. org,targ : tVec;
  285. roll, fov, xtoy : float;
  286. begin
  287. BlockRead(F,org,vecsize);
  288. BlockRead(F,targ,vecsize);
  289. BlockRead(F,roll,sizeof(float));
  290. BlockRead(F,fov,sizeof(float));
  291. BlockRead(F,xtoy,sizeof(float));
  292. SetCamera(org,targ,roll,fov, xtoy);
  293. end;
  294. Procedure TTracer.Save;
  295. var
  296. F:FILE;
  297. i:word;
  298. begin
  299. Assign(F,Out);
  300. Rewrite(F,1);
  301. BlockWrite(F,TRAHeader,12);
  302. BlockWrite(F,CurVer,sizeof(LongInt));
  303. if aView then
  304. begin
  305. I:=Ord(F_VIEWPORT);BlockWrite(F,I,1);
  306. BlockWrite(F,View.CamPos,vecsize);
  307. BlockWrite(F,View.LLPos,vecsize);
  308. BlockWrite(F,View.Up,vecsize);
  309. BlockWrite(F,View.Right,vecsize);
  310. end;
  311. I:=Ord(F_AMBIENT);BlockWrite(F,I,1);SaveRGB(F,Ambient);
  312. for i := 1 to ObjectCount do if Objects^[i] <> nil then
  313. if Pos('_FILE_',Objects^[i]^.OType) <> 0 then
  314. PFileObj(Objects^[i])^.Save(F);
  315. for i := 1 to LightCount do if Lights^[i] <> nil then
  316. begin
  317. if Pos('_FILE_',Lights^[i]^.OType) <> 0 then
  318. PLight(Lights^[i])^.Save(F);
  319. end;
  320. Close(F);
  321. end;
  322. Function TTracer.FindISect(aRay:TRay;var oT:float):PObject;
  323. var
  324. Cur : float;
  325. i : integer;
  326. begin
  327. FindISect:=nil;
  328. oT:=INF;
  329. for i := 1 to ObjectCount do
  330. begin
  331. Cur := Objects^[i]^.ISect(@aRay);
  332. if (Cur < oT) and (Cur > EPS) and (Cur < MaxDeep) then
  333. begin
  334. FindISect := Objects^[i];
  335. oT := Cur;
  336. end;
  337. end;
  338. end;{TGATrace.FindISect}
  339. Destructor TTracer.Done;
  340. var
  341. i : word;
  342. begin
  343. for i := 1 to ObjectCount do Dispose(Objects^[i],Done);
  344. for i := 1 to LightCount do Dispose(Lights^[i],Done);
  345. for i := 1 to TextureCount do Dispose(Textures^[i],Done);
  346. Dispose(Objects);
  347. Dispose(Lights);
  348. Dispose(Textures);
  349. end;
  350. {----------------------------------------------------}
  351. Procedure SetRotate(Pivot,Axis:tVec;Ang:float;var ob : PObject);
  352. var
  353. p_inv : tVec;
  354. TR,tr2 : TTRANSFORM;
  355. begin
  356. if ob = nil then exit;
  357. if Pos('_SURF_',ob^.OType) = 0 then exit;
  358. VLinear(p_inv,pivot,pivot,0,-1);
  359. Compute_Translation_Transform(TR,p_inv);
  360. Compute_Axis_Rotation_Transform(TR2,axis,ang*M_PI_180);
  361. Compose_Transforms(tr,tr2);
  362. Compute_Translation_Transform(TR2,pivot);
  363. Compose_Transforms(tr,tr2);
  364. PSurfObj(ob)^.Transform(tr);
  365. end;{LoadRotate}
  366. {----------------------------------------------------}
  367. Procedure SetTranslate(v:tVec;var ob : PObject);
  368. var
  369. TR : TTRANSFORM;
  370. begin
  371. if ob = nil then exit;
  372. if Pos('_SURF_',ob^.OType) = 0 then exit;
  373. Compute_Translation_Transform(TR,v);
  374. PSurfObj(ob)^.Transform(tr);
  375. end;{LoadTranslate}
  376. {----------------------------------------------------}
  377. Procedure SetScale(Pivot, V : tVec;var ob : PObject);
  378. var
  379. p_inv : tVec;
  380. TR,tr2 : TTRANSFORM;
  381. begin
  382. if ob = nil then exit;
  383. if Pos('_SURF_',ob^.OType) = 0 then exit;
  384. VLinear(p_inv,pivot,pivot,0,-1);
  385. Compute_Translation_Transform(TR,p_inv);
  386. Compute_Scaling_Transform(TR2,v);
  387. Compose_Transforms(tr,tr2);
  388. Compute_Translation_Transform(TR2,pivot);
  389. Compose_Transforms(tr,tr2);
  390. PSurfObj(ob)^.Transform(tr);
  391. end;{LoadScale}
  392. {----------------------------------------------------}
  393. END.