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
rt_vector(apiflt x,apiflt y,apiflt z)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
rt_color(apiflt r,apiflt g,apiflt b)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
rt_initialize()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
rt_renderscene(SceneHandle voidscene)115 void rt_renderscene(SceneHandle voidscene) {
116 scenedef *scene = (scenedef *)voidscene;
117 renderscene(*scene);
118 }
119
rt_camerasetup(SceneHandle voidscene,apiflt zoom,apiflt aspectratio,int antialiasing,int raydepth,vector camcent,vector viewvec,vector upvec)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
rt_outputfile(SceneHandle voidscene,const char * outname)153 void rt_outputfile(SceneHandle voidscene, const char *outname) {
154 scenedef *scene = (scenedef *)voidscene;
155 strcpy((char *)&scene->outfilename, outname);
156 }
157
rt_resolution(SceneHandle voidscene,int hres,int vres)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
rt_verbose(SceneHandle voidscene,int v)164 void rt_verbose(SceneHandle voidscene, int v) {
165 scenedef *scene = (scenedef *)voidscene;
166 scene->verbosemode = v;
167 }
168
rt_rawimage(SceneHandle voidscene,unsigned char * rawimage)169 void rt_rawimage(SceneHandle voidscene, unsigned char *rawimage) {
170 scenedef *scene = (scenedef *)voidscene;
171 scene->rawimage = rawimage;
172 }
173
rt_background(SceneHandle voidscene,color col)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
rt_boundmode(SceneHandle voidscene,int mode)181 void rt_boundmode(SceneHandle voidscene, int mode) {
182 scenedef *scene = (scenedef *)voidscene;
183 scene->boundmode = mode;
184 }
185
rt_boundthresh(SceneHandle voidscene,int threshold)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
rt_displaymode(SceneHandle voidscene,int mode)199 void rt_displaymode(SceneHandle voidscene, int mode) {
200 scenedef *scene = (scenedef *)voidscene;
201 scene->displaymode = mode;
202 }
203
rt_scenesetup(SceneHandle voidscene,char * outname,int hres,int vres,int verbose)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
rt_newscene(void)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
rt_deletescene(SceneHandle scene)238 void rt_deletescene(SceneHandle scene) {
239 if (scene != nullptr)
240 free(scene);
241 }
242
apitextotex(apitexture * apitex,texture * tex)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
rt_texture(apitexture * apitex)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
rt_tex_color(void * voidtex,color col)303 void rt_tex_color(void *voidtex, color col) {
304 texture *tex = (texture *)voidtex;
305 tex->col = col;
306 }
307
rt_tex_phong(void * voidtex,apiflt phong,apiflt phongexp,int type)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
rt_light(void * tex,vector ctr,apiflt rad)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
rt_scalarvol(void * tex,vector min,vector max,int xs,int ys,int zs,char * fname,void * invol)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
rt_extvol(void * tex,vector min,vector max,int samples,flt (* evaluator)(flt,flt,flt))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
rt_box(void * tex,vector min,vector max)346 void rt_box(void *tex, vector min, vector max) {
347 add_object((object *)newbox(tex, (vector)min, (vector)max));
348 }
349
rt_cylinder(void * tex,vector ctr,vector axis,apiflt rad)350 void rt_cylinder(void *tex, vector ctr, vector axis, apiflt rad) {
351 add_object(newcylinder(tex, (vector)ctr, (vector)axis, rad));
352 }
353
rt_fcylinder(void * tex,vector ctr,vector axis,apiflt rad)354 void rt_fcylinder(void *tex, vector ctr, vector axis, apiflt rad) {
355 add_object(newfcylinder(tex, (vector)ctr, (vector)axis, rad));
356 }
357
rt_plane(void * tex,vector ctr,vector norm)358 void rt_plane(void *tex, vector ctr, vector norm) {
359 add_object(newplane(tex, (vector)ctr, (vector)norm));
360 }
361
rt_ring(void * tex,vector ctr,vector norm,apiflt a,apiflt b)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
rt_sphere(void * tex,vector ctr,apiflt rad)366 void rt_sphere(void *tex, vector ctr, apiflt rad) {
367 add_object(newsphere(tex, (vector)ctr, rad));
368 }
369
rt_tri(void * tex,vector v0,vector v1,vector v2)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
rt_stri(void * tex,vector v0,vector v1,vector v2,vector n0,vector n1,vector n2)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
rt_quadsphere(void * tex,vector ctr,apiflt rad)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