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 "macros.hpp" 54 55 #include "box.hpp" 56 #include "cylinder.hpp" 57 #include "plane.hpp" 58 #include "quadric.hpp" 59 #include "ring.hpp" 60 #include "sphere.hpp" 61 #include "triangle.hpp" 62 #include "vol.hpp" 63 #include "extvol.hpp" 64 65 #include "texture.hpp" 66 #include "light.hpp" 67 #include "render.hpp" 68 #include "camera.hpp" 69 #include "vector.hpp" 70 #include "intersect.hpp" 71 #include "shade.hpp" 72 #include "util.hpp" 73 #include "imap.hpp" 74 #include "global.hpp" 75 76 #include "tachyon_video.hpp" 77 78 typedef void *SceneHandle; 79 #include "api.hpp" 80 81 vector rt_vector(apiflt x, apiflt y, apiflt z) { 82 vector v; 83 84 v.x = x; 85 v.y = y; 86 v.z = z; 87 88 return v; 89 } 90 91 color rt_color(apiflt r, apiflt g, apiflt b) { 92 color c; 93 94 c.r = r; 95 c.g = g; 96 c.b = b; 97 98 return c; 99 } 100 101 void rt_initialize() { 102 rpcmsg msg; 103 104 reset_object(); 105 reset_lights(); 106 InitTextures(); 107 108 if (!parinitted) { 109 parinitted = 1; 110 111 msg.type = 1; /* setup a ping message */ 112 } 113 } 114 115 void rt_renderscene(SceneHandle voidscene) { 116 scenedef *scene = (scenedef *)voidscene; 117 renderscene(*scene); 118 } 119 120 void rt_camerasetup(SceneHandle voidscene, 121 apiflt zoom, 122 apiflt aspectratio, 123 int antialiasing, 124 int raydepth, 125 vector camcent, 126 vector viewvec, 127 vector upvec) { 128 scenedef *scene = (scenedef *)voidscene; 129 130 vector newupvec; 131 vector newviewvec; 132 vector newrightvec; 133 134 VCross((vector *)&upvec, &viewvec, &newrightvec); 135 VNorm(&newrightvec); 136 137 VCross((vector *)&viewvec, &newrightvec, &newupvec); 138 VNorm(&newupvec); 139 140 newviewvec = viewvec; 141 VNorm(&newviewvec); 142 143 scene->camzoom = zoom; 144 scene->aspectratio = aspectratio; 145 scene->antialiasing = antialiasing; 146 scene->raydepth = raydepth; 147 scene->camcent = camcent; 148 scene->camviewvec = newviewvec; 149 scene->camrightvec = newrightvec; 150 scene->camupvec = newupvec; 151 } 152 153 void rt_outputfile(SceneHandle voidscene, const char *outname) { 154 scenedef *scene = (scenedef *)voidscene; 155 strcpy((char *)&scene->outfilename, outname); 156 } 157 158 void rt_resolution(SceneHandle voidscene, int hres, int vres) { 159 scenedef *scene = (scenedef *)voidscene; 160 scene->hres = hres; 161 scene->vres = vres; 162 } 163 164 void rt_verbose(SceneHandle voidscene, int v) { 165 scenedef *scene = (scenedef *)voidscene; 166 scene->verbosemode = v; 167 } 168 169 void rt_rawimage(SceneHandle voidscene, unsigned char *rawimage) { 170 scenedef *scene = (scenedef *)voidscene; 171 scene->rawimage = rawimage; 172 } 173 174 void rt_background(SceneHandle voidscene, color col) { 175 scenedef *scene = (scenedef *)voidscene; 176 scene->background.r = col.r; 177 scene->background.g = col.g; 178 scene->background.b = col.b; 179 } 180 181 void rt_boundmode(SceneHandle voidscene, int mode) { 182 scenedef *scene = (scenedef *)voidscene; 183 scene->boundmode = mode; 184 } 185 186 void rt_boundthresh(SceneHandle voidscene, int threshold) { 187 scenedef *scene = (scenedef *)voidscene; 188 189 if (threshold > 1) { 190 scene->boundthresh = threshold; 191 } 192 else { 193 rtmesg("Ignoring out-of-range automatic bounding threshold.\n"); 194 rtmesg("Automatic bounding threshold reset to default.\n"); 195 scene->boundthresh = MAXOCTNODES; 196 } 197 } 198 199 void rt_displaymode(SceneHandle voidscene, int mode) { 200 scenedef *scene = (scenedef *)voidscene; 201 scene->displaymode = mode; 202 } 203 204 void rt_scenesetup(SceneHandle voidscene, char *outname, int hres, int vres, int verbose) { 205 rt_outputfile(voidscene, outname); 206 rt_resolution(voidscene, hres, vres); 207 rt_verbose(voidscene, verbose); 208 } 209 210 SceneHandle rt_newscene(void) { 211 scenedef *scene; 212 SceneHandle voidscene; 213 214 scene = (scenedef *)malloc(sizeof(scenedef)); 215 memset(scene, 0, sizeof(scenedef)); /* clear all valuas to 0 */ 216 217 voidscene = (SceneHandle)scene; 218 219 rt_outputfile(voidscene, "/dev/null"); /* default output file (.tga) */ 220 rt_resolution(voidscene, 512, 512); /* 512x512 resolution */ 221 rt_verbose(voidscene, 0); /* verbose messages off */ 222 rt_rawimage(voidscene, nullptr); /* raw image output off */ 223 rt_boundmode(voidscene, RT_BOUNDING_ENABLED); /* spatial subdivision on */ 224 rt_boundthresh(voidscene, MAXOCTNODES); /* default threshold */ 225 rt_displaymode(voidscene, RT_DISPLAY_ENABLED); /* video output on */ 226 rt_camerasetup(voidscene, 227 1.0, 228 1.0, 229 0, 230 6, 231 rt_vector(0.0, 0.0, 0.0), 232 rt_vector(0.0, 0.0, 1.0), 233 rt_vector(0.0, 1.0, 0.0)); 234 235 return scene; 236 } 237 238 void rt_deletescene(SceneHandle scene) { 239 if (scene != nullptr) 240 free(scene); 241 } 242 243 void apitextotex(apitexture *apitex, texture *tex) { 244 switch (apitex->texturefunc) { 245 case 0: tex->texfunc = (color(*)(void *, void *, void *))(standard_texture); break; 246 247 case 1: tex->texfunc = (color(*)(void *, void *, void *))(checker_texture); break; 248 249 case 2: tex->texfunc = (color(*)(void *, void *, void *))(grit_texture); break; 250 251 case 3: tex->texfunc = (color(*)(void *, void *, void *))(marble_texture); break; 252 253 case 4: tex->texfunc = (color(*)(void *, void *, void *))(wood_texture); break; 254 255 case 5: tex->texfunc = (color(*)(void *, void *, void *))(gnoise_texture); break; 256 257 case 6: tex->texfunc = (color(*)(void *, void *, void *))(cyl_checker_texture); break; 258 259 case 7: 260 tex->texfunc = (color(*)(void *, void *, void *))(image_sphere_texture); 261 tex->img = AllocateImage((char *)apitex->imap); 262 break; 263 264 case 8: 265 tex->texfunc = (color(*)(void *, void *, void *))(image_cyl_texture); 266 tex->img = AllocateImage((char *)apitex->imap); 267 break; 268 269 case 9: 270 tex->texfunc = (color(*)(void *, void *, void *))(image_plane_texture); 271 tex->img = AllocateImage((char *)apitex->imap); 272 break; 273 274 default: tex->texfunc = (color(*)(void *, void *, void *))(standard_texture); break; 275 } 276 277 tex->ctr = apitex->ctr; 278 tex->rot = apitex->rot; 279 tex->scale = apitex->scale; 280 tex->uaxs = apitex->uaxs; 281 tex->vaxs = apitex->vaxs; 282 tex->ambient = apitex->ambient; 283 tex->diffuse = apitex->diffuse; 284 tex->specular = apitex->specular; 285 tex->opacity = apitex->opacity; 286 tex->col = apitex->col; 287 288 tex->islight = 0; 289 tex->shadowcast = 1; 290 tex->phong = 0.0; 291 tex->phongexp = 0.0; 292 tex->phongtype = 0; 293 } 294 295 void *rt_texture(apitexture *apitex) { 296 texture *tex; 297 298 tex = (texture *)rt_getmem(sizeof(texture)); 299 apitextotex(apitex, tex); 300 return (tex); 301 } 302 303 void rt_tex_color(void *voidtex, color col) { 304 texture *tex = (texture *)voidtex; 305 tex->col = col; 306 } 307 308 void rt_tex_phong(void *voidtex, apiflt phong, apiflt phongexp, int type) { 309 texture *tex = (texture *)voidtex; 310 tex->phong = phong; 311 tex->phongexp = phongexp; 312 tex->phongtype = type; 313 } 314 315 void rt_light(void *tex, vector ctr, apiflt rad) { 316 point_light *li; 317 318 li = newlight(tex, (vector)ctr, rad); 319 320 li->tex->islight = 1; 321 li->tex->shadowcast = 1; 322 li->tex->diffuse = 0.0; 323 li->tex->specular = 0.0; 324 li->tex->opacity = 1.0; 325 326 add_light(li); 327 add_object((object *)li); 328 } 329 330 void rt_scalarvol(void *tex, 331 vector min, 332 vector max, 333 int xs, 334 int ys, 335 int zs, 336 char *fname, 337 void *invol) { 338 add_object((object *)newscalarvol( 339 tex, (vector)min, (vector)max, xs, ys, zs, fname, (scalarvol *)invol)); 340 } 341 342 void rt_extvol(void *tex, vector min, vector max, int samples, flt (*evaluator)(flt, flt, flt)) { 343 add_object((object *)newextvol(tex, (vector)min, (vector)max, samples, evaluator)); 344 } 345 346 void rt_box(void *tex, vector min, vector max) { 347 add_object((object *)newbox(tex, (vector)min, (vector)max)); 348 } 349 350 void rt_cylinder(void *tex, vector ctr, vector axis, apiflt rad) { 351 add_object(newcylinder(tex, (vector)ctr, (vector)axis, rad)); 352 } 353 354 void rt_fcylinder(void *tex, vector ctr, vector axis, apiflt rad) { 355 add_object(newfcylinder(tex, (vector)ctr, (vector)axis, rad)); 356 } 357 358 void rt_plane(void *tex, vector ctr, vector norm) { 359 add_object(newplane(tex, (vector)ctr, (vector)norm)); 360 } 361 362 void rt_ring(void *tex, vector ctr, vector norm, apiflt a, apiflt b) { 363 add_object(newring(tex, (vector)ctr, (vector)norm, a, b)); 364 } 365 366 void rt_sphere(void *tex, vector ctr, apiflt rad) { 367 add_object(newsphere(tex, (vector)ctr, rad)); 368 } 369 370 void rt_tri(void *tex, vector v0, vector v1, vector v2) { 371 object *trn; 372 373 trn = newtri(tex, (vector)v0, (vector)v1, (vector)v2); 374 375 if (trn != nullptr) { 376 add_object(trn); 377 } 378 } 379 380 void rt_stri(void *tex, vector v0, vector v1, vector v2, vector n0, vector n1, vector n2) { 381 object *trn; 382 383 trn = newstri(tex, (vector)v0, (vector)v1, (vector)v2, (vector)n0, (vector)n1, (vector)n2); 384 385 if (trn != nullptr) { 386 add_object(trn); 387 } 388 } 389 390 void rt_quadsphere(void *tex, vector ctr, apiflt rad) { 391 quadric *q; 392 flt factor; 393 q = (quadric *)newquadric(); 394 factor = 1.0 / (rad * rad); 395 q->tex = (texture *)tex; 396 q->ctr = ctr; 397 398 q->mat.a = factor; 399 q->mat.b = 0.0; 400 q->mat.c = 0.0; 401 q->mat.d = 0.0; 402 q->mat.e = factor; 403 q->mat.f = 0.0; 404 q->mat.g = 0.0; 405 q->mat.h = factor; 406 q->mat.i = 0.0; 407 q->mat.j = -1.0; 408 409 add_object((object *)q); 410 } 411