1//: Backproject and project functions, using float16 for cameras
2
3float4 backproject(unsigned i,unsigned j,float16 Ut,float16 V,float16 w, float4 origin)
4{
5  float4 inputpoint=(float4)((float)i+0.5f,(float)j+0.5f,1.0f,0.0f);
6
7  float4 X=(float4)(dot((float4)(Ut.s0123),inputpoint),
8                    dot((float4)(Ut.s4567),inputpoint),
9                    dot((float4)(Ut.s89ab),inputpoint),
10                    dot((float4)(Ut.scdef),inputpoint));
11
12  X=X*(float4)(w.s0123);
13
14  X=(float4)(dot((float4)(V.s0123),X),
15             dot((float4)(V.s4567),X),
16             dot((float4)(V.s89ab),X),
17             dot((float4)(V.scdef),X));
18
19
20  X=normalize(X-(float4)(origin.xyzw)*X.w);
21
22  return X;
23}
24
25float4 backproject_corner(float i, float j,float16 Ut,float16 V,float16 w, float4 origin)
26{
27  float4 inputpoint=(float4)(i,j,1.0f,0.0f);
28
29  float4 X=(float4)(dot((float4)(Ut.s0123),inputpoint),
30                    dot((float4)(Ut.s4567),inputpoint),
31                    dot((float4)(Ut.s89ab),inputpoint),
32                    dot((float4)(Ut.scdef),inputpoint));
33
34  X=X*(float4)(w.s0123);
35
36  X=(float4)(dot((float4)(V.s0123),X),
37             dot((float4)(V.s4567),X),
38             dot((float4)(V.s89ab),X),
39             dot((float4)(V.scdef),X));
40
41  X= X / X.w;
42
43  X=normalize(X-(float4)(origin.xyzw));
44
45  return X;
46}
47
48
49bool project(__global float16 * cam, float4 p3d, float2 * p2d)
50{
51    p3d.w=1;
52    float u = dot((float4)((*cam).s0123),p3d);
53    float v = dot((float4)((*cam).s4567),p3d);
54
55    float denom=dot((float4)((*cam).s89ab),p3d);
56
57    if (denom==0.0f)
58        return false;
59    (*p2d)=(float2)(u/denom,v/denom);
60    return true;
61}
62
63//utility method that uses backproject to output a single ray (6 floats) from a global cam
64//uses perspective camera
65bool calc_scene_ray(__constant RenderSceneInfo * linfo,
66                    __global float16 * camera,
67                    int i, int j,
68                    float* ray_ox, float* ray_oy, float* ray_oz,
69                    float* ray_dx, float* ray_dy, float* ray_dz)
70{
71
72  float4 ray_o = (float4) camera[2].s4567; ray_o.w = 1.0f;
73  float4 ray_d = backproject(i, j, camera[0], camera[1], camera[2], ray_o);
74  ray_o = ray_o - linfo->origin; ray_o.w = 1.0f; //translate ray o to zero out scene origin
75  ray_o = ray_o/linfo->block_len; ray_o.w = 1.0f;
76
77  //thresh ray direction components - too small a treshhold causes axis aligned
78  //viewpoints to hang in infinite loop (block loop)
79  float thresh = exp2(-12.0f);
80  if (fabs(ray_d.x) < thresh) ray_d.x = copysign(thresh, ray_d.x);
81  if (fabs(ray_d.y) < thresh) ray_d.y = copysign(thresh, ray_d.y);
82  if (fabs(ray_d.z) < thresh) ray_d.z = copysign(thresh, ray_d.z);
83  ray_d.w = 0.0f; ray_d = normalize(ray_d);
84
85  //store float 3's
86  *ray_ox = ray_o.x;     *ray_oy = ray_o.y;     *ray_oz = ray_o.z;
87  *ray_dx = ray_d.x;     *ray_dy = ray_d.y;     *ray_dz = ray_d.z;
88
89  return true;
90}
91
92
93bool calc_scene_ray_generic_cam(__constant RenderSceneInfo * linfo,
94                                float4 ray_o, float4 ray_d,
95                                float* ray_ox, float* ray_oy, float* ray_oz,
96                                float* ray_dx, float* ray_dy, float* ray_dz)
97{
98  //make sure w is one
99  ray_o = ray_o - linfo->origin; ray_o.w = 1.0f; //translate ray o to zero out scene origin
100  ray_o = ray_o/linfo->block_len; ray_o.w = 1.0f;
101
102  //thresh ray direction components - too small a treshhold causes axis aligned
103  //viewpoints to hang in infinite loop (block loop)
104  float thresh = exp2(-12.0f);
105  if (fabs(ray_d.x) < thresh) ray_d.x = copysign(thresh, ray_d.x);
106  if (fabs(ray_d.y) < thresh) ray_d.y = copysign(thresh, ray_d.y);
107  if (fabs(ray_d.z) < thresh) ray_d.z = copysign(thresh, ray_d.z);
108  ray_d.w = 0.0f; ray_d = normalize(ray_d);
109
110  //store float 3's
111  *ray_ox = ray_o.x;     *ray_oy = ray_o.y;     *ray_oz = ray_o.z;
112  *ray_dx = ray_d.x;     *ray_dy = ray_d.y;     *ray_dz = ray_d.z;
113
114  return true;
115}
116