Added a bunch of additional particle state attributes to the Cycles particle info...
[blender.git] / intern / cycles / kernel / kernel_object.h
1 /*
2  * Copyright 2011, Blender Foundation.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  */
18
19 CCL_NAMESPACE_BEGIN
20
21 enum ObjectTransform {
22         OBJECT_TRANSFORM = 0,
23         OBJECT_INVERSE_TRANSFORM = 3,
24         OBJECT_PROPERTIES = 6,
25         OBJECT_TRANSFORM_MOTION_PRE = 8,
26         OBJECT_TRANSFORM_MOTION_POST = 12
27 };
28
29 __device_inline Transform object_fetch_transform(KernelGlobals *kg, int object, float time, enum ObjectTransform type)
30 {
31         Transform tfm;
32
33 #ifdef __MOTION__
34         /* if we do motion blur */
35         if(sd->flag & SD_OBJECT_MOTION) {
36                 /* fetch motion transforms */
37                 MotionTransform motion;
38
39                 motion.pre.x = have_motion;
40                 motion.pre.y = kernel_tex_fetch(__objects, offset + 1);
41                 motion.pre.z = kernel_tex_fetch(__objects, offset + 2);
42                 motion.pre.w = kernel_tex_fetch(__objects, offset + 3);
43
44                 motion.post.x = kernel_tex_fetch(__objects, offset + 4);
45                 motion.post.y = kernel_tex_fetch(__objects, offset + 5);
46                 motion.post.z = kernel_tex_fetch(__objects, offset + 6);
47                 motion.post.w = kernel_tex_fetch(__objects, offset + 7);
48
49                 /* interpolate (todo: do only once per object) */
50                 transform_motion_interpolate(&tfm, &motion, time);
51
52                 /* invert */
53                 if(type == OBJECT_INVERSE_TRANSFORM)
54                         tfm = transform_quick_inverse(tfm);
55
56                 return tfm;
57         }
58 #endif
59
60         int offset = object*OBJECT_SIZE + (int)type;
61
62         tfm.x = kernel_tex_fetch(__objects, offset + 0);
63         tfm.y = kernel_tex_fetch(__objects, offset + 1);
64         tfm.z = kernel_tex_fetch(__objects, offset + 2);
65         tfm.w = make_float4(0.0f, 0.0f, 0.0f, 1.0f);
66
67         return tfm;
68 }
69
70 __device_inline void object_position_transform(KernelGlobals *kg, ShaderData *sd, float3 *P)
71 {
72 #ifdef __MOTION__
73         *P = transform_point(&sd->ob_tfm, *P);
74 #else
75         Transform tfm = object_fetch_transform(kg, sd->object, TIME_INVALID, OBJECT_TRANSFORM);
76         *P = transform_point(&tfm, *P);
77 #endif
78 }
79
80 __device_inline void object_inverse_position_transform(KernelGlobals *kg, ShaderData *sd, float3 *P)
81 {
82 #ifdef __MOTION__
83         *P = transform_point(&sd->ob_itfm, *P);
84 #else
85         Transform tfm = object_fetch_transform(kg, sd->object, TIME_INVALID, OBJECT_INVERSE_TRANSFORM);
86         *P = transform_point(&tfm, *P);
87 #endif
88 }
89
90 __device_inline void object_inverse_normal_transform(KernelGlobals *kg, ShaderData *sd, float3 *N)
91 {
92 #ifdef __MOTION__
93         *N = normalize(transform_direction_transposed(&sd->ob_tfm, *N));
94 #else
95         Transform tfm = object_fetch_transform(kg, sd->object, TIME_INVALID, OBJECT_TRANSFORM);
96         *N = normalize(transform_direction_transposed(&tfm, *N));
97 #endif
98 }
99
100 __device_inline void object_normal_transform(KernelGlobals *kg, ShaderData *sd, float3 *N)
101 {
102 #ifdef __MOTION__
103         *N = normalize(transform_direction_transposed(&sd->ob_itfm, *N));
104 #else
105         Transform tfm = object_fetch_transform(kg, sd->object, TIME_INVALID, OBJECT_INVERSE_TRANSFORM);
106         *N = normalize(transform_direction_transposed(&tfm, *N));
107 #endif
108 }
109
110 __device_inline void object_dir_transform(KernelGlobals *kg, ShaderData *sd, float3 *D)
111 {
112 #ifdef __MOTION__
113         *D = transform_direction(&sd->ob_tfm, *D);
114 #else
115         Transform tfm = object_fetch_transform(kg, sd->object, 0.0f, OBJECT_TRANSFORM);
116         *D = transform_direction(&tfm, *D);
117 #endif
118 }
119
120 __device_inline float3 object_location(KernelGlobals *kg, ShaderData *sd)
121 {
122 #ifdef __MOTION__
123         return make_float3(sd->ob_tfm.x.w, sd->ob_tfm.y.w, sd->ob_tfm.z.w);
124 #else
125         Transform tfm = object_fetch_transform(kg, sd->object, 0.0f, OBJECT_TRANSFORM);
126         return make_float3(tfm.x.w, tfm.y.w, tfm.z.w);
127 #endif
128 }
129
130 __device_inline float object_surface_area(KernelGlobals *kg, int object)
131 {
132         int offset = object*OBJECT_SIZE + OBJECT_PROPERTIES;
133         float4 f = kernel_tex_fetch(__objects, offset);
134         return f.x;
135 }
136
137 __device_inline float object_pass_id(KernelGlobals *kg, int object)
138 {
139         if(object == ~0)
140                 return 0.0f;
141
142         int offset = object*OBJECT_SIZE + OBJECT_PROPERTIES;
143         float4 f = kernel_tex_fetch(__objects, offset);
144         return f.y;
145 }
146
147 __device_inline float object_random_number(KernelGlobals *kg, int object)
148 {
149         if(object == ~0)
150                 return 0.0f;
151
152         int offset = object*OBJECT_SIZE + OBJECT_PROPERTIES;
153         float4 f = kernel_tex_fetch(__objects, offset);
154         return f.z;
155 }
156
157 __device_inline uint object_particle_id(KernelGlobals *kg, int object)
158 {
159         if(object == ~0)
160                 return 0.0f;
161
162         int offset = object*OBJECT_SIZE + OBJECT_PROPERTIES;
163         float4 f = kernel_tex_fetch(__objects, offset);
164         return __float_as_int(f.w);
165 }
166
167 __device int shader_pass_id(KernelGlobals *kg, ShaderData *sd)
168 {
169         return kernel_tex_fetch(__shader_flag, (sd->shader & SHADER_MASK)*2 + 1);
170 }
171
172 __device_inline float particle_index(KernelGlobals *kg, int particle)
173 {
174         int offset = particle*PARTICLE_SIZE;
175         float4 f = kernel_tex_fetch(__particles, offset + 0);
176         return f.x;
177 }
178
179 __device float particle_age(KernelGlobals *kg, int particle)
180 {
181         int offset = particle*PARTICLE_SIZE;
182         float4 f = kernel_tex_fetch(__particles, offset + 0);
183         return f.y;
184 }
185
186 __device float particle_lifetime(KernelGlobals *kg, int particle)
187 {
188         int offset = particle*PARTICLE_SIZE;
189         float4 f = kernel_tex_fetch(__particles, offset + 0);
190         return f.z;
191 }
192
193 __device float particle_size(KernelGlobals *kg, int particle)
194 {
195         int offset = particle*PARTICLE_SIZE;
196         float4 f = kernel_tex_fetch(__particles, offset + 0);
197         return f.w;
198 }
199
200 __device float4 particle_rotation(KernelGlobals *kg, int particle)
201 {
202         int offset = particle*PARTICLE_SIZE;
203         float4 f = kernel_tex_fetch(__particles, offset + 1);
204         return f;
205 }
206
207 __device float3 particle_location(KernelGlobals *kg, int particle)
208 {
209         int offset = particle*PARTICLE_SIZE;
210         float4 f = kernel_tex_fetch(__particles, offset + 2);
211         return make_float3(f.x, f.y, f.z);
212 }
213
214 __device float3 particle_velocity(KernelGlobals *kg, int particle)
215 {
216         int offset = particle*PARTICLE_SIZE;
217         float4 f2 = kernel_tex_fetch(__particles, offset + 2);
218         float4 f3 = kernel_tex_fetch(__particles, offset + 3);
219         return make_float3(f2.w, f3.x, f3.y);
220 }
221
222 __device float3 particle_angular_velocity(KernelGlobals *kg, int particle)
223 {
224         int offset = particle*PARTICLE_SIZE;
225         float4 f3 = kernel_tex_fetch(__particles, offset + 3);
226         float4 f4 = kernel_tex_fetch(__particles, offset + 4);
227         return make_float3(f3.z, f3.w, f4.x);
228 }
229
230
231 CCL_NAMESPACE_END
232