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 * api.cpp - This file contains all of the API calls that are defined for
48 * external driver code to use.
49 */
50
51 #include "machine.hpp"
52 #include "types.hpp"
53 #include "api.hpp"
54 #include "macros.hpp"
55 #include "vector.hpp"
56
57 #define MyVNorm(a) VNorm((vector *)a)
58
rt_polycylinder(void * tex,vector * points,int numpts,apiflt rad)59 void rt_polycylinder(void *tex, vector *points, int numpts, apiflt rad) {
60 vector a;
61 int i;
62
63 if ((points == nullptr) || (numpts == 0)) {
64 return;
65 }
66
67 if (numpts > 0) {
68 rt_sphere(tex, points[0], rad);
69
70 if (numpts > 1) {
71 for (i = 1; i < numpts; i++) {
72 a.x = points[i].x - points[i - 1].x;
73 a.y = points[i].y - points[i - 1].y;
74 a.z = points[i].z - points[i - 1].z;
75
76 rt_fcylinder(tex, points[i - 1], a, rad);
77 rt_sphere(tex, points[i], rad);
78 }
79 }
80 }
81 }
82
rt_heightfield(void * tex,vector ctr,int m,int n,apiflt * field,apiflt wx,apiflt wy)83 void rt_heightfield(void *tex, vector ctr, int m, int n, apiflt *field, apiflt wx, apiflt wy) {
84 int xx, yy;
85 vector v0, v1, v2;
86 apiflt xoff, yoff, zoff;
87
88 xoff = ctr.x - (wx / 2.0);
89 yoff = ctr.z - (wy / 2.0);
90 zoff = ctr.y;
91
92 for (yy = 0; yy < (n - 1); yy++) {
93 for (xx = 0; xx < (m - 1); xx++) {
94 v0.x = wx * (xx) / (m * 1.0) + xoff;
95 v0.y = field[(yy)*m + (xx)] + zoff;
96 v0.z = wy * (yy) / (n * 1.0) + yoff;
97
98 v1.x = wx * (xx + 1) / (m * 1.0) + xoff;
99 v1.y = field[(yy)*m + (xx + 1)] + zoff;
100 v1.z = wy * (yy) / (n * 1.0) + yoff;
101
102 v2.x = wx * (xx + 1) / (m * 1.0) + xoff;
103 v2.y = field[(yy + 1) * m + (xx + 1)] + zoff;
104 v2.z = wy * (yy + 1) / (n * 1.0) + yoff;
105
106 rt_tri(tex, v1, v0, v2);
107
108 v0.x = wx * (xx) / (m * 1.0) + xoff;
109 v0.y = field[(yy)*m + (xx)] + zoff;
110 v0.z = wy * (yy) / (n * 1.0) + yoff;
111
112 v1.x = wx * (xx) / (m * 1.0) + xoff;
113 v1.y = field[(yy + 1) * m + (xx)] + zoff;
114 v1.z = wy * (yy + 1) / (n * 1.0) + yoff;
115
116 v2.x = wx * (xx + 1) / (m * 1.0) + xoff;
117 v2.y = field[(yy + 1) * m + (xx + 1)] + zoff;
118 v2.z = wy * (yy + 1) / (n * 1.0) + yoff;
119
120 rt_tri(tex, v0, v1, v2);
121 }
122 }
123 } /* end of heightfield */
124
125 static void
rt_sheightfield(void * tex,vector ctr,int m,int n,apiflt * field,apiflt wx,apiflt wy)126 rt_sheightfield(void *tex, vector ctr, int m, int n, apiflt *field, apiflt wx, apiflt wy) {
127 vector *vertices;
128 vector *normals;
129 vector offset;
130 apiflt xinc, yinc;
131 int x, y, addr;
132
133 vertices = (vector *)malloc(m * n * sizeof(vector));
134 normals = (vector *)malloc(m * n * sizeof(vector));
135
136 offset.x = ctr.x - (wx / 2.0);
137 offset.y = ctr.z - (wy / 2.0);
138 offset.z = ctr.y;
139
140 xinc = wx / ((apiflt)m);
141 yinc = wy / ((apiflt)n);
142
143 /* build vertex list */
144 for (y = 0; y < n; y++) {
145 for (x = 0; x < m; x++) {
146 addr = y * m + x;
147 vertices[addr] =
148 rt_vector(x * xinc + offset.x, field[addr] + offset.z, y * yinc + offset.y);
149 }
150 }
151
152 /* build normals from vertex list */
153 for (x = 1; x < m; x++) {
154 normals[x] = normals[(n - 1) * m + x] = rt_vector(0.0, 1.0, 0.0);
155 }
156 for (y = 1; y < n; y++) {
157 normals[y * m] = normals[y * m + (m - 1)] = rt_vector(0.0, 1.0, 0.0);
158 }
159 for (y = 1; y < (n - 1); y++) {
160 for (x = 1; x < (m - 1); x++) {
161 addr = y * m + x;
162
163 normals[addr] = rt_vector(-(field[addr + 1] - field[addr - 1]) / (2.0 * xinc),
164 1.0,
165 -(field[addr + m] - field[addr - m]) / (2.0 * yinc));
166
167 MyVNorm(&normals[addr]);
168 }
169 }
170
171 /* generate actual triangles */
172 for (y = 0; y < (n - 1); y++) {
173 for (x = 0; x < (m - 1); x++) {
174 addr = y * m + x;
175
176 rt_stri(tex,
177 vertices[addr],
178 vertices[addr + 1 + m],
179 vertices[addr + 1],
180 normals[addr],
181 normals[addr + 1 + m],
182 normals[addr + 1]);
183 rt_stri(tex,
184 vertices[addr],
185 vertices[addr + m],
186 vertices[addr + 1 + m],
187 normals[addr],
188 normals[addr + m],
189 normals[addr + 1 + m]);
190 }
191 }
192
193 free(normals);
194 free(vertices);
195 } /* end of smoothed heightfield */
196
adjust(apiflt * base,int xres,int yres,apiflt wx,apiflt wy,int xa,int ya,int x,int y,int xb,int yb)197 static void adjust(apiflt *base,
198 int xres,
199 int yres,
200 apiflt wx,
201 apiflt wy,
202 int xa,
203 int ya,
204 int x,
205 int y,
206 int xb,
207 int yb) {
208 apiflt d, v;
209
210 if (base[x + (xres * y)] == 0.0) {
211 d = (abs(xa - xb) / (xres * 1.0)) * wx + (abs(ya - yb) / (yres * 1.0)) * wy;
212
213 v = (base[xa + (xres * ya)] + base[xb + (xres * yb)]) / 2.0 +
214 (((((rand() % 1000) - 500.0) / 500.0) * d) / 8.0);
215
216 if (v < 0.0)
217 v = 0.0;
218 if (v > (xres + yres))
219 v = (xres + yres);
220 base[x + (xres * y)] = v;
221 }
222 }
223
224 static void
subdivide(apiflt * base,int xres,int yres,apiflt wx,apiflt wy,int x1,int y1,int x2,int y2)225 subdivide(apiflt *base, int xres, int yres, apiflt wx, apiflt wy, int x1, int y1, int x2, int y2) {
226 long x, y;
227
228 if (((x2 - x1) < 2) && ((y2 - y1) < 2)) {
229 return;
230 }
231
232 x = (x1 + x2) / 2;
233 y = (y1 + y2) / 2;
234
235 adjust(base, xres, yres, wx, wy, x1, y1, x, y1, x2, y1);
236 adjust(base, xres, yres, wx, wy, x2, y1, x2, y, x2, y2);
237 adjust(base, xres, yres, wx, wy, x1, y2, x, y2, x2, y2);
238 adjust(base, xres, yres, wx, wy, x1, y1, x1, y, x1, y2);
239
240 if (base[x + xres * y] == 0.0) {
241 base[x + (xres * y)] = (base[x1 + xres * y1] + base[x2 + xres * y1] + base[x2 + xres * y2] +
242 base[x1 + xres * y2]) /
243 4.0;
244 }
245
246 subdivide(base, xres, yres, wx, wy, x1, y1, x, y);
247 subdivide(base, xres, yres, wx, wy, x, y1, x2, y);
248 subdivide(base, xres, yres, wx, wy, x, y, x2, y2);
249 subdivide(base, xres, yres, wx, wy, x1, y, x, y2);
250 }
251
rt_landscape(void * tex,int m,int n,vector ctr,apiflt wx,apiflt wy)252 void rt_landscape(void *tex, int m, int n, vector ctr, apiflt wx, apiflt wy) {
253 int totalsize, x, y;
254 apiflt *field;
255
256 totalsize = m * n;
257
258 srand(totalsize);
259
260 field = (apiflt *)malloc(totalsize * sizeof(apiflt));
261
262 for (y = 0; y < n; y++) {
263 for (x = 0; x < m; x++) {
264 field[x + y * m] = 0.0;
265 }
266 }
267
268 field[0 + 0] = 1.0 + (rand() % 100) / 100.0;
269 field[m - 1] = 1.0 + (rand() % 100) / 100.0;
270 field[0 + m * (n - 1)] = 1.0 + (rand() % 100) / 100.0;
271 field[m - 1 + m * (n - 1)] = 1.0 + (rand() % 100) / 100.0;
272
273 subdivide(field, m, n, wx, wy, 0, 0, m - 1, n - 1);
274
275 rt_sheightfield(tex, ctr, m, n, field, wx, wy);
276
277 free(field);
278 }
279