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