Cycles Hair: refactoring to support generic attributes for hair curves. There
[blender.git] / intern / cycles / kernel / svm / svm_geometry.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 /* Geometry Node */
22
23 __device void svm_node_geometry(KernelGlobals *kg, ShaderData *sd, float *stack, uint type, uint out_offset)
24 {
25         float3 data;
26
27         switch(type) {
28                 case NODE_GEOM_P: data = sd->P; break;
29                 case NODE_GEOM_N: data = sd->N; break;
30 #ifdef __DPDU__
31                 case NODE_GEOM_T: data = primitive_tangent(kg, sd); break;
32 #endif
33                 case NODE_GEOM_I: data = sd->I; break;
34                 case NODE_GEOM_Ng: data = sd->Ng; break;
35 #ifdef __UV__
36                 case NODE_GEOM_uv: data = make_float3(sd->u, sd->v, 0.0f); break;
37 #endif
38         }
39
40         stack_store_float3(stack, out_offset, data);
41 }
42
43 __device void svm_node_geometry_bump_dx(KernelGlobals *kg, ShaderData *sd, float *stack, uint type, uint out_offset)
44 {
45 #ifdef __RAY_DIFFERENTIALS__
46         float3 data;
47
48         switch(type) {
49                 case NODE_GEOM_P: data = sd->P + sd->dP.dx; break;
50                 case NODE_GEOM_uv: data = make_float3(sd->u + sd->du.dx, sd->v + sd->dv.dx, 0.0f); break;
51                 default: svm_node_geometry(kg, sd, stack, type, out_offset); return;
52         }
53
54         stack_store_float3(stack, out_offset, data);
55 #else
56         svm_node_geometry(kg, sd, stack, type, out_offset);
57 #endif
58 }
59
60 __device void svm_node_geometry_bump_dy(KernelGlobals *kg, ShaderData *sd, float *stack, uint type, uint out_offset)
61 {
62 #ifdef __RAY_DIFFERENTIALS__
63         float3 data;
64
65         switch(type) {
66                 case NODE_GEOM_P: data = sd->P + sd->dP.dy; break;
67                 case NODE_GEOM_uv: data = make_float3(sd->u + sd->du.dy, sd->v + sd->dv.dy, 0.0f); break;
68                 default: svm_node_geometry(kg, sd, stack, type, out_offset); return;
69         }
70
71         stack_store_float3(stack, out_offset, data);
72 #else
73         svm_node_geometry(kg, sd, stack, type, out_offset);
74 #endif
75 }
76
77 /* Object Info */
78
79 __device void svm_node_object_info(KernelGlobals *kg, ShaderData *sd, float *stack, uint type, uint out_offset)
80 {
81         float data;
82
83         switch(type) {
84                 case NODE_INFO_OB_LOCATION: {
85                         stack_store_float3(stack, out_offset, object_location(kg, sd));
86                         return;
87                 }
88                 case NODE_INFO_OB_INDEX: data = object_pass_id(kg, sd->object); break;
89                 case NODE_INFO_MAT_INDEX: data = shader_pass_id(kg, sd); break;
90                 case NODE_INFO_OB_RANDOM: data = object_random_number(kg, sd->object); break;
91                 default: data = 0.0f; break;
92         }
93
94         stack_store_float(stack, out_offset, data);
95 }
96
97 /* Particle Info */
98
99 __device void svm_node_particle_info(KernelGlobals *kg, ShaderData *sd, float *stack, uint type, uint out_offset)
100 {
101         switch(type) {
102                 case NODE_INFO_PAR_INDEX: {
103                         uint particle_id = object_particle_id(kg, sd->object);
104                         stack_store_float(stack, out_offset, particle_index(kg, particle_id));
105                         break;
106                 }
107                 case NODE_INFO_PAR_AGE: {
108                         uint particle_id = object_particle_id(kg, sd->object);
109                         stack_store_float(stack, out_offset, particle_age(kg, particle_id));
110                         break;
111                 }
112                 case NODE_INFO_PAR_LIFETIME: {
113                         uint particle_id = object_particle_id(kg, sd->object);
114                         stack_store_float(stack, out_offset, particle_lifetime(kg, particle_id));
115                         break;
116                 }
117                 case NODE_INFO_PAR_LOCATION: {
118                         uint particle_id = object_particle_id(kg, sd->object);
119                         stack_store_float3(stack, out_offset, particle_location(kg, particle_id));
120                         break;
121                 }
122                 #if 0   /* XXX float4 currently not supported in SVM stack */
123                 case NODE_INFO_PAR_ROTATION: {
124                         uint particle_id = object_particle_id(kg, sd->object);
125                         stack_store_float4(stack, out_offset, particle_rotation(kg, particle_id));
126                         break;
127                 }
128                 #endif
129                 case NODE_INFO_PAR_SIZE: {
130                         uint particle_id = object_particle_id(kg, sd->object);
131                         stack_store_float(stack, out_offset, particle_size(kg, particle_id));
132                         break;
133                 }
134                 case NODE_INFO_PAR_VELOCITY: {
135                         uint particle_id = object_particle_id(kg, sd->object);
136                         stack_store_float3(stack, out_offset, particle_velocity(kg, particle_id));
137                         break;
138                 }
139                 case NODE_INFO_PAR_ANGULAR_VELOCITY: {
140                         uint particle_id = object_particle_id(kg, sd->object);
141                         stack_store_float3(stack, out_offset, particle_angular_velocity(kg, particle_id));
142                         break;
143                 }
144         }
145 }
146
147 #ifdef __HAIR__
148
149 /* Hair Info */
150
151 __device void svm_node_hair_info(KernelGlobals *kg, ShaderData *sd, float *stack, uint type, uint out_offset)
152 {
153         float data;
154         float3 data3;
155
156         switch(type) {
157                 case NODE_INFO_CURVE_IS_STRAND: {
158                         data = !(sd->curve_seg == ~0);
159                         stack_store_float(stack, out_offset, data);
160                         break;
161                 }
162                 case NODE_INFO_CURVE_INTERCEPT:
163                         break; /* handled as attribute */
164                 case NODE_INFO_CURVE_THICKNESS: {
165                         data = curve_thickness(kg, sd);
166                         stack_store_float(stack, out_offset, data);
167                         break;
168                 }
169                 case NODE_INFO_CURVE_TANGENT_NORMAL: {
170                         data3 = curve_tangent_normal(kg, sd);
171                         stack_store_float3(stack, out_offset, data3);
172                         break;
173                 }
174         }
175 }
176 #endif
177
178 CCL_NAMESPACE_END
179