diff options
Diffstat (limited to 'lib/compiler/test/inline_SUITE_data/itracer.erl')
-rw-r--r-- | lib/compiler/test/inline_SUITE_data/itracer.erl | 407 |
1 files changed, 407 insertions, 0 deletions
diff --git a/lib/compiler/test/inline_SUITE_data/itracer.erl b/lib/compiler/test/inline_SUITE_data/itracer.erl new file mode 100644 index 0000000000..93f24e9bb1 --- /dev/null +++ b/lib/compiler/test/inline_SUITE_data/itracer.erl @@ -0,0 +1,407 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2000-2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +-module(itracer). +-export([itracer/0]). + +%%%--------------------------------------------------------------------------- +%%% +%%% This is a little raytracer. +%%% +%%%--------------------------------------------------------------------------- + + +%%---------------------------------------------------------------------------- +%% Constructors. +%%---------------------------------------------------------------------------- + + +%%---------------------------------------------------------------------------- +%% +%%---------------------------------------------------------------------------- + +itracer() -> + C1 = ccreate(), + C2 = set_width(C1,100), + C3 = set_height(C2,100), + C4 = initialize(C3), + Sphere1 = screate(40,vcreate(35,10,0),{1,0,0}), + Sphere2 = screate(35,vcreate(-25,-25,50),{0,1,0}), + PL = traceloop(C4,50,50,[Sphere1,Sphere2]). + + +%%---------------------------------------------------------------------------- +%% +%%---------------------------------------------------------------------------- + +overflow_prevent(A) when A<1 -> A; +overflow_prevent(_) -> 1. + + +%%---------------------------------------------------------------------------- +%% +%%---------------------------------------------------------------------------- + +traceloop(Camera,Width,Height,Scene) -> + traceloop(Camera,Width,Height,0,0,Scene,[]). + + +traceloop(_,_,Height,_,Y,_,PL) when Height=<Y -> + PL; + +traceloop(Camera,Width,Height,X,Y,Scene,PL) when Width=<X -> + traceloop(Camera,Width,Height,0,Y+1,Scene,PL); + +traceloop(Camera,Width,Height,X,Y,Scene,PL) -> + Ray = ray(Camera,X/Width,Y/Height), + {R1,G1,B1} = traceray(Ray,Scene,1), + R2 = overflow_prevent(R1), + G2 = overflow_prevent(G1), + B2 = overflow_prevent(B1), + P = {trunc(R2*255), trunc(G2*255), trunc(B2*255)}, + traceloop(Camera,Width,Height,X+1,Y,Scene,[{X,Y,P}|PL]). + + +%%---------------------------------------------------------------------------- +%% +%%---------------------------------------------------------------------------- + +traceray(Ray,Scene,Level) -> + Hit = findintersection(Ray,Scene,Level), + case Hit of + nohit -> {0,0,0}; + {[T|Ts],Object} -> shaderay(Ray,Scene,Level,T,Object) + end. + + +%%---------------------------------------------------------------------------- +%% +%%---------------------------------------------------------------------------- + +% Here we loop through all the objects in the scene to find the +% closest intersection. + +findintersection(_,[],_) -> nohit; + +findintersection(Ray,[Object|Objects],Level) -> + Ts = intersection(Object,Ray), + Hit1 = findintersection(Ray,Objects,Level), + Hit2 = closesthit(Ts,Object,Hit1). + + +closesthit(nohit,_,nohit) -> nohit; +closesthit(nohit,_,{[T|Ts],Obj}) when T>0 -> {[T|Ts],Obj}; +closesthit(nohit,_,_) -> nohit; +closesthit([T|Ts],Obj,nohit) when T>0 -> {[T|Ts],Obj}; +closesthit(_,_,nohit) -> nohit; +closesthit([T1|Ts1],Obj1,{[T2|Ts2],Obj2}) when T1>0,T1<T2 -> {[T1|Ts1],Obj1}; +closesthit([T1|Ts1],Obj1,{[T2|Ts2],Obj2}) when T2>0,T2<T1 -> {[T2|Ts2],Obj2}; +closesthit(_,_,_) -> nohit. + + + +%%---------------------------------------------------------------------------- +%% +%%---------------------------------------------------------------------------- + +shaderay(Ray,Scene,Level,T,Object) -> + Direction = get_direction(Ray), + Origin = get_origin(Ray), + Point = add(Origin, mul(T, Direction)), + Normal = calcnormal(Object, Point), + Diffuse = -dot(Normal, Direction), + ReflectionVector = reflection(Ray,Normal), + NewOrigin = add(Point, mul(0.0001, Normal)), + ReflectionRay = rcreate(NewOrigin,ReflectionVector), + {Red1,Green1,Blue1} = get_color(Object), + if + Level<4, Diffuse>0 -> + {Red2,Green2,Blue2} = traceray(ReflectionRay,Scene,Level+1), + {Diffuse*Red1 + 0.5*Red2, + Diffuse*Green1 + 0.5*Green2, + Diffuse*Blue1 + 0.5*Blue2}; + Level<4, Diffuse<0 -> + {0,0,0}; + true -> + {0,0,0} + end. + + +%%---------------------------------------------------------------------------- +%% Har nedan foljer bara ett gang testfunktioner.... +%%---------------------------------------------------------------------------- +-record(camera,{width,height,zoom,position,lookat,up,right,down,corner}). + +%%%--------------------------------------------------------------------------- +%%% +%%% Useful camera operations. +%%% +%%%--------------------------------------------------------------------------- + + +%%---------------------------------------------------------------------------- +%% Constructors. +%%---------------------------------------------------------------------------- + +ccreate() -> + #camera{width=100, height=100, zoom=256, + position = vcreate(0,0,-256), + lookat = vcreate(0,0,0), + up = vcreate(0,1,0)}. + + + +%%---------------------------------------------------------------------------- +%% Selectors and modifiers. +%%---------------------------------------------------------------------------- + +set_width(C,Width) -> C#camera{width=Width}. +set_height(C,Height) -> C#camera{height=Height}. +set_zoom(C,Zoom) -> C#camera{zoom=Zoom}. +cset_position(C,Pos) -> C#camera{position=Pos}. +set_lookat(C,Lookat) -> C#camera{lookat=Lookat}. +set_up(C,Up) -> C#camera{up=Up}. + +get_width(C) -> C#camera.width. +get_height(C) -> C#camera.height. +get_zoom(C) -> C#camera.zoom. +cget_position(C) -> C#camera.position. +get_lookat(C) -> C#camera.lookat. +get_up(C) -> C#camera.up. + + + +%%---------------------------------------------------------------------------- +%% Operators. +%%---------------------------------------------------------------------------- + +initialize(C) -> + Dir = normalize(sub(C#camera.lookat, C#camera.position)), + Up1 = normalize(C#camera.up), + D = dot(Up1, Dir), + Up2 = normalize(sub(Up1, mul(D, Dir))), + Down = mul(-1, Up2), + Right = normalize(cross(Up2,Dir)), + Corner1 = mul(C#camera.zoom, Dir), + Corner2 = add(Corner1, mul(-C#camera.width/2, Right)), + Corner3 = add(Corner2, mul(-C#camera.height/2, Down)), + C2 = C#camera{down=Down, right=Right, corner=Corner3}. + + +% +% X och Y ska ligga i intervallet [0..1] +% +ray(C,X,Y) -> + Right = mul(C#camera.width*X, C#camera.right), + Down = mul(C#camera.height*Y, C#camera.down), + Point = add(C#camera.corner, add(Right,Down)), + rcreate(C#camera.position,normalize(Point)). + + + +%%---------------------------------------------------------------------------- +%% E N D O F F I L E +%%---------------------------------------------------------------------------- +-record(vector,{x,y,z}). + + +%%%--------------------------------------------------------------------------- +%%% +%%% Useful vector operations. +%%% +%%%--------------------------------------------------------------------------- + + +%%---------------------------------------------------------------------------- +%% Constructors. +%%---------------------------------------------------------------------------- + +vcreate() -> + #vector{x=0,y=0,z=0}. + + +vcreate(X,Y,Z) -> + #vector{x=X,y=Y,z=Z}. + + + +%%---------------------------------------------------------------------------- +%% Selectors and modifiers. +%%---------------------------------------------------------------------------- + +set_x(V,X) -> V#vector{x=X}. +set_y(V,Y) -> V#vector{y=Y}. +set_z(V,Z) -> V#vector{z=Z}. + +get_x(V) -> V#vector.x. +get_y(V) -> V#vector.y. +get_z(V) -> V#vector.z. + + + +%%---------------------------------------------------------------------------- +%% Operators. +%%---------------------------------------------------------------------------- + +add(A,B) -> + #vector{x=A#vector.x+B#vector.x, + y=A#vector.y+B#vector.y, + z=A#vector.z+B#vector.z}. + + +sub(A,B) -> + #vector{x=A#vector.x-B#vector.x, + y=A#vector.y-B#vector.y, + z=A#vector.z-B#vector.z}. + + +mul(T,A) -> + #vector{x=A#vector.x * T, + y=A#vector.y * T, + z=A#vector.z * T}. + + +dot(A,B) -> + A#vector.x*B#vector.x + + A#vector.y*B#vector.y + + A#vector.z*B#vector.z. + + +normalize(A) -> + S = 1 / math:sqrt(dot(A,A)), + vcreate(A#vector.x * S, A#vector.y * S, A#vector.z * S). + + +cross(A,B) -> + #vector{x = A#vector.y*B#vector.z - A#vector.z*B#vector.y, + y = A#vector.z*B#vector.x - A#vector.x*B#vector.z, + z = A#vector.x*B#vector.y - A#vector.y*B#vector.x}. + + +%%---------------------------------------------------------------------------- +%% E N D O F F I L E +%%---------------------------------------------------------------------------- +-record(ray,{origin,direction}). + +%%%--------------------------------------------------------------------------- +%%% +%%% Useful ray stuff. +%%% +%%%--------------------------------------------------------------------------- + + +%%---------------------------------------------------------------------------- +%% Constructors. +%%---------------------------------------------------------------------------- + +rcreate() -> + #ray{origin=vcreate(0,0,0), direction=vcreate(0,0,1)}. + + +rcreate(Origin,Direction) -> + #ray{origin=Origin, direction=Direction}. + + + +%%---------------------------------------------------------------------------- +%% Selectors and modifiers. +%%---------------------------------------------------------------------------- + +set_origin(R,Origin) -> R#ray{origin=Origin}. +set_direction(R,Direction) -> R#ray{direction=Direction}. + +get_origin(R) -> R#ray.origin. +get_direction(R) -> R#ray.direction. + + + +%%---------------------------------------------------------------------------- +%% +%%---------------------------------------------------------------------------- + +reflection(R,N) -> + A = mul(2*dot(N, R#ray.direction), N), + normalize(sub(R#ray.direction, A)). + + + +%%---------------------------------------------------------------------------- +%% E N D O F F I L E +%%---------------------------------------------------------------------------- +-record(sphere,{radius,position,color}). + +%%%--------------------------------------------------------------------------- +%%% +%%% Useful sphere operations. +%%% +%%%--------------------------------------------------------------------------- + + +%%---------------------------------------------------------------------------- +%% Constructors. +%%---------------------------------------------------------------------------- + +screate() -> + #sphere{radius=1, position=vcreate(0,0,0), color={1,1,1}}. + + +screate(Radius,Position,Color) -> + #sphere{radius=Radius, position=Position, color=Color}. + + + +%%---------------------------------------------------------------------------- +%% Selectors and modifiers. +%%---------------------------------------------------------------------------- + +set_radius(S,Radius) -> S#sphere{radius=Radius}. +sset_position(S,Position) -> S#sphere{position=Position}. +set_color(S,Color) -> S#sphere{color=Color}. + +get_radius(S) -> S#sphere.radius. +sget_position(S) -> S#sphere.position. +get_color(S) -> S#sphere.color. + + + +%%---------------------------------------------------------------------------- +%% Calculates the intersection between a ray and the sphere. +%%---------------------------------------------------------------------------- + +intersection(S,Ray) -> + SR = sub(S#sphere.position,get_origin(Ray)), + B = dot(SR,get_direction(Ray)), + C = dot(SR,SR), + Root = B*B-C + S#sphere.radius * S#sphere.radius, + if + Root>0 -> + SquareRoot = math:sqrt(Root), + [B-SquareRoot,B+SquareRoot]; + true -> + nohit + end. + +calcnormal(S,P) -> + normalize(sub(P, S#sphere.position)). + %mul(1/S#sphere.radius, sub(P, S#sphere.position)). + + + +%%---------------------------------------------------------------------------- +%% E N D O F F I L E +%%---------------------------------------------------------------------------- |