55f4bf3794d4fa4e10da6779096dac7767be6b45
[blender.git] / source / blender / render / intern / source / texture_ocean.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
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  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19  * All rights reserved.
20  *
21  * Contributors: Matt Ebb
22  *
23  * ***** END GPL LICENSE BLOCK *****
24  */
25
26 /** \file blender/render/intern/source/texture_ocean.c
27  *  \ingroup bke
28  */
29
30 #include <stddef.h>
31
32 #include "BLI_math.h"
33 #include "BLI_utildefines.h"
34
35 #include "DNA_modifier_types.h"
36 #include "DNA_object_types.h"
37 #include "DNA_texture_types.h"
38
39 #include "BKE_global.h" /* XXX */
40
41 #include "BKE_modifier.h"
42 #include "BKE_ocean.h"
43
44 #include "render_types.h"
45 #include "RE_shader_ext.h"
46
47 #include "texture.h"
48
49 #include "texture_ocean.h"  /* own include */
50
51
52 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
53 /* defined in pipeline.c, is hardcopy of active dynamic allocated Render */
54 /* only to be used here in this file, it's for speed */
55 extern struct Render R;
56 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
57
58
59
60
61 /* ***** actual texture sampling ***** */
62 int ocean_texture(Tex *tex, const float texvec[2], TexResult *texres)
63 {
64         OceanTex *ot = tex->ot;
65         ModifierData *md;
66         OceanModifierData *omd;
67
68         texres->tin = 0.0f;
69
70         if ( !(ot) ||
71              !(ot->object) ||
72              !(md  = (ModifierData *)modifiers_findByType(ot->object, eModifierType_Ocean)) ||
73              !(omd = (OceanModifierData *)md)->ocean)
74         {
75                 return 0;
76         }
77         else {
78                 const int do_normals = (omd->flag & MOD_OCEAN_GENERATE_NORMALS);
79                 int cfra = R.r.cfra;
80                 int retval = TEX_INT;
81
82                 OceanResult ocr;
83                 const float u = 0.5f + 0.5f * texvec[0];
84                 const float v = 0.5f + 0.5f * texvec[1];
85
86                 if (omd->oceancache && omd->cached == true) {
87
88                         CLAMP(cfra, omd->bakestart, omd->bakeend);
89                         cfra -= omd->bakestart; /* shift to 0 based */
90
91                         BKE_ocean_cache_eval_uv(omd->oceancache, &ocr, cfra, u, v);
92
93                 }
94                 else {  /* non-cached */
95
96                         if (G.is_rendering)
97                                 BKE_ocean_eval_uv_catrom(omd->ocean, &ocr, u, v);
98                         else
99                                 BKE_ocean_eval_uv(omd->ocean, &ocr, u, v);
100
101                         ocr.foam = BKE_ocean_jminus_to_foam(ocr.Jminus, omd->foam_coverage);
102                 }
103
104                 switch (ot->output) {
105                         case TEX_OCN_DISPLACEMENT:
106                                 /* XYZ displacement */
107                                 texres->tr = 0.5f + 0.5f * ocr.disp[0];
108                                 texres->tg = 0.5f + 0.5f * ocr.disp[2];
109                                 texres->tb = 0.5f + 0.5f * ocr.disp[1];
110
111                                 texres->tr = MAX2(0.0f, texres->tr);
112                                 texres->tg = MAX2(0.0f, texres->tg);
113                                 texres->tb = MAX2(0.0f, texres->tb);
114
115                                 BRICONTRGB;
116
117                                 retval = TEX_RGB;
118                                 break;
119
120                         case TEX_OCN_EMINUS:
121                                 /* -ve eigenvectors ? */
122                                 texres->tr = ocr.Eminus[0];
123                                 texres->tg = ocr.Eminus[2];
124                                 texres->tb = ocr.Eminus[1];
125                                 retval = TEX_RGB;
126                                 break;
127
128                         case TEX_OCN_EPLUS:
129                                 /* -ve eigenvectors ? */
130                                 texres->tr = ocr.Eplus[0];
131                                 texres->tg = ocr.Eplus[2];
132                                 texres->tb = ocr.Eplus[1];
133                                 retval = TEX_RGB;
134                                 break;
135
136                         case TEX_OCN_JPLUS:
137                                 texres->tin = ocr.Jplus;
138                                 retval = TEX_INT;
139                                 break;
140
141                         case TEX_OCN_FOAM:
142
143                                 texres->tin = ocr.foam;
144
145                                 BRICONT;
146
147                                 retval = TEX_INT;
148                                 break;
149                 }
150
151                 /* if normals needed */
152
153                 if (texres->nor && do_normals) {
154                         normalize_v3_v3(texres->nor, ocr.normal);
155                         retval |= TEX_NOR;
156                 }
157
158                 texres->ta = 1.0f;
159
160                 return retval;
161         }
162 }