Fix incorrect FLT_MIN use
[blender.git] / intern / cycles / render / nodes.h
1 /*
2  * Copyright 2011-2013 Blender Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #ifndef __NODES_H__
18 #define __NODES_H__
19
20 #include "graph.h"
21
22 #include "util_string.h"
23
24 CCL_NAMESPACE_BEGIN
25
26 class ImageManager;
27 class Scene;
28 class Shader;
29
30 /* Texture Mapping */
31
32 class TextureMapping {
33 public:
34         TextureMapping();
35         Transform compute_transform();
36         bool skip();
37         void compile(SVMCompiler& compiler, int offset_in, int offset_out);
38         void compile(OSLCompiler &compiler);
39
40         int compile_begin(SVMCompiler& compiler, ShaderInput *vector_in);
41         void compile_end(SVMCompiler& compiler, ShaderInput *vector_in, int vector_offset);
42
43         float3 translation;
44         float3 rotation;
45         float3 scale;
46
47         float3 min, max;
48         bool use_minmax;
49
50         enum Type { POINT = 0, TEXTURE = 1, VECTOR = 2, NORMAL = 3 };
51         Type type;
52
53         enum Mapping { NONE = 0, X = 1, Y = 2, Z = 3 };
54         Mapping x_mapping, y_mapping, z_mapping;
55
56         enum Projection { FLAT, CUBE, TUBE, SPHERE };
57         Projection projection;
58
59         bool equals(const TextureMapping& other) {
60                 return translation == other.translation &&
61                        rotation == other.rotation &&
62                        scale == other.scale &&
63                        use_minmax == other.use_minmax &&
64                        min == other.min &&
65                        max == other.max &&
66                        type == other.type &&
67                        x_mapping == other.x_mapping &&
68                        y_mapping == other.y_mapping &&
69                        z_mapping == other.z_mapping &&
70                        projection == other.projection;
71         }
72 };
73
74 /* Nodes */
75
76 class TextureNode : public ShaderNode {
77 public:
78         TextureNode(const char *name_) : ShaderNode(name_) {}
79         TextureMapping tex_mapping;
80
81         virtual bool equals(const ShaderNode *other) {
82                 return ShaderNode::equals(other) &&
83                        tex_mapping.equals(((const TextureNode*)other)->tex_mapping);
84         }
85 };
86
87 /* Any node which uses image manager's slot should be a subclass of this one. */
88 class ImageSlotTextureNode : public TextureNode {
89 public:
90         ImageSlotTextureNode(const char *name_) : TextureNode(name_) {
91                 special_type = SHADER_SPECIAL_TYPE_IMAGE_SLOT;
92         }
93         int slot;
94 };
95
96 class ImageTextureNode : public ImageSlotTextureNode {
97 public:
98         SHADER_NODE_NO_CLONE_CLASS(ImageTextureNode)
99         ~ImageTextureNode();
100         ShaderNode *clone() const;
101         void attributes(Shader *shader, AttributeRequestSet *attributes);
102
103         ImageManager *image_manager;
104         int is_float;
105         bool is_linear;
106         bool use_alpha;
107         string filename;
108         void *builtin_data;
109         ustring color_space;
110         ustring projection;
111         InterpolationType interpolation;
112         ExtensionType extension;
113         float projection_blend;
114         bool animated;
115
116         static ShaderEnum color_space_enum;
117         static ShaderEnum projection_enum;
118
119         virtual bool equals(const ShaderNode *other) {
120                 const ImageTextureNode *image_node = (const ImageTextureNode*)other;
121                 return ImageSlotTextureNode::equals(other) &&
122                        use_alpha == image_node->use_alpha &&
123                        filename == image_node->filename &&
124                        builtin_data == image_node->builtin_data &&
125                        color_space == image_node->color_space &&
126                        projection == image_node->projection &&
127                        interpolation == image_node->interpolation &&
128                        extension == image_node->extension &&
129                        projection_blend == image_node->projection_blend &&
130                        animated == image_node->animated;
131         }
132 };
133
134 class EnvironmentTextureNode : public ImageSlotTextureNode {
135 public:
136         SHADER_NODE_NO_CLONE_CLASS(EnvironmentTextureNode)
137         ~EnvironmentTextureNode();
138         ShaderNode *clone() const;
139         void attributes(Shader *shader, AttributeRequestSet *attributes);
140         virtual int get_group() { return NODE_GROUP_LEVEL_2; }
141
142         ImageManager *image_manager;
143         int is_float;
144         bool is_linear;
145         bool use_alpha;
146         string filename;
147         void *builtin_data;
148         ustring color_space;
149         ustring projection;
150         InterpolationType interpolation;
151         bool animated;
152
153         static ShaderEnum color_space_enum;
154         static ShaderEnum projection_enum;
155
156         virtual bool equals(const ShaderNode *other) {
157                 const EnvironmentTextureNode *env_node = (const EnvironmentTextureNode*)other;
158                 return ImageSlotTextureNode::equals(other) &&
159                        use_alpha == env_node->use_alpha &&
160                        filename == env_node->filename &&
161                        builtin_data == env_node->builtin_data &&
162                        color_space == env_node->color_space &&
163                        projection == env_node->projection &&
164                        interpolation == env_node->interpolation &&
165                        animated == env_node->animated;
166         }
167 };
168
169 class SkyTextureNode : public TextureNode {
170 public:
171         SHADER_NODE_CLASS(SkyTextureNode)
172
173         virtual int get_group() { return NODE_GROUP_LEVEL_2; }
174
175         float3 sun_direction;
176         float turbidity;
177         float ground_albedo;
178
179         ustring type;
180         static ShaderEnum type_enum;
181
182         virtual bool equals(const ShaderNode *other) {
183                 const SkyTextureNode *sky_node = (const SkyTextureNode*)other;
184                 return TextureNode::equals(other) &&
185                        sun_direction == sky_node->sun_direction &&
186                        turbidity == sky_node->turbidity &&
187                        ground_albedo == sky_node->ground_albedo &&
188                        type == sky_node->type;
189         }
190 };
191
192 class OutputNode : public ShaderNode {
193 public:
194         SHADER_NODE_CLASS(OutputNode)
195
196         /* Don't allow output node de-duplication. */
197         virtual bool equals(const ShaderNode * /*other*/) { return false; }
198 };
199
200 class GradientTextureNode : public TextureNode {
201 public:
202         SHADER_NODE_CLASS(GradientTextureNode)
203
204         virtual int get_group() { return NODE_GROUP_LEVEL_2; }
205
206         ustring type;
207         static ShaderEnum type_enum;
208
209         virtual bool equals(const ShaderNode *other) {
210                 const GradientTextureNode *gradient_node = (const GradientTextureNode*)other;
211                 return TextureNode::equals(other) &&
212                        type == gradient_node->type;
213         }
214 };
215
216 class NoiseTextureNode : public TextureNode {
217 public:
218         SHADER_NODE_CLASS(NoiseTextureNode)
219 };
220
221 class VoronoiTextureNode : public TextureNode {
222 public:
223         SHADER_NODE_CLASS(VoronoiTextureNode)
224
225         virtual int get_group() { return NODE_GROUP_LEVEL_2; }
226
227         ustring coloring;
228
229         static ShaderEnum coloring_enum;
230
231         virtual bool equals(const ShaderNode *other) {
232                 const VoronoiTextureNode *voronoi_node = (const VoronoiTextureNode*)other;
233                 return TextureNode::equals(other) &&
234                        coloring == voronoi_node->coloring;
235         }
236 };
237
238 class MusgraveTextureNode : public TextureNode {
239 public:
240         SHADER_NODE_CLASS(MusgraveTextureNode)
241
242         virtual int get_group() { return NODE_GROUP_LEVEL_2; }
243
244         ustring type;
245
246         static ShaderEnum type_enum;
247
248         virtual bool equals(const ShaderNode *other) {
249                 const MusgraveTextureNode *musgrave_node = (const MusgraveTextureNode*)other;
250                 return TextureNode::equals(other) &&
251                        type == musgrave_node->type;
252         }
253 };
254
255 class WaveTextureNode : public TextureNode {
256 public:
257         SHADER_NODE_CLASS(WaveTextureNode)
258
259         virtual int get_group() { return NODE_GROUP_LEVEL_2; }
260
261         ustring type;
262         ustring profile;
263         static ShaderEnum type_enum;
264         static ShaderEnum profile_enum;
265
266         virtual bool equals(const ShaderNode *other) {
267                 const WaveTextureNode *wave_node = (const WaveTextureNode*)other;
268                 return TextureNode::equals(other) &&
269                        type == wave_node->type &&
270                        profile == wave_node->profile;
271         }
272 };
273
274 class MagicTextureNode : public TextureNode {
275 public:
276         SHADER_NODE_CLASS(MagicTextureNode)
277
278         virtual int get_group() { return NODE_GROUP_LEVEL_2; }
279
280         int depth;
281
282         virtual bool equals(const ShaderNode *other) {
283                 const MagicTextureNode *magic_node = (const MagicTextureNode*)other;
284                 return TextureNode::equals(other) &&
285                        depth == magic_node->depth;
286         }
287 };
288
289 class CheckerTextureNode : public TextureNode {
290 public:
291         SHADER_NODE_CLASS(CheckerTextureNode)
292
293         virtual int get_group() { return NODE_GROUP_LEVEL_2; }
294 };
295
296 class BrickTextureNode : public TextureNode {
297 public:
298         SHADER_NODE_CLASS(BrickTextureNode)
299
300         float offset, squash;
301         int offset_frequency, squash_frequency;
302
303         virtual int get_group() { return NODE_GROUP_LEVEL_2; }
304
305         virtual bool equals(const ShaderNode *other) {
306                 const BrickTextureNode *brick_node = (const BrickTextureNode*)other;
307                 return TextureNode::equals(other) &&
308                        offset == brick_node->offset &&
309                        squash == brick_node->squash &&
310                        offset_frequency == brick_node->offset_frequency &&
311                        squash_frequency == brick_node->squash_frequency;
312         }
313 };
314
315 class PointDensityTextureNode : public ShaderNode {
316 public:
317         SHADER_NODE_NO_CLONE_CLASS(PointDensityTextureNode)
318
319         ~PointDensityTextureNode();
320         ShaderNode *clone() const;
321         void attributes(Shader *shader, AttributeRequestSet *attributes);
322
323         bool has_spatial_varying() { return true; }
324         bool has_object_dependency() { return true; }
325
326         ImageManager *image_manager;
327         int slot;
328         string filename;
329         ustring space;
330         void *builtin_data;
331         InterpolationType interpolation;
332
333         Transform tfm;
334
335         static ShaderEnum space_enum;
336
337         virtual bool equals(const ShaderNode *other) {
338                 const PointDensityTextureNode *point_dendity_node = (const PointDensityTextureNode*)other;
339                 return ShaderNode::equals(other) &&
340                        filename == point_dendity_node->filename &&
341                        space == point_dendity_node->space &&
342                        builtin_data == point_dendity_node->builtin_data &&
343                        interpolation == point_dendity_node->interpolation &&
344                        tfm == point_dendity_node->tfm;
345         }
346 };
347
348 class MappingNode : public ShaderNode {
349 public:
350         SHADER_NODE_CLASS(MappingNode)
351         virtual int get_group() { return NODE_GROUP_LEVEL_2; }
352
353         TextureMapping tex_mapping;
354
355         virtual bool equals(const ShaderNode *other) {
356                 const MappingNode *mapping_node = (const MappingNode*)other;
357                 return ShaderNode::equals(other) &&
358                        tex_mapping.equals(mapping_node->tex_mapping);
359         }
360 };
361
362 class ConvertNode : public ShaderNode {
363 public:
364         ConvertNode(ShaderSocketType from, ShaderSocketType to, bool autoconvert = false);
365         SHADER_NODE_BASE_CLASS(ConvertNode)
366
367         bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, float3 *optimized_value);
368
369         ShaderSocketType from, to;
370
371         virtual bool equals(const ShaderNode *other)
372         {
373                 const ConvertNode *convert_node = (const ConvertNode*)other;
374                 return ShaderNode::equals(other) &&
375                        from == convert_node->from &&
376                        to == convert_node->to;
377         }
378 };
379
380 class BsdfNode : public ShaderNode {
381 public:
382         BsdfNode(bool scattering = false);
383         SHADER_NODE_BASE_CLASS(BsdfNode);
384
385         bool has_spatial_varying() { return true; }
386         void compile(SVMCompiler& compiler, ShaderInput *param1, ShaderInput *param2, ShaderInput *param3 = NULL, ShaderInput *param4 = NULL);
387
388         ClosureType closure;
389         bool scattering;
390
391         virtual bool equals(const ShaderNode * /*other*/)
392         {
393                 /* TODO(sergey): With some care BSDF nodes can be de-duplicated. */
394                 return false;
395         }
396 };
397
398 class AnisotropicBsdfNode : public BsdfNode {
399 public:
400         SHADER_NODE_CLASS(AnisotropicBsdfNode)
401
402         ustring distribution;
403         static ShaderEnum distribution_enum;
404
405         void attributes(Shader *shader, AttributeRequestSet *attributes);
406 };
407
408 class DiffuseBsdfNode : public BsdfNode {
409 public:
410         SHADER_NODE_CLASS(DiffuseBsdfNode)
411 };
412
413 class TranslucentBsdfNode : public BsdfNode {
414 public:
415         SHADER_NODE_CLASS(TranslucentBsdfNode)
416 };
417
418 class TransparentBsdfNode : public BsdfNode {
419 public:
420         SHADER_NODE_CLASS(TransparentBsdfNode)
421
422         bool has_surface_transparent() { return true; }
423 };
424
425 class VelvetBsdfNode : public BsdfNode {
426 public:
427         SHADER_NODE_CLASS(VelvetBsdfNode)
428 };
429
430 class GlossyBsdfNode : public BsdfNode {
431 public:
432         SHADER_NODE_CLASS(GlossyBsdfNode)
433
434         void simplify_settings(Scene *scene);
435         bool has_integrator_dependency();
436
437         ustring distribution, distribution_orig;
438         static ShaderEnum distribution_enum;
439 };
440
441 class GlassBsdfNode : public BsdfNode {
442 public:
443         SHADER_NODE_CLASS(GlassBsdfNode)
444
445         void simplify_settings(Scene *scene);
446         bool has_integrator_dependency();
447
448         ustring distribution, distribution_orig;
449         static ShaderEnum distribution_enum;
450 };
451
452 class RefractionBsdfNode : public BsdfNode {
453 public:
454         SHADER_NODE_CLASS(RefractionBsdfNode)
455
456         void simplify_settings(Scene *scene);
457         bool has_integrator_dependency();
458
459         ustring distribution, distribution_orig;
460         static ShaderEnum distribution_enum;
461 };
462
463 class ToonBsdfNode : public BsdfNode {
464 public:
465         SHADER_NODE_CLASS(ToonBsdfNode)
466
467         ustring component;
468         static ShaderEnum component_enum;
469 };
470
471 class SubsurfaceScatteringNode : public BsdfNode {
472 public:
473         SHADER_NODE_CLASS(SubsurfaceScatteringNode)
474         bool has_surface_bssrdf() { return true; }
475         bool has_bssrdf_bump();
476
477         static ShaderEnum falloff_enum;
478 };
479
480 class EmissionNode : public ShaderNode {
481 public:
482         SHADER_NODE_CLASS(EmissionNode)
483         bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, float3 *optimized_value);
484
485         bool has_surface_emission() { return true; }
486 };
487
488 class BackgroundNode : public ShaderNode {
489 public:
490         SHADER_NODE_CLASS(BackgroundNode)
491         bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, float3 *optimized_value);
492 };
493
494 class HoldoutNode : public ShaderNode {
495 public:
496         SHADER_NODE_CLASS(HoldoutNode)
497         virtual int get_group() { return NODE_GROUP_LEVEL_1; }
498 };
499
500 class AmbientOcclusionNode : public ShaderNode {
501 public:
502         SHADER_NODE_CLASS(AmbientOcclusionNode)
503
504         bool has_spatial_varying() { return true; }
505         virtual int get_group() { return NODE_GROUP_LEVEL_1; }
506 };
507
508 class VolumeNode : public ShaderNode {
509 public:
510         SHADER_NODE_CLASS(VolumeNode)
511
512         void compile(SVMCompiler& compiler, ShaderInput *param1, ShaderInput *param2);
513         virtual int get_group() { return NODE_GROUP_LEVEL_1; }
514
515         ClosureType closure;
516
517         virtual bool equals(const ShaderNode * /*other*/)
518         {
519                 /* TODO(sergey): With some care Volume nodes can be de-duplicated. */
520                 return false;
521         }
522 };
523
524 class AbsorptionVolumeNode : public VolumeNode {
525 public:
526         SHADER_NODE_CLASS(AbsorptionVolumeNode)
527 };
528
529 class ScatterVolumeNode : public VolumeNode {
530 public:
531         SHADER_NODE_CLASS(ScatterVolumeNode)
532 };
533
534 class HairBsdfNode : public BsdfNode {
535 public:
536         SHADER_NODE_CLASS(HairBsdfNode)
537
538         ustring component;
539         static ShaderEnum component_enum;
540
541 };
542
543 class GeometryNode : public ShaderNode {
544 public:
545         SHADER_NODE_CLASS(GeometryNode)
546         void attributes(Shader *shader, AttributeRequestSet *attributes);
547         bool has_spatial_varying() { return true; }
548 };
549
550 class TextureCoordinateNode : public ShaderNode {
551 public:
552         SHADER_NODE_CLASS(TextureCoordinateNode)
553         void attributes(Shader *shader, AttributeRequestSet *attributes);
554         bool has_spatial_varying() { return true; }
555         bool has_object_dependency() { return use_transform; }
556
557         bool from_dupli;
558         bool use_transform;
559         Transform ob_tfm;
560
561         virtual bool equals(const ShaderNode *other) {
562                 const TextureCoordinateNode *texco_node = (const TextureCoordinateNode*)other;
563                 return ShaderNode::equals(other) &&
564                        from_dupli == texco_node->from_dupli &&
565                        use_transform == texco_node->use_transform &&
566                        ob_tfm == texco_node->ob_tfm;
567         }
568 };
569
570 class UVMapNode : public ShaderNode {
571 public:
572         SHADER_NODE_CLASS(UVMapNode)
573         void attributes(Shader *shader, AttributeRequestSet *attributes);
574         bool has_spatial_varying() { return true; }
575         virtual int get_group() { return NODE_GROUP_LEVEL_1; }
576
577         ustring attribute;
578         bool from_dupli;
579
580         virtual bool equals(const ShaderNode *other) {
581                 const UVMapNode *uv_map_node = (const UVMapNode*)other;
582                 return ShaderNode::equals(other) &&
583                        attribute == uv_map_node->attribute &&
584                        from_dupli == uv_map_node->from_dupli;
585         }
586 };
587
588 class LightPathNode : public ShaderNode {
589 public:
590         SHADER_NODE_CLASS(LightPathNode)
591         virtual int get_group() { return NODE_GROUP_LEVEL_1; }
592 };
593
594 class LightFalloffNode : public ShaderNode {
595 public:
596         SHADER_NODE_CLASS(LightFalloffNode)
597         bool has_spatial_varying() { return true; }
598         virtual int get_group() { return NODE_GROUP_LEVEL_2; }
599 };
600
601 class ObjectInfoNode : public ShaderNode {
602 public:
603         SHADER_NODE_CLASS(ObjectInfoNode)
604         virtual int get_group() { return NODE_GROUP_LEVEL_1; }
605 };
606
607 class ParticleInfoNode : public ShaderNode {
608 public:
609         SHADER_NODE_CLASS(ParticleInfoNode)
610         void attributes(Shader *shader, AttributeRequestSet *attributes);
611         virtual int get_group() { return NODE_GROUP_LEVEL_1; }
612 };
613
614 class HairInfoNode : public ShaderNode {
615 public:
616         SHADER_NODE_CLASS(HairInfoNode)
617
618         void attributes(Shader *shader, AttributeRequestSet *attributes);
619         bool has_spatial_varying() { return true; }
620         virtual int get_group() { return NODE_GROUP_LEVEL_1; }
621         virtual int get_feature() {
622                 return ShaderNode::get_feature() | NODE_FEATURE_HAIR;
623         }
624 };
625
626 class ValueNode : public ShaderNode {
627 public:
628         SHADER_NODE_CLASS(ValueNode)
629
630         bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, float3 *optimized_value);
631
632         float value;
633
634         virtual bool equals(const ShaderNode *other) {
635                 const ValueNode *value_node = (const ValueNode*)other;
636                 return ShaderNode::equals(other) &&
637                        value == value_node->value;
638         }
639 };
640
641 class ColorNode : public ShaderNode {
642 public:
643         SHADER_NODE_CLASS(ColorNode)
644
645         bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, float3 *optimized_value);
646
647         float3 value;
648
649         virtual bool equals(const ShaderNode *other) {
650                 const ColorNode *color_node = (const ColorNode*)other;
651                 return ShaderNode::equals(other) &&
652                        value == color_node->value;
653         }
654 };
655
656 class AddClosureNode : public ShaderNode {
657 public:
658         SHADER_NODE_CLASS(AddClosureNode)
659 };
660
661 class MixClosureNode : public ShaderNode {
662 public:
663         SHADER_NODE_CLASS(MixClosureNode)
664         bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, float3 *optimized_value);
665 };
666
667 class MixClosureWeightNode : public ShaderNode {
668 public:
669         SHADER_NODE_CLASS(MixClosureWeightNode);
670 };
671
672 class InvertNode : public ShaderNode {
673 public:
674         SHADER_NODE_CLASS(InvertNode)
675
676         virtual int get_group() { return NODE_GROUP_LEVEL_3; }
677 };
678
679 class MixNode : public ShaderNode {
680 public:
681         SHADER_NODE_CLASS(MixNode)
682         bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, float3 *optimized_value);
683
684         virtual int get_group() { return NODE_GROUP_LEVEL_3; }
685
686         bool use_clamp;
687
688         ustring type;
689         static ShaderEnum type_enum;
690
691         virtual bool equals(const ShaderNode *other)
692         {
693                 const MixNode *mix_node = (const MixNode*)other;
694                 return ShaderNode::equals(other) &&
695                        use_clamp == mix_node->use_clamp &&
696                        type == mix_node->type;
697         }
698 };
699
700 class CombineRGBNode : public ShaderNode {
701 public:
702         SHADER_NODE_CLASS(CombineRGBNode)
703
704         virtual int get_group() { return NODE_GROUP_LEVEL_3; }
705 };
706
707 class CombineHSVNode : public ShaderNode {
708 public:
709         SHADER_NODE_CLASS(CombineHSVNode)
710
711         virtual int get_group() { return NODE_GROUP_LEVEL_3; }
712 };
713
714 class CombineXYZNode : public ShaderNode {
715 public:
716         SHADER_NODE_CLASS(CombineXYZNode)
717
718         virtual int get_group() { return NODE_GROUP_LEVEL_3; }
719 };
720
721 class GammaNode : public ShaderNode {
722 public:
723         SHADER_NODE_CLASS(GammaNode)
724
725         bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, float3 *optimized_value);
726
727         virtual int get_group() { return NODE_GROUP_LEVEL_1; }
728 };
729
730 class BrightContrastNode : public ShaderNode {
731 public:
732         SHADER_NODE_CLASS(BrightContrastNode)
733         virtual int get_group() { return NODE_GROUP_LEVEL_1; }
734 };
735
736 class SeparateRGBNode : public ShaderNode {
737 public:
738         SHADER_NODE_CLASS(SeparateRGBNode)
739
740         virtual int get_group() { return NODE_GROUP_LEVEL_3; }
741 };
742
743 class SeparateHSVNode : public ShaderNode {
744 public:
745         SHADER_NODE_CLASS(SeparateHSVNode)
746
747         virtual int get_group() { return NODE_GROUP_LEVEL_3; }
748 };
749
750 class SeparateXYZNode : public ShaderNode {
751 public:
752         SHADER_NODE_CLASS(SeparateXYZNode)
753
754         virtual int get_group() { return NODE_GROUP_LEVEL_3; }
755 };
756
757 class HSVNode : public ShaderNode {
758 public:
759         SHADER_NODE_CLASS(HSVNode)
760 };
761
762 class AttributeNode : public ShaderNode {
763 public:
764         SHADER_NODE_CLASS(AttributeNode)
765         void attributes(Shader *shader, AttributeRequestSet *attributes);
766         bool has_spatial_varying() { return true; }
767
768         ustring attribute;
769
770         virtual bool equals(const ShaderNode *other) {
771                 const AttributeNode *color_node = (const AttributeNode*)other;
772                 return ShaderNode::equals(other) &&
773                        attribute == color_node->attribute;
774         }
775 };
776
777 class CameraNode : public ShaderNode {
778 public:
779         SHADER_NODE_CLASS(CameraNode)
780         bool has_spatial_varying() { return true; }
781 };
782
783 class FresnelNode : public ShaderNode {
784 public:
785         SHADER_NODE_CLASS(FresnelNode)
786         bool has_spatial_varying() { return true; }
787         virtual int get_group() { return NODE_GROUP_LEVEL_1; }
788 };
789
790 class LayerWeightNode : public ShaderNode {
791 public:
792         SHADER_NODE_CLASS(LayerWeightNode)
793         bool has_spatial_varying() { return true; }
794         virtual int get_group() { return NODE_GROUP_LEVEL_1; }
795 };
796
797 class WireframeNode : public ShaderNode {
798 public:
799         SHADER_NODE_CLASS(WireframeNode)
800         bool has_spatial_varying() { return true; }
801         virtual int get_group() { return NODE_GROUP_LEVEL_3; }
802
803         bool use_pixel_size;
804 };
805
806 class WavelengthNode : public ShaderNode {
807 public:
808         SHADER_NODE_CLASS(WavelengthNode)
809
810         virtual int get_group() { return NODE_GROUP_LEVEL_3; }
811 };
812
813 class BlackbodyNode : public ShaderNode {
814 public:
815         SHADER_NODE_CLASS(BlackbodyNode)
816         bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, float3 *optimized_value);
817
818         virtual int get_group() { return NODE_GROUP_LEVEL_3; }
819 };
820
821 class MathNode : public ShaderNode {
822 public:
823         SHADER_NODE_CLASS(MathNode)
824         virtual int get_group() { return NODE_GROUP_LEVEL_1; }
825         bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, float3 *optimized_value);
826
827         bool use_clamp;
828
829         ustring type;
830         static ShaderEnum type_enum;
831
832         virtual bool equals(const ShaderNode *other)
833         {
834                 const MathNode *math_node = (const MathNode*)other;
835                 return ShaderNode::equals(other) &&
836                        use_clamp == math_node->use_clamp &&
837                        type == math_node->type;
838         }
839 };
840
841 class NormalNode : public ShaderNode {
842 public:
843         SHADER_NODE_CLASS(NormalNode)
844         virtual int get_group() { return NODE_GROUP_LEVEL_2; }
845
846         float3 direction;
847
848         virtual bool equals(const ShaderNode *other)
849         {
850                 const NormalNode *normal_node = (const NormalNode*)other;
851                 return ShaderNode::equals(other) &&
852                        direction == normal_node->direction;
853         }
854 };
855
856 class VectorMathNode : public ShaderNode {
857 public:
858         SHADER_NODE_CLASS(VectorMathNode)
859         virtual int get_group() { return NODE_GROUP_LEVEL_1; }
860         bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, float3 *optimized_value);
861
862         ustring type;
863         static ShaderEnum type_enum;
864
865         virtual bool equals(const ShaderNode *other)
866         {
867                 const MathNode *math_node = (const MathNode*)other;
868                 return ShaderNode::equals(other) &&
869                        type == math_node->type;
870         }
871 };
872
873 class VectorTransformNode : public ShaderNode {
874 public:
875         SHADER_NODE_CLASS(VectorTransformNode)
876
877         virtual int get_group() { return NODE_GROUP_LEVEL_3; }
878
879         ustring type;
880         ustring convert_from;
881         ustring convert_to;
882
883         static ShaderEnum type_enum;
884         static ShaderEnum convert_space_enum;
885
886         virtual bool equals(const ShaderNode *other) {
887                 const VectorTransformNode *vector_transform_node = (const VectorTransformNode*)other;
888                 return ShaderNode::equals(other) &&
889                        type == vector_transform_node->type &&
890                        convert_from == vector_transform_node->convert_from &&
891                        convert_to == vector_transform_node->convert_to;
892         }
893 };
894
895 class BumpNode : public ShaderNode {
896 public:
897         SHADER_NODE_CLASS(BumpNode)
898         bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, float3 *optimized_value);
899         bool has_spatial_varying() { return true; }
900         virtual int get_feature() {
901                 return NODE_FEATURE_BUMP;
902         }
903
904         bool invert;
905
906         virtual bool equals(const ShaderNode *other) {
907                 const BumpNode *bump_node = (const BumpNode*)other;
908                 return ShaderNode::equals(other) &&
909                        invert == bump_node->invert;
910         }
911 };
912
913 class RGBCurvesNode : public ShaderNode {
914 public:
915         SHADER_NODE_CLASS(RGBCurvesNode)
916
917         virtual int get_group() { return NODE_GROUP_LEVEL_3; }
918         virtual bool equals(const ShaderNode * /*other*/) { return false; }
919
920         float4 curves[RAMP_TABLE_SIZE];
921         float min_x, max_x;
922 };
923
924 class VectorCurvesNode : public ShaderNode {
925 public:
926         SHADER_NODE_CLASS(VectorCurvesNode)
927
928         virtual int get_group() { return NODE_GROUP_LEVEL_3; }
929         virtual bool equals(const ShaderNode * /*other*/) { return false; }
930
931         float4 curves[RAMP_TABLE_SIZE];
932         float min_x, max_x;
933 };
934
935 class RGBRampNode : public ShaderNode {
936 public:
937         SHADER_NODE_CLASS(RGBRampNode)
938         float4 ramp[RAMP_TABLE_SIZE];
939         bool interpolate;
940         virtual int get_group() { return NODE_GROUP_LEVEL_1; }
941         virtual bool equals(const ShaderNode * /*other*/) { return false; }
942 };
943
944 class SetNormalNode : public ShaderNode {
945 public:
946         SHADER_NODE_CLASS(SetNormalNode)
947 };
948
949 class OSLScriptNode : public ShaderNode {
950 public:
951         SHADER_NODE_CLASS(OSLScriptNode)
952
953         /* ideally we could beter detect this, but we can't query this now */
954         bool has_spatial_varying() { return true; }
955
956         string filepath;
957         string bytecode_hash;
958
959         virtual bool equals(const ShaderNode * /*other*/) { return false; }
960 };
961
962 class NormalMapNode : public ShaderNode {
963 public:
964         SHADER_NODE_CLASS(NormalMapNode)
965         void attributes(Shader *shader, AttributeRequestSet *attributes);
966         bool has_spatial_varying() { return true; }
967         virtual int get_group() { return NODE_GROUP_LEVEL_3; }
968
969         ustring space;
970         static ShaderEnum space_enum;
971
972         ustring attribute;
973
974         virtual bool equals(const ShaderNode *other)
975         {
976                 const NormalMapNode *normal_map_node = (const NormalMapNode*)other;
977                 return ShaderNode::equals(other) &&
978                        space == normal_map_node->space &&
979                        attribute == normal_map_node->attribute;
980         }
981 };
982
983 class TangentNode : public ShaderNode {
984 public:
985         SHADER_NODE_CLASS(TangentNode)
986         void attributes(Shader *shader, AttributeRequestSet *attributes);
987         bool has_spatial_varying() { return true; }
988         virtual int get_group() { return NODE_GROUP_LEVEL_3; }
989
990         ustring direction_type;
991         static ShaderEnum direction_type_enum;
992
993         ustring axis;
994         static ShaderEnum axis_enum;
995
996         ustring attribute;
997
998         virtual bool equals(const ShaderNode *other)
999         {
1000                 const TangentNode *tangent_node = (const TangentNode*)other;
1001                 return ShaderNode::equals(other) &&
1002                        direction_type == tangent_node->direction_type &&
1003                        axis == tangent_node->axis &&
1004                        attribute == tangent_node->attribute;
1005         }
1006 };
1007
1008 CCL_NAMESPACE_END
1009
1010 #endif /* __NODES_H__ */
1011