Advertisement
Guest User

Tree of Objects approach

a guest
May 4th, 2019
72
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Julia 7.02 KB | None | 0 0
  1. using Images, Colors, ImageView, LinearAlgebra, Gtk.ShortNames, StaticArrays, BenchmarkTools, ForwardDiff, FixedPointNumbers, Profile, StatProfilerHTML
  2.  
  3. function ray_source(x::Real,y::Real,Pos::SVector{3},Direction::SVector{3},
  4.         maxx::Int64,maxy::Int64,Sensorxv::SVector{3},Sensoryv::SVector{3})
  5.   (SVector{3}(Pos+(maxx/2-x)/maxx*Sensorxv+(maxy/2-y)/maxy*Sensoryv),SVector{3}(normalize(Direction)))
  6. end
  7.  
  8. const x = 800
  9. const y = 800
  10.  
  11. Picff  = Array{RGB{Normed{UInt8,8}}}(undef,x,y)
  12. PicTos = Array{RGB{Normed{UInt8,8}}}(undef,x,y)
  13. PicExp = Array{RGB{Normed{UInt8,8}}}(undef,x,y)
  14.  
  15. CamPosition = SVector{3}(-10.0,10.0,20.0)
  16. Normal = SVector{3}(10.0,-10.0,-20.0)
  17. SclX = 60.0
  18. SclY = 60.0
  19.  
  20. Ortho1 = SVector{3}(  0.0, -0.8944271909999159, 0.4472135954999579)
  21. Ortho2 = SVector{3}( 0.9128709291752769, 0.18257418583505536, 0.3651483716701107 )
  22.  
  23.  
  24. abstract type Shader end
  25. abstract type Sdf end
  26.  
  27. mutable struct RayInfo
  28.    Position::SVector{3,Float64}
  29.    Direction::SVector{3,Float64}
  30.    lSdf::Sdf
  31.    tSdf::Sdf
  32.    Step::Float64
  33.    Initial::SVector{3,Float64}
  34.    length::Float64
  35.    renderlim::Float64
  36. end
  37.  
  38. function gradient(Sdf::Sdf, Ri::RayInfo)
  39.   local Step = Ri.Step
  40.   normalize([(dist(Sdf,Ri.Position+SVector{3}(Step,0.0,0.0)) - dist(Sdf,Ri.Position))/Step,
  41.              (dist(Sdf,Ri.Position+SVector{3}(0.0,Step,0.0)) - dist(Sdf,Ri.Position))/Step,
  42.              (dist(Sdf,Ri.Position+SVector{3}(0.0,0.0,Step)) - dist(Sdf,Ri.Position))/Step])
  43. end
  44.  
  45. struct ConstantShader <: Shader
  46.   Color::RGB
  47. end
  48.  
  49. function shade(Shadr::ConstantShader,Ri::RayInfo)
  50.   Shadr.Color
  51. end
  52.  
  53.  
  54. struct Checkbox <: Shader
  55.   BoxSize::Float64
  56.   Shd1::Shader
  57.   Shd2::Shader
  58. end
  59.  
  60. function shade(Shadr::Checkbox,Ri::RayInfo)
  61.   x,y,z = Ri.Position
  62.   Bs = Shadr.BoxSize
  63.   if xor(mod(x,2*Bs)>Bs,mod(y,2*Bs)>Bs,mod(z,2*Bs)>Bs)
  64.     shade(Shadr.Shd1,Ri)
  65.   else
  66.     shade(Shadr.Shd2,Ri)
  67.   end
  68. end
  69.  
  70. struct Spot <: Shader
  71.   lightPos::SVector{3,Float64}
  72.   brightness::Float64
  73.   Shd1::Shader
  74. end
  75.  
  76. function shade(Shadr::Spot,Ri::RayInfo)
  77.   shade(Shadr.Shd1,Ri)*min(1,max(0.1,Shadr.brightness*dot(gradient(Ri.tSdf,Ri),normalize(Shadr.lightPos-Ri.Position))))
  78. end
  79.  
  80.  
  81.  
  82. struct Conjun <: Sdf
  83.   Coll::Array{Sdf, 1}
  84. end
  85.  
  86. function dist(Sdf::Conjun, Position::SVector{3,Float64})
  87.   min(map(x->dist(x,Position),Sdf.Coll)...)
  88. end
  89.  
  90. function closest(Sdf::Conjun, Position::SVector{3,Float64})
  91.   closest(Sdf.Coll[argmin(map(x->dist(x,Position),Sdf.Coll))],Position)
  92. end
  93.  
  94. struct Transl <: Sdf
  95.   Off::SVector{3,Float64}
  96.   Vict::Sdf
  97. end
  98.  
  99. function dist(Sdf::Transl, Position::SVector{3,Float64})
  100.   dist(Sdf.Vict,Position-Sdf.Off)
  101. end
  102.  
  103. function closest(Sdf::Transl, Position::SVector{3,Float64})
  104.   closest(Sdf.Vict,Position-Sdf.Off)
  105. end
  106.  
  107.  
  108.  
  109. abstract type SSdf <: Sdf end
  110.  
  111. ## Everything that is Subtype of SSdf must provide color
  112.  
  113. function closest(Sdf::SSdf,Position::SVector{3,Float64})
  114.   Sdf
  115. end
  116.  
  117.  
  118. struct Sphere <: SSdf
  119.    Radius::Float64
  120.    Shadr::Shader
  121. end
  122.  
  123. function dist(Sph::Sphere, Position::SVector{3,Float64})
  124.    norm(Position)-Sph.Radius
  125. end
  126.  
  127. function color(Sph::Sphere, Ri::RayInfo)
  128.   shade(Sph.Shadr,Ri)
  129. end
  130.  
  131.  
  132. struct Plane <: SSdf
  133.    Normal::SVector{3,Float64} ##Check for normality
  134.    Shadr::Shader
  135. end
  136.  
  137. function dist(Pln::Plane, Position::SVector{3,Float64})
  138.    norm(dot(Position,Pln.Normal))
  139. end
  140.  
  141. function color(Pln::Plane, Ri::RayInfo)
  142.   shade(Pln.Shadr,Ri)
  143. end
  144.  
  145. struct IsometricCamera
  146.   Position::SVector{3,Float64}
  147.   Direction::SVector{3,Float64}
  148.   Sensorx::SVector{3,Float64}
  149.   Sensory::SVector{3,Float64}
  150.   Maxx::Float64
  151.   Maxy::Float64
  152.   function IsometricCamera(Position::SVector{3,Float64}, Direction::SVector{3,Float64}, Sensorx::SVector{3,Float64}, Sensory::SVector{3,Float64}, Maxx::Int64, Maxy::Int64)
  153.     new(Position, normalize(Direction), Sensorx/Maxx, Sensory/Maxy, Maxx/2.0, Maxy/2.0)
  154.   end
  155. end
  156.  
  157. function los(Cam::IsometricCamera,X::Int64,Y::Int64)::Tuple{SVector{3,Float64},SVector{3,Float64}}
  158.   ((X-Cam.Maxx)*Cam.Sensorx+(Y-Cam.Maxy)*Cam.Sensory+Cam.Position,Cam.Direction)
  159. end
  160.  
  161.  
  162. isocam = IsometricCamera(SVector{3,Float64}(45.0,45.0,45.0),SVector{3,Float64}(-1.0,-1.0,-1.0),45*normalize(SVector{3,Float64}(0.0,1.0,-1.0)),45*normalize(SVector{3,Float64}(1.0,-1.0,-1.0)),x,y)
  163.  
  164.  
  165.  
  166. const Red   = ConstantShader(RGB{Normed{UInt8,8}}(1,0,0))
  167. const Green = ConstantShader(RGB{Normed{UInt8,8}}(0,1,0))
  168. const Blue  = ConstantShader(RGB{Normed{UInt8,8}}(0,0,1))
  169. const Gelb  = ConstantShader(RGB{Normed{UInt8,8}}(1,1,0))
  170. const Black = ConstantShader(RGB{Normed{UInt8,8}}(0,0,0))
  171. const White = ConstantShader(RGB{Normed{UInt8,8}}(1,1,1))
  172. const Grey = ConstantShader(RGB{Normed{UInt8,8}}(0.5,0.5,0.5))
  173.  
  174. function scene_ff(Pos)  
  175.    union(trans(sphere(3.0,spot(SVector{3,Float64}(0,0,0),1.5,Red)),SVector{3,Float64}(0,20,0)),
  176.          trans(sphere(12.0,spot(SVector{3,Float64}(0,0,0),1.8,Blue)),SVector{3,Float64}(12,9,-4)),
  177.          trans(sphere(9.0,spot(SVector{3,Float64}(0,0,0),1.0,Green)),SVector{3,Float64}(3,-13,0)),
  178.          sphere(1.0,White),
  179.          trans(sphere(0.5,White),SVector{3,Float64}(-20,0,0)),
  180.          trans(sphere(1.0,Red),SVector{3,Float64}(-18,0,0)),
  181.          plane(SVector{3,Float64}(0.0,0.0,1.0),checkerbox(10,Grey,Black)))(Pos)
  182. end
  183.  
  184. const scene = Conjun([
  185.    Transl(SVector{3,Float64}(0,20,0),Sphere(3.0,Spot(SVector{3,Float64}(0,0,0),1.5,Red))),
  186.    Transl(SVector{3,Float64}(12,9,-4),Sphere(12.0,Spot(SVector{3,Float64}(0,0,0),1.8,Blue))),
  187.    Transl(SVector{3,Float64}(3,-13,0),Sphere(9.0,Spot(SVector{3,Float64}(0,0,0),1.0,Green))),
  188.    Sphere(1.0,White),
  189.    Transl(SVector{3,Float64}(-20,0,0),Sphere(0.5,White)),
  190.    Transl(SVector{3,Float64}(-18,0,0),Sphere(1.0,Red)),
  191.    Plane(SVector(0.0,0.0,1.0),Checkbox(10,Grey,Black))
  192. ])
  193.  
  194.  
  195. function raymarch(Pos::SVector{3,Float64},Normal::SVector{3,Float64},Sdf::Sdf,Fb::Shader,renderlim::Float64)
  196. stepsize=1.0;
  197. Start=Pos;
  198. Strecke=0.0;
  199.  while (stepsize > 0.001)
  200.    stepsize=dist(scene,Pos);
  201.    Pos+=Normal*stepsize;
  202.    Strecke+=stepsize
  203.    if Strecke > renderlim
  204.      c = closest(Sdf,Pos)
  205.      return shade(Fb,RayInfo(Pos,Normal,c,Sdf,stepsize,Start,Strecke,renderlim-Strecke))
  206.    end
  207.  end
  208.    c = closest(Sdf,Pos)
  209.    color(c,RayInfo(Pos,Normal,c,Sdf,stepsize,Start,Strecke,renderlim-Strecke))
  210. end
  211.  
  212. @btime for h=-10.0:0.5:10.0
  213.   for i=-10.0:0.5:10.0
  214.     for j=-10.0:0.5:10.0
  215.       dist(scene,SVector{3,Float64}(h,i,j))
  216.     end
  217.   end
  218. end
  219. ##      65.579 ms (2136551 allocations: 52.58 MiB)
  220.  
  221. for i=1:x
  222.   for j=1:y
  223.      lpos, lnormal = ray_source(Float64(i),Float64(j),CamPosition,Normal,x,y,SclX * Ortho1,SclY * Ortho2)
  224.      @profile PicTos[i,j]=raymarch(lpos,lnormal,scene,Black,500.0)
  225.   end
  226. end
  227. ##     6.605 s (195129663 allocations: 4.84 GiB)
  228.  
  229. statprofilehtml()
  230. guidict = imshow(PicTos);
  231.  
  232. if (!isinteractive())
  233.  
  234.     # Create a condition object
  235.     c = Condition()
  236.  
  237.     # Get the window
  238.     win = guidict["gui"]["window"]
  239.  
  240.     # Notify the condition object when the window closes
  241.     signal_connect(win, :destroy) do widget
  242.         notify(c)
  243.     end
  244.  
  245.     # Wait for the notification before proceeding ...
  246.     wait(c)
  247. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement