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