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.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 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 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 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 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 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 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