1 /*
2     Copyright (c) 2005-2021 Intel Corporation
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 /*
18     The original source for this example is
19     Copyright (c) 1994-2008 John E. Stone
20     All rights reserved.
21 
22     Redistribution and use in source and binary forms, with or without
23     modification, are permitted provided that the following conditions
24     are met:
25     1. Redistributions of source code must retain the above copyright
26        notice, this list of conditions and the following disclaimer.
27     2. Redistributions in binary form must reproduce the above copyright
28        notice, this list of conditions and the following disclaimer in the
29        documentation and/or other materials provided with the distribution.
30     3. The name of the author may not be used to endorse or promote products
31        derived from this software without specific prior written permission.
32 
33     THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
34     OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
35     WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
36     ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
37     DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
38     DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
39     OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
40     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
41     LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
42     OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
43     SUCH DAMAGE.
44 */
45 
46 /*
47  * texture.cpp - This file contains functions for implementing textures.
48  */
49 
50 #include "machine.hpp"
51 #include "types.hpp"
52 #include "macros.hpp"
53 #include "texture.hpp"
54 #include "coordsys.hpp"
55 #include "imap.hpp"
56 #include "vector.hpp"
57 #include "box.hpp"
58 
59 /* plain vanilla texture solely based on object color */
standard_texture(vector * hit,texture * tex,ray * ry)60 color standard_texture(vector *hit, texture *tex, ray *ry) {
61     return tex->col;
62 }
63 
64 /* cylindrical image map */
image_cyl_texture(vector * hit,texture * tex,ray * ry)65 color image_cyl_texture(vector *hit, texture *tex, ray *ry) {
66     vector rh;
67     flt u, v;
68 
69     rh.x = hit->x - tex->ctr.x;
70     rh.z = hit->y - tex->ctr.y;
71     rh.y = hit->z - tex->ctr.z;
72 
73     xyztocyl(rh, 1.0, &u, &v);
74 
75     u = u * tex->scale.x;
76     u = u + tex->rot.x;
77     u = fmod(u, 1.0);
78     if (u < 0.0)
79         u += 1.0;
80 
81     v = v * tex->scale.y;
82     v = v + tex->rot.y;
83     v = fmod(v, 1.0);
84     if (v < 0.0)
85         v += 1.0;
86 
87     return ImageMap((rawimage *)tex->img, u, v);
88 }
89 
90 /* spherical image map */
image_sphere_texture(vector * hit,texture * tex,ray * ry)91 color image_sphere_texture(vector *hit, texture *tex, ray *ry) {
92     vector rh;
93     flt u, v;
94 
95     rh.x = hit->x - tex->ctr.x;
96     rh.y = hit->y - tex->ctr.y;
97     rh.z = hit->z - tex->ctr.z;
98 
99     xyztospr(rh, &u, &v);
100 
101     u = u * tex->scale.x;
102     u = u + tex->rot.x;
103     u = fmod(u, 1.0);
104     if (u < 0.0)
105         u += 1.0;
106 
107     v = v * tex->scale.y;
108     v = v + tex->rot.y;
109     v = fmod(v, 1.0);
110     if (v < 0.0)
111         v += 1.0;
112 
113     return ImageMap((rawimage *)tex->img, u, v);
114 }
115 
116 /* planar image map */
image_plane_texture(vector * hit,texture * tex,ray * ry)117 color image_plane_texture(vector *hit, texture *tex, ray *ry) {
118     vector pnt;
119     flt u, v;
120 
121     pnt.x = hit->x - tex->ctr.x;
122     pnt.y = hit->y - tex->ctr.y;
123     pnt.z = hit->z - tex->ctr.z;
124 
125     VDOT(u, tex->uaxs, pnt);
126     /*  VDOT(len, tex->uaxs, tex->uaxs);
127   u = u / sqrt(len); */
128 
129     VDOT(v, tex->vaxs, pnt);
130     /*  VDOT(len, tex->vaxs, tex->vaxs);
131   v = v / sqrt(len); */
132 
133     u = u * tex->scale.x;
134     u = u + tex->rot.x;
135     u = fmod(u, 1.0);
136     if (u < 0.0)
137         u += 1.0;
138 
139     v = v * tex->scale.y;
140     v = v + tex->rot.y;
141     v = fmod(v, 1.0);
142     if (v < 0.0)
143         v += 1.0;
144 
145     return ImageMap((rawimage *)tex->img, u, v);
146 }
147 
grit_texture(vector * hit,texture * tex,ray * ry)148 color grit_texture(vector *hit, texture *tex, ray *ry) {
149     int rnum;
150     flt fnum;
151     color col;
152 
153     rnum = rand() % 4096;
154     fnum = (rnum / 4096.0 * 0.2) + 0.8;
155 
156     col.r = tex->col.r * fnum;
157     col.g = tex->col.g * fnum;
158     col.b = tex->col.b * fnum;
159 
160     return col;
161 }
162 
checker_texture(vector * hit,texture * tex,ray * ry)163 color checker_texture(vector *hit, texture *tex, ray *ry) {
164     long x, y, z;
165     flt xh, yh, zh;
166     color col;
167 
168     xh = hit->x - tex->ctr.x;
169     x = (long)((fabs(xh) * 3) + 0.5);
170     x = x % 2;
171     yh = hit->y - tex->ctr.y;
172     y = (long)((fabs(yh) * 3) + 0.5);
173     y = y % 2;
174     zh = hit->z - tex->ctr.z;
175     z = (long)((fabs(zh) * 3) + 0.5);
176     z = z % 2;
177 
178     if (((x + y + z) % 2) == 1) {
179         col.r = 1.0;
180         col.g = 0.2;
181         col.b = 0.0;
182     }
183     else {
184         col.r = 0.0;
185         col.g = 0.2;
186         col.b = 1.0;
187     }
188 
189     return col;
190 }
191 
cyl_checker_texture(vector * hit,texture * tex,ray * ry)192 color cyl_checker_texture(vector *hit, texture *tex, ray *ry) {
193     long x, y;
194     vector rh;
195     flt u, v;
196     color col;
197 
198     rh.x = hit->x - tex->ctr.x;
199     rh.y = hit->y - tex->ctr.y;
200     rh.z = hit->z - tex->ctr.z;
201 
202     xyztocyl(rh, 1.0, &u, &v);
203 
204     x = (long)(fabs(u) * 18.0);
205     x = x % 2;
206     y = (long)(fabs(v) * 10.0);
207     y = y % 2;
208 
209     if (((x + y) % 2) == 1) {
210         col.r = 1.0;
211         col.g = 0.2;
212         col.b = 0.0;
213     }
214     else {
215         col.r = 0.0;
216         col.g = 0.2;
217         col.b = 1.0;
218     }
219 
220     return col;
221 }
222 
wood_texture(vector * hit,texture * tex,ray * ry)223 color wood_texture(vector *hit, texture *tex, ray *ry) {
224     flt radius, angle;
225     int grain;
226     color col;
227     flt x, y, z;
228 
229     x = (hit->x - tex->ctr.x) * 1000;
230     y = (hit->y - tex->ctr.y) * 1000;
231     z = (hit->z - tex->ctr.z) * 1000;
232 
233     radius = sqrt(x * x + z * z);
234     if (z == 0.0)
235         angle = 3.1415926 / 2.0;
236     else
237         angle = atan(x / z);
238 
239     radius = radius + 3.0 * sin(20 * angle + y / 150.0);
240     grain = ((int)(radius + 0.5)) % 60;
241     if (grain < 40) {
242         col.r = 0.8;
243         col.g = 1.0;
244         col.b = 0.2;
245     }
246     else {
247         col.r = 0.0;
248         col.g = 0.0;
249         col.b = 0.0;
250     }
251 
252     return col;
253 }
254 
255 #define NMAX 28
256 short int NoiseMatrix[NMAX][NMAX][NMAX];
257 
InitNoise(void)258 void InitNoise(void) {
259     byte_t x, y, z, i, j, k;
260 
261     for (x = 0; x < NMAX; x++) {
262         for (y = 0; y < NMAX; y++) {
263             for (z = 0; z < NMAX; z++) {
264                 NoiseMatrix[x][y][z] = rand() % 12000;
265 
266                 if (x == NMAX - 1)
267                     i = 0;
268                 else
269                     i = x;
270 
271                 if (y == NMAX - 1)
272                     j = 0;
273                 else
274                     j = y;
275 
276                 if (z == NMAX - 1)
277                     k = 0;
278                 else
279                     k = z;
280 
281                 NoiseMatrix[x][y][z] = NoiseMatrix[i][j][k];
282             }
283         }
284     }
285 }
286 
Noise(flt x,flt y,flt z)287 int Noise(flt x, flt y, flt z) {
288     byte_t ix, iy, iz;
289     flt ox, oy, oz;
290     int p000, p001, p010, p011;
291     int p100, p101, p110, p111;
292     int p00, p01, p10, p11;
293     int p0, p1;
294     int d00, d01, d10, d11;
295     int d0, d1, d;
296 
297     x = fabs(x);
298     y = fabs(y);
299     z = fabs(z);
300 
301     ix = ((int)x) % (NMAX - 1);
302     iy = ((int)y) % (NMAX - 1);
303     iz = ((int)z) % (NMAX - 1);
304 
305     ox = (x - ((int)x));
306     oy = (y - ((int)y));
307     oz = (z - ((int)z));
308 
309     p000 = NoiseMatrix[ix][iy][iz];
310     p001 = NoiseMatrix[ix][iy][iz + 1];
311     p010 = NoiseMatrix[ix][iy + 1][iz];
312     p011 = NoiseMatrix[ix][iy + 1][iz + 1];
313     p100 = NoiseMatrix[ix + 1][iy][iz];
314     p101 = NoiseMatrix[ix + 1][iy][iz + 1];
315     p110 = NoiseMatrix[ix + 1][iy + 1][iz];
316     p111 = NoiseMatrix[ix + 1][iy + 1][iz + 1];
317 
318     d00 = p100 - p000;
319     d01 = p101 - p001;
320     d10 = p110 - p010;
321     d11 = p111 - p011;
322 
323     p00 = (int)((int)d00 * ox) + p000;
324     p01 = (int)((int)d01 * ox) + p001;
325     p10 = (int)((int)d10 * ox) + p010;
326     p11 = (int)((int)d11 * ox) + p011;
327     d0 = p10 - p00;
328     d1 = p11 - p01;
329     p0 = (int)((int)d0 * oy) + p00;
330     p1 = (int)((int)d1 * oy) + p01;
331     d = p1 - p0;
332 
333     return (int)((int)d * oz) + p0;
334 }
335 
marble_texture(vector * hit,texture * tex,ray * ry)336 color marble_texture(vector *hit, texture *tex, ray *ry) {
337     flt i, d;
338     flt x, y, z;
339     color col;
340 
341     x = hit->x;
342     y = hit->y;
343     z = hit->z;
344 
345     x = x * 1.0;
346 
347     d = x + 0.0006 * Noise(x, (y * 1.0), (z * 1.0));
348     d = d * (((int)d) % 25);
349     i = 0.0 + 0.10 * fabs(d - 10.0 - 20.0 * ((int)d * 0.05));
350     if (i > 1.0)
351         i = 1.0;
352     if (i < 0.0)
353         i = 0.0;
354 
355     /*
356   col.r=i * tex->col.r;
357   col.g=i * tex->col.g;
358   col.b=i * tex->col.b;
359 */
360 
361     col.r = (1.0 + sin(i * 6.28)) / 2.0;
362     col.g = (1.0 + sin(i * 16.28)) / 2.0;
363     col.b = (1.0 + cos(i * 30.28)) / 2.0;
364 
365     return col;
366 }
367 
gnoise_texture(vector * hit,texture * tex,ray * ry)368 color gnoise_texture(vector *hit, texture *tex, ray *ry) {
369     color col;
370     flt f;
371 
372     f = Noise((hit->x - tex->ctr.x), (hit->y - tex->ctr.y), (hit->z - tex->ctr.z));
373 
374     if (f < 0.01)
375         f = 0.01;
376     if (f > 1.0)
377         f = 1.0;
378 
379     col.r = tex->col.r * f;
380     col.g = tex->col.g * f;
381     col.b = tex->col.b * f;
382 
383     return col;
384 }
385 
InitTextures(void)386 void InitTextures(void) {
387     InitNoise();
388     ResetImages();
389 }
390