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