yazdmich

Untitled

Sep 25th, 2014
242
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 30.47 KB | None | 0 0
  1. import GUI
  2.  
  3. module Vector
  4. export Set, Magnitude, Normal, Normalized, Negative, Dot, Cross, Add, Mult
  5. %%%
  6. function Set (x : real, y : real, z : real) : array 1 .. 3 of real
  7. var v : array 1 .. 3 of real
  8. v (1) := x
  9. v (2) := y
  10. v (3) := z
  11. result v
  12. end Set
  13. %%%
  14. function Magnitude (v : array 1 .. 3 of real) : real
  15. result sqrt ((v (1) * v (1)) + (v (2) * v (2)) + (v (3) * v (3)))
  16. end Magnitude
  17. %%%
  18. function Normal (v : array 1 .. 3 of real) : array 1 .. 3 of real
  19. var vect : array 1 .. 3 of real
  20. var mag : real := sqrt ((v (1) * v (1)) + (v (2) * v (2)) + (v (3) * v (3)))
  21. if mag > 0 then
  22. vect (1) := v (1) / mag
  23. vect (2) := v (2) / mag
  24. vect (3) := v (3) / mag
  25. else
  26. vect (1) := v (1)
  27. vect (2) := v (2)
  28. vect (3) := v (3)
  29. end if
  30. result vect
  31. end Normal
  32. %%%
  33. function Normalized (x : real, y : real, z : real) : array 1 .. 3 of real
  34. var v : array 1 .. 3 of real
  35. v (1) := x
  36. v (2) := y
  37. v (3) := z
  38. v := Normal (v)
  39. result v
  40. end Normalized
  41. %%%
  42. function Negative (v : array 1 .. 3 of real) : array 1 .. 3 of real
  43. var vect : array 1 .. 3 of real
  44. vect (1) := -v (1)
  45. vect (2) := -v (2)
  46. vect (3) := -v (3)
  47. result vect
  48. end Negative
  49. %%%
  50. function Dot (v : array 1 .. 3 of real, v2 : array 1 .. 3 of real) : real
  51. result v (1) * v2 (1) + v (2) * v2 (2) + v (3) * v2 (3)
  52. end Dot
  53. %%%
  54. function Cross (v : array 1 .. 3 of real, v2 : array 1 .. 3 of real) : array 1 .. 3 of real
  55. var vect : array 1 .. 3 of real
  56. vect (1) := v (2) * v2 (3) - v (3) * v2 (2)
  57. vect (2) := v (3) * v2 (1) - v (1) * v2 (3)
  58. vect (3) := v (1) * v2 (2) - v (2) * v2 (1)
  59. result vect
  60. end Cross
  61. %%%
  62. function Add (v : array 1 .. 3 of real, v2 : array 1 .. 3 of real) : array 1 .. 3 of real
  63. var vect : array 1 .. 3 of real
  64. vect (1) := v (1) + v2 (1)
  65. vect (2) := v (2) + v2 (2)
  66. vect (3) := v (3) + v2 (3)
  67. result vect
  68. end Add
  69. %%%
  70. function Mult (v : array 1 .. 3 of real, scalar : real) : array 1 .. 3 of real
  71. var vect : array 1 .. 3 of real
  72. vect (1) := v (1) * scalar
  73. vect (2) := v (2) * scalar
  74. vect (3) := v (3) * scalar
  75. result vect
  76. end Mult
  77. end Vector
  78. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  79. module Colour
  80. export Set, Brightness, Scalar, Add, Mult, Average, Clip
  81.  
  82. function Set (r : real, g : real, b : real, s : real) : array 1 .. 4 of real
  83. var col : array 1 .. 4 of real
  84. col (1) := r
  85. col (2) := g
  86. col (3) := b
  87. col (4) := s
  88. result col
  89. end Set
  90. %%%
  91. function Brightness (c : array 1 .. 4 of real) : real
  92. result (c (1) + c (2) + c (3)) / 3
  93. end Brightness
  94. %%%
  95. function Scalar (c : array 1 .. 4 of real, scalar : real) : array 1 .. 4 of real
  96. var col : array 1 .. 4 of real
  97. col (1) := c (1) * scalar
  98. col (2) := c (2) * scalar
  99. col (3) := c (3) * scalar
  100. col (4) := c (4)
  101. result col
  102. end Scalar
  103. %%%
  104. function Add (c : array 1 .. 4 of real, c2 : array 1 .. 4 of real) : array 1 .. 4 of real
  105. var col : array 1 .. 4 of real
  106. col (1) := c (1) + c2 (1)
  107. col (2) := c (2) + c2 (2)
  108. col (3) := c (3) + c2 (3)
  109. col (4) := c (4)
  110. result col
  111. end Add
  112. %%%
  113. function Mult (c : array 1 .. 4 of real, c2 : array 1 .. 4 of real) : array 1 .. 4 of real
  114. var col : array 1 .. 4 of real
  115. col (1) := c (1) * c2 (1)
  116. col (2) := c (2) * c2 (2)
  117. col (3) := c (3) * c2 (3)
  118. col (4) := c (4)
  119. result col
  120. end Mult
  121. %%%
  122. function Average (c : array 1 .. 4 of real, c2 : array 1 .. 4 of real) : array 1 .. 4 of real
  123. var col : array 1 .. 4 of real
  124. col (1) := (c (1) + c2 (1)) / 2
  125. col (2) := (c (2) + c2 (2)) / 2
  126. col (3) := (c (3) + c2 (3)) / 2
  127. col (4) := c (4)
  128. result col
  129. end Average
  130. %%%
  131. function Clip (c : array 1 .. 4 of real) : array 1 .. 4 of real
  132. var col : array 1 .. 4 of real
  133. var alllight : real := c (1) + c (2) + c (3)
  134. var excesslight : real := alllight - 3
  135. %
  136. if excesslight > 0 then
  137. col (1) := c (1) + excesslight * (c (1) / alllight)
  138. col (2) := c (2) + excesslight * (c (2) / alllight)
  139. col (3) := c (3) + excesslight * (c (3) / alllight)
  140. else
  141. col (1) := c (1)
  142. col (2) := c (2)
  143. col (3) := c (3)
  144. end if
  145. if col (1) > 1 then
  146. col (1) := 1
  147. end if
  148. if col (2) > 1 then
  149. col (2) := 1
  150. end if
  151. if col (3) > 1 then
  152. col (3) := 1
  153. end if
  154. %
  155. if col (1) < 0 then
  156. col (1) := 0
  157. end if
  158. if col (2) < 0 then
  159. col (2) := 0
  160. end if
  161. if col (3) < 0 then
  162. col (3) := 0
  163. end if
  164. col (4) := c (4)
  165. result col
  166. end Clip
  167. end Colour
  168. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  169. module Camera
  170. import Vector
  171. export Direction, Right, Down
  172.  
  173. function Direction (pos : array 1 .. 3 of real, look : array 1 .. 3 of real) : array 1 .. 3 of real
  174. result Vector.Normal (Vector.Negative (Vector.Add (pos, Vector.Negative (look))))
  175. end Direction
  176. %%%
  177. function Right (dir : array 1 .. 3 of real) : array 1 .. 3 of real
  178. var y : array 1 .. 3 of real := Vector.Set (0, 1, 0)
  179. result Vector.Normal (Vector.Cross (y, dir))
  180. end Right
  181. %%%
  182. function Down (right : array 1 .. 3 of real, dir : array 1 .. 3 of real) : array 1 .. 3 of real
  183. result Vector.Cross (right, dir)
  184. end Down
  185. end Camera
  186. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  187. class Light
  188. export CreateLight, LightPosition, LightColour
  189. var position : array 1 .. 3 of real
  190. var ccolour : array 1 .. 4 of real
  191.  
  192. procedure CreateLight (pos : array 1 .. 3 of real, col : array 1 .. 4 of real)
  193. position := pos
  194. ccolour := col
  195. end CreateLight
  196. %%%
  197. function LightPosition : array 1 .. 3 of real
  198. result position
  199. end LightPosition
  200. %%%
  201. function LightColour : array 1 .. 4 of real
  202. result ccolour
  203. end LightColour
  204. end Light
  205. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  206. class Primitive
  207. export CreatePrimitive, getPrimitivePN, getPrimitiveRD, getPrimitiveColour, getPrimitiveShape, findIntersection, getNormalAt
  208. var pos_normal : array 1 .. 3 of real
  209. var rad_dis : real
  210. var ccolour : array 1 .. 4 of real
  211. var shape : int
  212. %%%
  213. procedure CreatePrimitive (p : array 1 .. 3 of real, r : real, c : array 1 .. 4 of real, sh : int)
  214. pos_normal := p
  215. rad_dis := r
  216. ccolour := c
  217. shape := sh
  218. end CreatePrimitive
  219. %%%
  220. function getPrimitivePN : array 1 .. 3 of real
  221. result pos_normal
  222. end getPrimitivePN
  223. %%%
  224. function getPrimitiveRD : real
  225. result rad_dis
  226. end getPrimitiveRD
  227. %%%
  228. function getPrimitiveColour : array 1 .. 4 of real
  229. result ccolour
  230. end getPrimitiveColour
  231. %%%
  232. function getPrimitiveShape : int
  233. result shape
  234. end getPrimitiveShape
  235. %%%
  236. function getNormalAt (point : array 1 .. 3 of real) : array 1 .. 3 of real
  237. if shape = 0 then
  238. result pos_normal
  239. elsif shape = 1 then
  240. var nvect : array 1 .. 3 of real
  241. %nvect := Vector.Normal (Vector.Add (point, Vector.Negative (pos_normal)))
  242. var mag : real
  243. nvect (1) := point (1) - pos_normal (1)
  244. nvect (2) := point (2) - pos_normal (2)
  245. nvect (3) := point (3) - pos_normal (3)
  246. mag := sqrt (nvect (1) * nvect (1) + nvect (2) * nvect (2) + nvect (3) * nvect (3))
  247. nvect (1) := nvect (1) / mag
  248. nvect (2) := nvect (2) / mag
  249. nvect (3) := nvect (3) / mag
  250. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  251. result nvect
  252. end if
  253. end getNormalAt
  254. %%%
  255. function findIntersection (ray_origin : array 1 .. 3 of real, ray_direction : array 1 .. 3 of real) : real
  256. if shape = 0 then
  257. %var a : real := Vector.Dot (pos_normal, ray_direction)
  258. var a : real := pos_normal (1) * ray_direction (1) + pos_normal (2) * ray_direction (2) + pos_normal (3) * ray_direction (3)
  259. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  260. if a = 0 then
  261. result - 1
  262. else
  263. %var b : real := Vector.Dot (pos_normal, Vector.Add (ray_origin, Vector.Negative (Vector.Mult (pos_normal, rad_dis))))
  264. var b : real := pos_normal (1) * (ray_origin (1) - (pos_normal (1) * rad_dis)) + pos_normal (2) * (ray_origin (2) - (pos_normal (2) * rad_dis)) + pos_normal (3) * (ray_origin (3)
  265. - (pos_normal (3) *
  266. rad_dis))
  267. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  268. var c : real := -1 * b / a
  269. if c > 0.00001 then
  270. result c
  271. else
  272. result - 1
  273. end if
  274. end if
  275. elsif shape = 1 then
  276. var b, c, discriminant : real
  277. b := 2 * ((ray_origin (1) - pos_normal (1)) * ray_direction (1) + (ray_origin (2) - pos_normal (2)) * ray_direction (2) + (ray_origin (3) - pos_normal (3)) * ray_direction (3))
  278. c := (ray_origin (1) - pos_normal (1)) ** 2 + (ray_origin (2) - pos_normal (2)) ** 2 + (ray_origin (3) - pos_normal (3)) ** 2 - rad_dis * rad_dis
  279. discriminant := b * b - 4 * c
  280. if discriminant > 0 then
  281. discriminant := sqrt (discriminant)
  282. var root_1 := ((-1 * b - discriminant) / 2) - 0.00001
  283. if root_1 > 0 then
  284. result root_1
  285. else
  286. var root_2 := ((discriminant - b) / 2) - 0.00001
  287. result root_2
  288. end if
  289. else
  290. result - 1
  291. end if
  292. end if
  293. end findIntersection
  294. end Primitive
  295. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  296. function winningObjIndex (obj : array 1 .. * of real) : int
  297. %
  298. var objCount : int := upper (obj)
  299. if objCount = 0 then
  300. result - 1
  301. else
  302. %
  303. if objCount = 1 then
  304. if obj (1) > 0 then
  305. result 1
  306. else
  307. result - 1
  308. end if
  309. %
  310. else
  311. var min_index : int
  312. var maxi : real := 0
  313. for i : 1 .. objCount
  314. if maxi < obj (i) then
  315. maxi := obj (i)
  316. end if
  317. end for
  318. %
  319. if maxi > 0 then
  320. for i : 1 .. objCount
  321. if obj (i) > 0 and obj (i) <= maxi then
  322. maxi := obj (i)
  323. min_index := i
  324. end if
  325. end for
  326. result min_index
  327. else
  328. result - 1
  329. end if
  330. end if
  331. end if
  332. end winningObjIndex
  333. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  334. function getColourAt (pos : array 1 .. 3 of real, dir : array 1 .. 3 of real, object : array 1 .. * of ^Primitive,
  335. winningIndex : int, lights : array 1 .. * of ^Light, accuracy : real,
  336. ambientlight : real) : array 1 .. 4 of real
  337. %%%
  338. var mag : real
  339. var objCount : int := upper (object)
  340. var winning_object_colour : array 1 .. 4 of real := object (winningIndex) -> getPrimitiveColour
  341. var winning_object_normal : array 1 .. 3 of real := object (winningIndex) -> getNormalAt (pos)
  342. %var final_colour : array 1 .. 4 of real := Colour.Scalar (winning_object_colour, ambientlight)
  343. var final_colour : array 1 .. 4 of real
  344. final_colour (1) := winning_object_colour (1) * ambientlight
  345. final_colour (2) := winning_object_colour (2) * ambientlight
  346. final_colour (3) := winning_object_colour (3) * ambientlight
  347. final_colour (4) := winning_object_colour (4)
  348. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  349. var ref_dir : array 1 .. 3 of real
  350.  
  351. if winning_object_colour (4) > 0 and winning_object_colour (4) <= 1 then
  352. %ref_dir := Vector.Normal (Vector.Add (Vector.Negative (dir),
  353. % Vector.Mult (Vector.Add (Vector.Mult (winning_object_normal,
  354. % Vector.Dot (winning_object_normal,
  355. % Vector.Negative (dir))), dir), 2)))
  356. ref_dir (1) := -dir (1) + (((winning_object_normal (1) * (winning_object_normal (1) * (-dir (1)) + winning_object_normal (2) * (-dir (2)) + winning_object_normal (3) * (-dir (3)))) +
  357. dir (1))
  358. * 2)
  359. ref_dir (2) := -dir (2) + (((winning_object_normal (2) * (winning_object_normal (1) * (-dir (1)) + winning_object_normal (2) * (-dir (2)) + winning_object_normal (3) * (-dir (3)))) +
  360. dir (2))
  361. * 2)
  362. ref_dir (3) := -dir (3) + (((winning_object_normal (3) * (winning_object_normal (1) * (-dir (1)) + winning_object_normal (2) * (-dir (2)) + winning_object_normal (3) * (-dir (3)))) +
  363. dir (3))
  364. * 2)
  365. mag := sqrt (ref_dir (1) * ref_dir (1) + ref_dir (2) * ref_dir (2) + ref_dir (3) * ref_dir (3))
  366. ref_dir (1) := ref_dir (1) / mag
  367. ref_dir (2) := ref_dir (2) / mag
  368. ref_dir (3) := ref_dir (3) / mag
  369. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  370. var ref_intersections : array 1 .. objCount of real
  371. for r_index : 1 .. objCount
  372. if r_index not= winningIndex then
  373. ref_intersections (r_index) := object (r_index) -> findIntersection (pos, ref_dir)
  374. else
  375. ref_intersections (r_index) := -1
  376. end if
  377. end for
  378.  
  379. var index_of_winning_ref : int := winningObjIndex (ref_intersections)
  380.  
  381. if index_of_winning_ref not= -1 then
  382. if ref_intersections (index_of_winning_ref) > accuracy then
  383. %var ref_int_pos : array 1 .. 3 of real := Vector.Add (pos, Vector.Mult (ref_dir, ref_intersections (index_of_winning_ref)))
  384. var ref_int_pos : array 1 .. 3 of real
  385. ref_int_pos (1) := pos (1) + ref_dir (1) * ref_intersections (index_of_winning_ref)
  386. ref_int_pos (2) := pos (2) + ref_dir (2) * ref_intersections (index_of_winning_ref)
  387. ref_int_pos (3) := pos (3) + ref_dir (3) * ref_intersections (index_of_winning_ref)
  388. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  389. var ref_colour : array 1 .. 4 of real := getColourAt (ref_int_pos, ref_dir, object, index_of_winning_ref, lights, accuracy, ambientlight)
  390. %final_colour := Colour.Add (final_colour, Colour.Scalar (ref_colour, winning_object_colour (4)))
  391. final_colour (1) := final_colour (1) + ref_colour (1) * winning_object_colour (4)
  392. final_colour (2) := final_colour (2) + ref_colour (2) * winning_object_colour (4)
  393. final_colour (3) := final_colour (3) + ref_colour (3) * winning_object_colour (4)
  394. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  395. end if
  396. end if
  397. end if
  398. %
  399. var light_direction, lightPos : array 1 .. 3 of real
  400. var cosine_angle : real
  401. var shadowed : boolean
  402. var distance_to_light_magnitude : real
  403. var secondary_intersections : array 1 .. objCount of real
  404. %
  405. for light : 1 .. upper (lights)
  406. %light_direction := Vector.Normal (Vector.Add (lights (light) -> LightPosition, Vector.Negative (pos)))
  407. lightPos := lights (light) -> LightPosition
  408. light_direction (1) := lightPos (1) - pos (1)
  409. light_direction (2) := lightPos (2) - pos (2)
  410. light_direction (3) := lightPos (3) - pos (3)
  411. mag := sqrt (light_direction (1) * light_direction (1) + light_direction (2) * light_direction (2) + light_direction (3) * light_direction (3))
  412. light_direction (1) := light_direction (1) / mag
  413. light_direction (2) := light_direction (2) / mag
  414. light_direction (3) := light_direction (3) / mag
  415. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  416. %
  417. %cosine_angle := Vector.Dot (winning_object_normal, light_direction)
  418. cosine_angle := winning_object_normal (1) * light_direction (1) + winning_object_normal (2) * light_direction (2) + winning_object_normal (3) * light_direction (3)
  419. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  420. if cosine_angle > 0 then
  421.  
  422. shadowed := false
  423. %distance_to_light_magnitude := Vector.Magnitude (light_direction)
  424. distance_to_light_magnitude := sqrt (light_direction (1) * light_direction (1) + light_direction (2) * light_direction (2) + light_direction (3) * light_direction (3))
  425. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%5
  426. if shadowed = false then
  427. for i : 1 .. objCount
  428. if i not= winningIndex then
  429. secondary_intersections (i) := object (i) -> findIntersection (pos, light_direction)
  430. else
  431. secondary_intersections (i) := -1
  432. end if
  433. end for
  434. end if
  435.  
  436. for c : 1 .. objCount
  437. if secondary_intersections (c) > accuracy then %
  438. if secondary_intersections (c) <= distance_to_light_magnitude then
  439. shadowed := true
  440. exit when shadowed = true
  441. end if
  442. end if
  443. end for
  444.  
  445. var lightColour : array 1 .. 4 of real := lights (light) -> LightColour
  446. if shadowed = false then
  447. %final_colour := Colour.Add (final_colour, Colour.Mult (winning_object_colour, Colour.Scalar (lights (light) -> LightColour, cosine_angle)))
  448. final_colour (1) := final_colour (1) + winning_object_colour (1) * (lightColour (1) * cosine_angle)
  449. final_colour (2) := final_colour (2) + winning_object_colour (2) * (lightColour (2) * cosine_angle)
  450. final_colour (3) := final_colour (3) + winning_object_colour (3) * (lightColour (3) * cosine_angle)
  451. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  452. if winning_object_colour (4) > 0 and winning_object_colour (4) <= 1 then
  453. var specular : real := Vector.Dot (ref_dir, light_direction)
  454. if specular > 0 then
  455. specular := specular ** 10
  456. %final_colour := Colour.Add (final_colour, Colour.Scalar (lights (light) -> LightColour, (specular * winning_object_colour (4))))
  457. final_colour (1) := final_colour (1) + lightColour (1) * (specular * winning_object_colour (4))
  458. final_colour (2) := final_colour (2) + lightColour (2) * (specular * winning_object_colour (4))
  459. final_colour (3) := final_colour (3) + lightColour (3) * (specular * winning_object_colour (4))
  460. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  461. end if
  462. end if
  463. end if
  464. end if
  465. end for
  466. %final_colour := Colour.Clip (final_colour)
  467. var alllight : real := final_colour (1) + final_colour (2) + final_colour (3)
  468. var excesslight : real := alllight - 3
  469. %
  470. if excesslight > 0 then
  471. final_colour (1) := final_colour (1) + excesslight * (final_colour (1) / alllight)
  472. final_colour (2) := final_colour (2) + excesslight * (final_colour (2) / alllight)
  473. final_colour (3) := final_colour (3) + excesslight * (final_colour (3) / alllight)
  474. end if
  475. %
  476. if final_colour (1) > 1 then
  477. final_colour (1) := 1
  478. end if
  479. if final_colour (2) > 1 then
  480. final_colour (2) := 1
  481. end if
  482. if final_colour (3) > 1 then
  483. final_colour (3) := 1
  484. end if
  485. %
  486. if final_colour (1) < 0 then
  487. final_colour (1) := 0
  488. end if
  489. if final_colour (2) < 0 then
  490. final_colour (2) := 0
  491. end if
  492. if final_colour (3) < 0 then
  493. final_colour (3) := 0
  494. end if
  495. %
  496. result final_colour
  497. end getColourAt
  498. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  499. %%%%%%%%%%%%% Camera %%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  500. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  501. var camPos, look_at, camDir, camRight, camDown : array 1 .. 3 of real
  502. camPos := Vector.Set (-16, 6, 0)
  503. look_at := Vector.Set (0, 0, 0)
  504. camDir := Camera.Direction (camPos, look_at)
  505. camRight := Camera.Right (camDir)
  506. camDown := Camera.Down (camRight, camDir)
  507. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  508. %%%%%%%%%%%%% Lights %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  509. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  510. var lightCount : int := 1 % amount of lights to make
  511. var lights : array 1 .. lightCount of ^Light
  512. %
  513. for i : 1 .. lightCount
  514. new lights (i)
  515. end for
  516. % lights (i) -> CreateLight ((x,y,z),(r,g,b,s))
  517. lights (1) -> CreateLight (Vector.Set (0, 6, 0), Colour.Set (0.3, 0.3, 0.3, 0))
  518. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  519. %%%%%%%%%%%%% Objects %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  520. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  521. var objCount : int := 10 % Amount of objects u create
  522. var object : array 1 .. objCount of ^Primitive
  523. %
  524. for i : 1 .. objCount
  525. new object (i)
  526. end for
  527. % object (i) -> CreatePrimtive ((x,y,z),r,(r,g,b,s),shape)
  528. % shape 0, plane
  529. % shape 1, sphere
  530. % colour s, reflectiveness 0= none 1=full
  531. object (1) -> CreatePrimitive (Vector.Set (0, 1, 0), -1, Colour.Set (1, 1, 1, 1), 0)
  532. object (2) -> CreatePrimitive (Vector.Set (0, 0, -10), 1, Colour.Set (1, 0, 0, 0), 1)
  533. object (3) -> CreatePrimitive (Vector.Set (0, 0, -8), 1, Colour.Set (0, 1, 0, 0.1), 1)
  534. object (4) -> CreatePrimitive (Vector.Set (0, 0, -6), 1, Colour.Set (0, 0, 1, 0.2), 1)
  535. object (5) -> CreatePrimitive (Vector.Set (0, 0, -4), 1, Colour.Set (1, 1, 0, 0.3), 1)
  536. object (6) -> CreatePrimitive (Vector.Set (0, 0, -2), 1, Colour.Set (0, 1, 1, 0.4), 1)
  537. object (7) -> CreatePrimitive (Vector.Set (0, 0, 0), 1, Colour.Set (1, 1, 1, 0.5), 1)
  538. object (8) -> CreatePrimitive (Vector.Set (0, 0, 2), 1, Colour.Set (0, 1, 1, 0.6), 1)
  539. object (9) -> CreatePrimitive (Vector.Set (0, 0, 4), 1, Colour.Set (1, 1, 0, 0.7), 1)
  540. object (10) -> CreatePrimitive (Vector.Set (0, 0, 6), 1, Colour.Set (0, 0, 1, 0.8), 1)
  541. /*
  542. object (11) -> CreatePrimitive (Vector.Set (0, 0, 8), 1, Colour.Set (0, 1, 0, 0.9), 1)
  543. object (12) -> CreatePrimitive (Vector.Set (0, 0, 10), 1, Colour.Set (1, 0, 0, 1), 1)
  544. object (13) -> CreatePrimitive (Vector.Set (1, 0, 0), 2, Colour.Set (1, 1, 1, 1), 0)
  545. */
  546. %%%%%%%%%%%%%%Ray/Intersection Variables %%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  547. var cam_ray_direction : array 1 .. 3 of real
  548. var intersection_pos, intersection_ray_dir : array 1 .. 3 of real
  549. var intersection_colour : array 1 .. 4 of real
  550. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%Basic Variables
  551. const width : int := 640
  552. const height : int := 480
  553. var thisone : int
  554. var xamnt, yamnt : real
  555. var aspectratio : real := width / height
  556. var intersections : array 1 .. objCount of real
  557. var winningIndex : int
  558. var accuracy : real := 0.00001
  559. var ambientlight : real := 0.2
  560. var mag : real
  561. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%Get Info GUI
  562. View.Set ("graphics:640;480")
  563. var aadepth : int := 1
  564. var aafield, aalabel : int
  565. procedure changeaa (text : string)
  566. var ntext : string := ""
  567. for i : 1 .. length (text)
  568. if ord (text (i)) > 47 and ord (text (i)) < 58 then
  569. ntext += text (i)
  570. end if
  571. end for
  572. if ntext not= "" then
  573. aadepth := strint (ntext)
  574. drawfillbox (110, 10, 157, 25, white)
  575. GUI.SetLabel (aalabel, ntext + "x MSAA")
  576. GUI.SetText (aafield, ntext)
  577. end if
  578. end changeaa
  579. %
  580. procedure quuit
  581. quit
  582. end quuit
  583. %
  584. aalabel := GUI.CreateLabel (100, 13, intstr (aadepth) + "x MSAA")
  585. aafield := GUI.CreateTextFieldFull (160, 13, 50, intstr (aadepth), changeaa, GUI.INDENT, 0, 0)
  586. var cont : int := GUI.CreateButton (8, 10, 0, "Continue", GUI.Quit)
  587. var quitBtn : int := GUI.CreateButton (576, 10, 0, "Quit", quuit)
  588.  
  589. var textbox := GUI.CreateTextBoxFull (10, 40, 620, 430,
  590. GUI.INDENT, 0)
  591.  
  592. procedure getlight (i : int)
  593. var temp : array 1 .. 3 of real := lights (i) -> LightPosition
  594. var temp2 : array 1 .. 4 of real := lights (i) -> LightColour
  595. var line : string
  596. line := "Light " + intstr (i) + " at (" + realstr (temp (1), 4) + ", " + realstr (temp (2), 4) + ", " + realstr (temp (3), 4) + ") with Colour: (R: " + realstr (floor (temp2 (1) * 255), 4) +
  597. ", G: " +
  598. realstr (floor (temp2 (2) * 255), 4) + ", B: " + realstr (floor (temp2 (3) * 255), 4) + ", S: " + realstr (temp2 (4), 4) + ")"
  599. GUI.AddLine (textbox, line)
  600. end getlight
  601. %
  602. procedure getshape (i : int)
  603. var temp : array 1 .. 3 of real := object (i) -> getPrimitivePN
  604. var temp2 : array 1 .. 4 of real := object (i) -> getPrimitiveColour
  605. var t : real := object (i) -> getPrimitiveRD
  606. var t2 : real := object (i) -> getPrimitiveShape
  607. var ty, pn, rd, line : string
  608. if t2 = 0 then
  609. ty := "Plane"
  610. pn := "Normal of"
  611. rd := "Distance of"
  612. elsif t2 = 1 then
  613. ty := "Sphere"
  614. pn := "Center at"
  615. rd := "Radius of"
  616. end if
  617. line := ty + ": " + pn + " (" + realstr (temp (1), 4) + ", " + realstr (temp (2), 4) + ", " + realstr (temp (3), 4) + ") and " + rd + realstr (t, 4) + " with Colour: (R: " +
  618. realstr (floor (temp2 (1) *
  619. 255), 4) +
  620. ", G: " +
  621. realstr (floor (temp2 (2) * 255), 4) + ", B: " + realstr (floor (temp2 (3) * 255), 4) + ", S: " + realstr (temp2 (4), 4) + ")"
  622. GUI.AddLine (textbox, line)
  623. end getshape
  624. %
  625. var line : string
  626. line := "Resolution: " + intstr (width) + "x" + intstr (height)
  627. GUI.AddLine (textbox, line)
  628. line := "Ambient Light: " + realstr (ambientlight, 4)
  629. GUI.AddLine (textbox, line)
  630. line := ""
  631. GUI.AddLine (textbox, line)
  632. line := "Camera at: (" + realstr (camPos (1), 4) + ", " + realstr (camPos (2), 4) + ", " + realstr (camPos (3), 4) + ")"
  633. GUI.AddLine (textbox, line)
  634. line := "Camera looking at: (" + realstr (look_at (1), 4) + "," + realstr (look_at (2), 4) + "," + realstr (look_at (3), 4) + ")"
  635. GUI.AddLine (textbox, line)
  636. line := ""
  637. GUI.AddLine (textbox, line)
  638. line := intstr (lightCount) + " Light(s)"
  639. GUI.AddLine (textbox, line)
  640. for i : 1 .. lightCount
  641. getlight (i)
  642. end for
  643. line := ""
  644. GUI.AddLine (textbox, line)
  645. line := intstr (objCount) + " Shape(s)"
  646. GUI.AddLine (textbox, line)
  647. for i : 1 .. objCount
  648. getshape (i)
  649. end for
  650.  
  651. loop
  652. exit when GUI.ProcessEvent
  653. end loop
  654. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%AA variables
  655. var aaindex : int
  656. var aathreshold : real := 0.1
  657. var aalev : int := aadepth ** 2
  658. var AR, AG, AB : array 0 .. aalev - 1 of real
  659. var TR, TG, TB : real
  660. var LR, LG, LB : array 0 .. width - 1, 0 .. height - 1 of real
  661. var gcol : array 1 .. 3 of real
  662. %%%%%%%%%%%%%%%%%%%
  663. View.Set ("graphics:" + intstr (width) + ";" + intstr (height) + ",nobuttonbar,offscreenonly")
  664. var endtime, ctime1, ctime2 : int
  665. var ctt, btt : real := 0
  666. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%Assign for variables
  667. var h_y : real := height + 0.5
  668. var w_a : real := aspectratio / width
  669. var x_w : real := (width - height) / height / 2
  670. var h_a : real := height * aspectratio
  671. var y_h : real := (height - width) / width / 2
  672. var a_j : int := aadepth - 1
  673.  
  674. function msaa (x : int, y : int) : array 1 .. 3 of real
  675. var TR, TG, TB : real := 0
  676. var rcol : array 1 .. 3 of real
  677. for aax : 0 .. aadepth - 1
  678. for aay : 0 .. aadepth - 1
  679. aaindex := aay * aadepth + aax
  680.  
  681. if width > height then
  682. xamnt := (x + aax / a_j) * w_a - x_w
  683. yamnt := ((height - y) + aax / a_j) / height
  684. elsif height > width then
  685. xamnt := (x + aax / a_j) / width
  686. yamnt := ((height - y) + aax / a_j) / h_a - y_h
  687. else
  688. xamnt := (x + aax / a_j) / width
  689. yamnt := ((height - y) + aax / a_j) / height
  690. end if
  691.  
  692. cam_ray_direction (1) := camDir (1) + camRight (1) * (xamnt - 0.5) + camDown (1) * (yamnt - 0.5)
  693. cam_ray_direction (2) := camDir (2) + camRight (2) * (xamnt - 0.5) + camDown (2) * (yamnt - 0.5)
  694. cam_ray_direction (3) := camDir (3) + camRight (3) * (xamnt - 0.5) + camDown (3) * (yamnt - 0.5)
  695. mag := sqrt (cam_ray_direction (1) * cam_ray_direction (1) + cam_ray_direction (2) * cam_ray_direction (2) + cam_ray_direction (3) * cam_ray_direction (3))
  696. cam_ray_direction (1) := cam_ray_direction (1) / mag
  697. cam_ray_direction (2) := cam_ray_direction (2) / mag
  698. cam_ray_direction (3) := cam_ray_direction (3) / mag
  699.  
  700. for i : 1 .. objCount
  701. intersections (i) := object (i) -> findIntersection (camPos, cam_ray_direction)
  702. end for
  703. winningIndex := winningObjIndex (intersections)
  704.  
  705. if winningIndex = -1 then
  706. AR (aaindex) := 0
  707. AG (aaindex) := 0
  708. AB (aaindex) := 0
  709. else
  710. if intersections (winningIndex) > accuracy then
  711. %intersection_pos := Vector.Add (camPos, Vector.Mult (cam_ray_direction, intersections (winningIndex)))
  712. intersection_pos (1) := camPos (1) + cam_ray_direction (1) * intersections (winningIndex)
  713. intersection_pos (2) := camPos (2) + cam_ray_direction (2) * intersections (winningIndex)
  714. intersection_pos (3) := camPos (3) + cam_ray_direction (3) * intersections (winningIndex)
  715. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  716. intersection_colour := getColourAt (intersection_pos, cam_ray_direction, object, winningIndex, lights, accuracy, ambientlight)
  717. AR (aaindex) := intersection_colour (1)
  718. AG (aaindex) := intersection_colour (2)
  719. AB (aaindex) := intersection_colour (3)
  720. end if
  721. end if
  722.  
  723. end for
  724. end for
  725.  
  726. for i : 0 .. aalev - 1
  727. TR := TR + AR (i)
  728. TG := TG + AG (i)
  729. TB := TB + AB (i)
  730. end for
  731.  
  732. rcol (1) := TR / aalev
  733. rcol (2) := TG / aalev
  734. rcol (3) := TB / aalev
  735. result rcol
  736.  
  737. end msaa
  738.  
  739. var starttime : int := Time.Elapsed
  740. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  741. for x : 0 .. width - 1
  742. for y : 0 .. height - 1
  743. thisone := y * width + x
  744. %
  745. %
  746. if width > height then
  747. xamnt := ((x + 0.5) * w_a) - x_w
  748. yamnt := (h_y - y) / height
  749. elsif height > width then
  750. xamnt := (x + 0.5) / width
  751. yamnt := ((h_y - y) / h_a) - y_h
  752. else
  753. xamnt := (x + 0.5) / width
  754. yamnt := (h_y - y) / height
  755. end if
  756.  
  757. %cam_ray_direction := Vector.Normal (Vector.Add (Vector.Add (camDir, Vector.Mult (camRight, xamnt - 0.5)), Vector.Mult (camDown, yamnt - 0.5)))
  758. cam_ray_direction (1) := camDir (1) + camRight (1) * (xamnt - 0.5) + camDown (1) * (yamnt - 0.5)
  759. cam_ray_direction (2) := camDir (2) + camRight (2) * (xamnt - 0.5) + camDown (2) * (yamnt - 0.5)
  760. cam_ray_direction (3) := camDir (3) + camRight (3) * (xamnt - 0.5) + camDown (3) * (yamnt - 0.5)
  761. mag := sqrt (cam_ray_direction (1) * cam_ray_direction (1) + cam_ray_direction (2) * cam_ray_direction (2) + cam_ray_direction (3) * cam_ray_direction (3))
  762. cam_ray_direction (1) := cam_ray_direction (1) / mag
  763. cam_ray_direction (2) := cam_ray_direction (2) / mag
  764. cam_ray_direction (3) := cam_ray_direction (3) / mag
  765. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  766. for i : 1 .. objCount
  767. intersections (i) := object (i) -> findIntersection (camPos, cam_ray_direction)
  768. end for
  769. winningIndex := winningObjIndex (intersections)
  770. %
  771. if winningIndex = -1 then
  772. TR := 0
  773. TG := 0
  774. TB := 0
  775. else
  776. if intersections (winningIndex) > accuracy then
  777. %intersection_pos := Vector.Add (camPos, Vector.Mult (cam_ray_direction, intersections (winningIndex)))
  778. intersection_pos (1) := camPos (1) + cam_ray_direction (1) * intersections (winningIndex)
  779. intersection_pos (2) := camPos (2) + cam_ray_direction (2) * intersections (winningIndex)
  780. intersection_pos (3) := camPos (3) + cam_ray_direction (3) * intersections (winningIndex)
  781. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  782. intersection_colour := getColourAt (intersection_pos, cam_ray_direction, object, winningIndex, lights, accuracy, ambientlight)
  783. TR := intersection_colour (1)
  784. TG := intersection_colour (2)
  785. TB := intersection_colour (3)
  786. end if
  787. end if
  788. %
  789. if aadepth > 1 then
  790. if x > 0 and (abs (LR (x - 1, y) - TR) + abs (LR (x - 1, y) - TR) + abs (LR (x - 1, y) - TR) > 0.2) then
  791. gcol := msaa (x - 1, y)
  792. RGB.SetColour (255, gcol (1), gcol (2), gcol (3))
  793. drawdot (x - 1, y, 255)
  794. View.UpdateArea (x - 1, y, x - 1, y)
  795. end if
  796. if y > 0 and (abs (LR (x, y - 1) - TR) + abs (LR (x, y - 1) - TR) + abs (LR (x, y - 1) - TR) > 0.01) then
  797. gcol := msaa (x, y)
  798. TR := gcol (1)
  799. TR := gcol (1)
  800. TR := gcol (1)
  801. end if
  802. else
  803. end if
  804.  
  805. LR (x, y) := TR
  806. LG (x, y) := TG
  807. LB (x, y) := TB
  808.  
  809. RGB.SetColour (255, TR, TG, TB)
  810. drawdot (x, y, 255)
  811. end for
  812. View.UpdateArea (x, 0, x, maxy)
  813. end for
  814. %
  815. endtime := Time.Elapsed
  816. %var popup := Window.Open ("graphics:300;300,nobuttonbar")
  817. put (endtime - starttime) / 1000, " Seconds"
Advertisement
Add Comment
Please, Sign In to add comment