1 /*
2 Copyright (c) 2005-2020 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.h"
52 #include "types.h"
53 #include "api.h"
54 #include "macros.h"
55 #include "vector.h"
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 == NULL) || (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,
84 apiflt * field, apiflt wx, apiflt wy) {
85 int xx,yy;
86 vector v0, v1, v2;
87 apiflt xoff, yoff, zoff;
88
89 xoff=ctr.x - (wx / 2.0);
90 yoff=ctr.z - (wy / 2.0);
91 zoff=ctr.y;
92
93 for (yy=0; yy<(n-1); yy++) {
94 for (xx=0; xx<(m-1); xx++) {
95 v0.x=wx*(xx )/(m*1.0) + xoff;
96 v0.y=field[(yy )*m + (xx )] + zoff;
97 v0.z=wy*(yy )/(n*1.0) + yoff;
98
99 v1.x=wx*(xx + 1)/(m*1.0) + xoff;
100 v1.y=field[(yy )*m + (xx + 1)] + zoff;
101 v1.z=wy*(yy )/(n*1.0) + yoff;
102
103 v2.x=wx*(xx + 1)/(m*1.0) + xoff;
104 v2.y=field[(yy + 1)*m + (xx + 1)] + zoff;
105 v2.z=wy*(yy + 1)/(n*1.0) + yoff;
106
107 rt_tri(tex, v1, v0, v2);
108
109 v0.x=wx*(xx )/(m*1.0) + xoff;
110 v0.y=field[(yy )*m + (xx )] + zoff;
111 v0.z=wy*(yy )/(n*1.0) + yoff;
112
113 v1.x=wx*(xx )/(m*1.0) + xoff;
114 v1.y=field[(yy + 1)*m + (xx )] + zoff;
115 v1.z=wy*(yy + 1)/(n*1.0) + yoff;
116
117 v2.x=wx*(xx + 1)/(m*1.0) + xoff;
118 v2.y=field[(yy + 1)*m + (xx + 1)] + zoff;
119 v2.z=wy*(yy + 1)/(n*1.0) + yoff;
120
121 rt_tri(tex, v0, v1, v2);
122 }
123 }
124 } /* end of heightfield */
125
126
rt_sheightfield(void * tex,vector ctr,int m,int n,apiflt * field,apiflt wx,apiflt wy)127 static void rt_sheightfield(void * tex, vector ctr, int m, int n,
128 apiflt * field, apiflt wx, apiflt wy) {
129 vector * vertices;
130 vector * normals;
131 vector offset;
132 apiflt xinc, yinc;
133 int x, y, addr;
134
135 vertices = (vector *) malloc(m*n*sizeof(vector));
136 normals = (vector *) malloc(m*n*sizeof(vector));
137
138 offset.x = ctr.x - (wx / 2.0);
139 offset.y = ctr.z - (wy / 2.0);
140 offset.z = ctr.y;
141
142 xinc = wx / ((apiflt) m);
143 yinc = wy / ((apiflt) n);
144
145 /* build vertex list */
146 for (y=0; y<n; y++) {
147 for (x=0; x<m; x++) {
148 addr = y*m + x;
149 vertices[addr] = rt_vector(
150 x * xinc + offset.x,
151 field[addr] + offset.z,
152 y * yinc + offset.y);
153 }
154 }
155
156 /* build normals from vertex list */
157 for (x=1; x<m; x++) {
158 normals[x] = normals[(n - 1)*m + x] = rt_vector(0.0, 1.0, 0.0);
159 }
160 for (y=1; y<n; y++) {
161 normals[y*m] = normals[y*m + (m-1)] = rt_vector(0.0, 1.0, 0.0);
162 }
163 for (y=1; y<(n-1); y++) {
164 for (x=1; x<(m-1); x++) {
165 addr = y*m + x;
166
167 normals[addr] = rt_vector(
168 -(field[addr + 1] - field[addr - 1]) / (2.0 * xinc),
169 1.0,
170 -(field[addr + m] - field[addr - m]) / (2.0 * yinc));
171
172 MyVNorm(&normals[addr]);
173 }
174 }
175
176 /* generate actual triangles */
177 for (y=0; y<(n-1); y++) {
178 for (x=0; x<(m-1); x++) {
179 addr = y*m + x;
180
181 rt_stri(tex, vertices[addr], vertices[addr + 1 + m], vertices[addr + 1],
182 normals[addr], normals[addr + 1 + m], normals[addr + 1]);
183 rt_stri(tex, vertices[addr], vertices[addr + m], vertices[addr + 1 + m],
184 normals[addr], normals[addr + m], normals[addr + 1 + m]);
185 }
186 }
187
188 free(normals);
189 free(vertices);
190 } /* end of smoothed heightfield */
191
192
adjust(apiflt * base,int xres,int yres,apiflt wx,apiflt wy,int xa,int ya,int x,int y,int xb,int yb)193 static void adjust(apiflt *base, int xres, int yres, apiflt wx, apiflt wy,
194 int xa, int ya, int x, int y, int xb, int yb) {
195 apiflt d, v;
196
197 if (base[x + (xres*y)]==0.0) {
198
199 d=(abs(xa - xb) / (xres * 1.0))*wx + (abs(ya - yb) / (yres * 1.0))*wy;
200
201 v=(base[xa + (xres*ya)] + base[xb + (xres*yb)]) / 2.0 +
202 (((((rand() % 1000) - 500.0)/500.0)*d) / 8.0);
203
204 if (v < 0.0) v=0.0;
205 if (v > (xres + yres)) v=(xres + yres);
206 base[x + (xres * y)]=v;
207 }
208 }
209
subdivide(apiflt * base,int xres,int yres,apiflt wx,apiflt wy,int x1,int y1,int x2,int y2)210 static void subdivide(apiflt *base, int xres, int yres, apiflt wx, apiflt wy,
211 int x1, int y1, int x2, int y2) {
212 long x,y;
213
214 if (((x2 - x1) < 2) && ((y2 - y1) < 2)) { return; }
215
216 x=(x1 + x2) / 2;
217 y=(y1 + y2) / 2;
218
219 adjust(base, xres, yres, wx, wy, x1, y1, x, y1, x2, y1);
220 adjust(base, xres, yres, wx, wy, x2, y1, x2, y, x2, y2);
221 adjust(base, xres, yres, wx, wy, x1, y2, x, y2, x2, y2);
222 adjust(base, xres, yres, wx, wy, x1, y1, x1, y, x1, y2);
223
224
225 if (base[x + xres*y]==0.0) {
226 base[x + (xres * y)]=(base[x1 + xres*y1] + base[x2 + xres*y1] +
227 base[x2 + xres*y2] + base[x1 + xres*y2] )/4.0;
228 }
229
230 subdivide(base, xres, yres, wx, wy, x1, y1 ,x ,y);
231 subdivide(base, xres, yres, wx, wy, x, y1, x2, y);
232 subdivide(base, xres, yres, wx, wy, x, y, x2, y2);
233 subdivide(base, xres, yres, wx, wy, x1, y, x, y2);
234 }
235
rt_landscape(void * tex,int m,int n,vector ctr,apiflt wx,apiflt wy)236 void rt_landscape(void * tex, int m, int n,
237 vector ctr, apiflt wx, apiflt wy) {
238 int totalsize, x, y;
239 apiflt * field;
240
241 totalsize=m*n;
242
243 srand(totalsize);
244
245 field=(apiflt *) malloc(totalsize*sizeof(apiflt));
246
247 for (y=0; y<n; y++) {
248 for (x=0; x<m; x++) {
249 field[x + y*m]=0.0;
250 }
251 }
252
253 field[0 + 0]=1.0 + (rand() % 100)/100.0;
254 field[m - 1]=1.0 + (rand() % 100)/100.0;
255 field[0 + m*(n - 1)]=1.0 + (rand() % 100)/100.0;
256 field[m - 1 + m*(n - 1)]=1.0 + (rand() % 100)/100.0;
257
258 subdivide(field, m, n, wx, wy, 0, 0, m-1, n-1);
259
260 rt_sheightfield(tex, ctr, m, n, field, wx, wy);
261
262 free(field);
263 }
264
265