1*d86ed7fbStbbdev /*
2*d86ed7fbStbbdev     Copyright (c) 2005-2020 Intel Corporation
3*d86ed7fbStbbdev 
4*d86ed7fbStbbdev     Licensed under the Apache License, Version 2.0 (the "License");
5*d86ed7fbStbbdev     you may not use this file except in compliance with the License.
6*d86ed7fbStbbdev     You may obtain a copy of the License at
7*d86ed7fbStbbdev 
8*d86ed7fbStbbdev         http://www.apache.org/licenses/LICENSE-2.0
9*d86ed7fbStbbdev 
10*d86ed7fbStbbdev     Unless required by applicable law or agreed to in writing, software
11*d86ed7fbStbbdev     distributed under the License is distributed on an "AS IS" BASIS,
12*d86ed7fbStbbdev     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*d86ed7fbStbbdev     See the License for the specific language governing permissions and
14*d86ed7fbStbbdev     limitations under the License.
15*d86ed7fbStbbdev */
16*d86ed7fbStbbdev 
17*d86ed7fbStbbdev /*
18*d86ed7fbStbbdev     The original source for this example is
19*d86ed7fbStbbdev     Copyright (c) 1994-2008 John E. Stone
20*d86ed7fbStbbdev     All rights reserved.
21*d86ed7fbStbbdev 
22*d86ed7fbStbbdev     Redistribution and use in source and binary forms, with or without
23*d86ed7fbStbbdev     modification, are permitted provided that the following conditions
24*d86ed7fbStbbdev     are met:
25*d86ed7fbStbbdev     1. Redistributions of source code must retain the above copyright
26*d86ed7fbStbbdev        notice, this list of conditions and the following disclaimer.
27*d86ed7fbStbbdev     2. Redistributions in binary form must reproduce the above copyright
28*d86ed7fbStbbdev        notice, this list of conditions and the following disclaimer in the
29*d86ed7fbStbbdev        documentation and/or other materials provided with the distribution.
30*d86ed7fbStbbdev     3. The name of the author may not be used to endorse or promote products
31*d86ed7fbStbbdev        derived from this software without specific prior written permission.
32*d86ed7fbStbbdev 
33*d86ed7fbStbbdev     THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
34*d86ed7fbStbbdev     OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
35*d86ed7fbStbbdev     WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
36*d86ed7fbStbbdev     ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
37*d86ed7fbStbbdev     DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
38*d86ed7fbStbbdev     DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
39*d86ed7fbStbbdev     OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
40*d86ed7fbStbbdev     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
41*d86ed7fbStbbdev     LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
42*d86ed7fbStbbdev     OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
43*d86ed7fbStbbdev     SUCH DAMAGE.
44*d86ed7fbStbbdev */
45*d86ed7fbStbbdev 
46*d86ed7fbStbbdev /*
47*d86ed7fbStbbdev  * api.cpp - This file contains all of the API calls that are defined for
48*d86ed7fbStbbdev  *         external driver code to use.
49*d86ed7fbStbbdev  */
50*d86ed7fbStbbdev 
51*d86ed7fbStbbdev #include "machine.hpp"
52*d86ed7fbStbbdev #include "types.hpp"
53*d86ed7fbStbbdev #include "macros.hpp"
54*d86ed7fbStbbdev 
55*d86ed7fbStbbdev #include "box.hpp"
56*d86ed7fbStbbdev #include "cylinder.hpp"
57*d86ed7fbStbbdev #include "plane.hpp"
58*d86ed7fbStbbdev #include "quadric.hpp"
59*d86ed7fbStbbdev #include "ring.hpp"
60*d86ed7fbStbbdev #include "sphere.hpp"
61*d86ed7fbStbbdev #include "triangle.hpp"
62*d86ed7fbStbbdev #include "vol.hpp"
63*d86ed7fbStbbdev #include "extvol.hpp"
64*d86ed7fbStbbdev 
65*d86ed7fbStbbdev #include "texture.hpp"
66*d86ed7fbStbbdev #include "light.hpp"
67*d86ed7fbStbbdev #include "render.hpp"
68*d86ed7fbStbbdev #include "camera.hpp"
69*d86ed7fbStbbdev #include "vector.hpp"
70*d86ed7fbStbbdev #include "intersect.hpp"
71*d86ed7fbStbbdev #include "shade.hpp"
72*d86ed7fbStbbdev #include "util.hpp"
73*d86ed7fbStbbdev #include "imap.hpp"
74*d86ed7fbStbbdev #include "global.hpp"
75*d86ed7fbStbbdev 
76*d86ed7fbStbbdev #include "tachyon_video.hpp"
77*d86ed7fbStbbdev 
78*d86ed7fbStbbdev typedef void *SceneHandle;
79*d86ed7fbStbbdev #include "api.hpp"
80*d86ed7fbStbbdev 
81*d86ed7fbStbbdev vector rt_vector(apiflt x, apiflt y, apiflt z) {
82*d86ed7fbStbbdev     vector v;
83*d86ed7fbStbbdev 
84*d86ed7fbStbbdev     v.x = x;
85*d86ed7fbStbbdev     v.y = y;
86*d86ed7fbStbbdev     v.z = z;
87*d86ed7fbStbbdev 
88*d86ed7fbStbbdev     return v;
89*d86ed7fbStbbdev }
90*d86ed7fbStbbdev 
91*d86ed7fbStbbdev color rt_color(apiflt r, apiflt g, apiflt b) {
92*d86ed7fbStbbdev     color c;
93*d86ed7fbStbbdev 
94*d86ed7fbStbbdev     c.r = r;
95*d86ed7fbStbbdev     c.g = g;
96*d86ed7fbStbbdev     c.b = b;
97*d86ed7fbStbbdev 
98*d86ed7fbStbbdev     return c;
99*d86ed7fbStbbdev }
100*d86ed7fbStbbdev 
101*d86ed7fbStbbdev void rt_initialize() {
102*d86ed7fbStbbdev     rpcmsg msg;
103*d86ed7fbStbbdev 
104*d86ed7fbStbbdev     reset_object();
105*d86ed7fbStbbdev     reset_lights();
106*d86ed7fbStbbdev     InitTextures();
107*d86ed7fbStbbdev 
108*d86ed7fbStbbdev     if (!parinitted) {
109*d86ed7fbStbbdev         parinitted = 1;
110*d86ed7fbStbbdev 
111*d86ed7fbStbbdev         msg.type = 1; /* setup a ping message */
112*d86ed7fbStbbdev     }
113*d86ed7fbStbbdev }
114*d86ed7fbStbbdev 
115*d86ed7fbStbbdev void rt_renderscene(SceneHandle voidscene) {
116*d86ed7fbStbbdev     scenedef *scene = (scenedef *)voidscene;
117*d86ed7fbStbbdev     renderscene(*scene);
118*d86ed7fbStbbdev }
119*d86ed7fbStbbdev 
120*d86ed7fbStbbdev void rt_camerasetup(SceneHandle voidscene,
121*d86ed7fbStbbdev                     apiflt zoom,
122*d86ed7fbStbbdev                     apiflt aspectratio,
123*d86ed7fbStbbdev                     int antialiasing,
124*d86ed7fbStbbdev                     int raydepth,
125*d86ed7fbStbbdev                     vector camcent,
126*d86ed7fbStbbdev                     vector viewvec,
127*d86ed7fbStbbdev                     vector upvec) {
128*d86ed7fbStbbdev     scenedef *scene = (scenedef *)voidscene;
129*d86ed7fbStbbdev 
130*d86ed7fbStbbdev     vector newupvec;
131*d86ed7fbStbbdev     vector newviewvec;
132*d86ed7fbStbbdev     vector newrightvec;
133*d86ed7fbStbbdev 
134*d86ed7fbStbbdev     VCross((vector *)&upvec, &viewvec, &newrightvec);
135*d86ed7fbStbbdev     VNorm(&newrightvec);
136*d86ed7fbStbbdev 
137*d86ed7fbStbbdev     VCross((vector *)&viewvec, &newrightvec, &newupvec);
138*d86ed7fbStbbdev     VNorm(&newupvec);
139*d86ed7fbStbbdev 
140*d86ed7fbStbbdev     newviewvec = viewvec;
141*d86ed7fbStbbdev     VNorm(&newviewvec);
142*d86ed7fbStbbdev 
143*d86ed7fbStbbdev     scene->camzoom = zoom;
144*d86ed7fbStbbdev     scene->aspectratio = aspectratio;
145*d86ed7fbStbbdev     scene->antialiasing = antialiasing;
146*d86ed7fbStbbdev     scene->raydepth = raydepth;
147*d86ed7fbStbbdev     scene->camcent = camcent;
148*d86ed7fbStbbdev     scene->camviewvec = newviewvec;
149*d86ed7fbStbbdev     scene->camrightvec = newrightvec;
150*d86ed7fbStbbdev     scene->camupvec = newupvec;
151*d86ed7fbStbbdev }
152*d86ed7fbStbbdev 
153*d86ed7fbStbbdev void rt_outputfile(SceneHandle voidscene, const char *outname) {
154*d86ed7fbStbbdev     scenedef *scene = (scenedef *)voidscene;
155*d86ed7fbStbbdev     strcpy((char *)&scene->outfilename, outname);
156*d86ed7fbStbbdev }
157*d86ed7fbStbbdev 
158*d86ed7fbStbbdev void rt_resolution(SceneHandle voidscene, int hres, int vres) {
159*d86ed7fbStbbdev     scenedef *scene = (scenedef *)voidscene;
160*d86ed7fbStbbdev     scene->hres = hres;
161*d86ed7fbStbbdev     scene->vres = vres;
162*d86ed7fbStbbdev }
163*d86ed7fbStbbdev 
164*d86ed7fbStbbdev void rt_verbose(SceneHandle voidscene, int v) {
165*d86ed7fbStbbdev     scenedef *scene = (scenedef *)voidscene;
166*d86ed7fbStbbdev     scene->verbosemode = v;
167*d86ed7fbStbbdev }
168*d86ed7fbStbbdev 
169*d86ed7fbStbbdev void rt_rawimage(SceneHandle voidscene, unsigned char *rawimage) {
170*d86ed7fbStbbdev     scenedef *scene = (scenedef *)voidscene;
171*d86ed7fbStbbdev     scene->rawimage = rawimage;
172*d86ed7fbStbbdev }
173*d86ed7fbStbbdev 
174*d86ed7fbStbbdev void rt_background(SceneHandle voidscene, color col) {
175*d86ed7fbStbbdev     scenedef *scene = (scenedef *)voidscene;
176*d86ed7fbStbbdev     scene->background.r = col.r;
177*d86ed7fbStbbdev     scene->background.g = col.g;
178*d86ed7fbStbbdev     scene->background.b = col.b;
179*d86ed7fbStbbdev }
180*d86ed7fbStbbdev 
181*d86ed7fbStbbdev void rt_boundmode(SceneHandle voidscene, int mode) {
182*d86ed7fbStbbdev     scenedef *scene = (scenedef *)voidscene;
183*d86ed7fbStbbdev     scene->boundmode = mode;
184*d86ed7fbStbbdev }
185*d86ed7fbStbbdev 
186*d86ed7fbStbbdev void rt_boundthresh(SceneHandle voidscene, int threshold) {
187*d86ed7fbStbbdev     scenedef *scene = (scenedef *)voidscene;
188*d86ed7fbStbbdev 
189*d86ed7fbStbbdev     if (threshold > 1) {
190*d86ed7fbStbbdev         scene->boundthresh = threshold;
191*d86ed7fbStbbdev     }
192*d86ed7fbStbbdev     else {
193*d86ed7fbStbbdev         rtmesg("Ignoring out-of-range automatic bounding threshold.\n");
194*d86ed7fbStbbdev         rtmesg("Automatic bounding threshold reset to default.\n");
195*d86ed7fbStbbdev         scene->boundthresh = MAXOCTNODES;
196*d86ed7fbStbbdev     }
197*d86ed7fbStbbdev }
198*d86ed7fbStbbdev 
199*d86ed7fbStbbdev void rt_displaymode(SceneHandle voidscene, int mode) {
200*d86ed7fbStbbdev     scenedef *scene = (scenedef *)voidscene;
201*d86ed7fbStbbdev     scene->displaymode = mode;
202*d86ed7fbStbbdev }
203*d86ed7fbStbbdev 
204*d86ed7fbStbbdev void rt_scenesetup(SceneHandle voidscene, char *outname, int hres, int vres, int verbose) {
205*d86ed7fbStbbdev     rt_outputfile(voidscene, outname);
206*d86ed7fbStbbdev     rt_resolution(voidscene, hres, vres);
207*d86ed7fbStbbdev     rt_verbose(voidscene, verbose);
208*d86ed7fbStbbdev }
209*d86ed7fbStbbdev 
210*d86ed7fbStbbdev SceneHandle rt_newscene(void) {
211*d86ed7fbStbbdev     scenedef *scene;
212*d86ed7fbStbbdev     SceneHandle voidscene;
213*d86ed7fbStbbdev 
214*d86ed7fbStbbdev     scene = (scenedef *)malloc(sizeof(scenedef));
215*d86ed7fbStbbdev     memset(scene, 0, sizeof(scenedef)); /* clear all valuas to 0  */
216*d86ed7fbStbbdev 
217*d86ed7fbStbbdev     voidscene = (SceneHandle)scene;
218*d86ed7fbStbbdev 
219*d86ed7fbStbbdev     rt_outputfile(voidscene, "/dev/null"); /* default output file (.tga) */
220*d86ed7fbStbbdev     rt_resolution(voidscene, 512, 512); /* 512x512 resolution */
221*d86ed7fbStbbdev     rt_verbose(voidscene, 0); /* verbose messages off */
222*d86ed7fbStbbdev     rt_rawimage(voidscene, nullptr); /* raw image output off */
223*d86ed7fbStbbdev     rt_boundmode(voidscene, RT_BOUNDING_ENABLED); /* spatial subdivision on */
224*d86ed7fbStbbdev     rt_boundthresh(voidscene, MAXOCTNODES); /* default threshold */
225*d86ed7fbStbbdev     rt_displaymode(voidscene, RT_DISPLAY_ENABLED); /* video output on */
226*d86ed7fbStbbdev     rt_camerasetup(voidscene,
227*d86ed7fbStbbdev                    1.0,
228*d86ed7fbStbbdev                    1.0,
229*d86ed7fbStbbdev                    0,
230*d86ed7fbStbbdev                    6,
231*d86ed7fbStbbdev                    rt_vector(0.0, 0.0, 0.0),
232*d86ed7fbStbbdev                    rt_vector(0.0, 0.0, 1.0),
233*d86ed7fbStbbdev                    rt_vector(0.0, 1.0, 0.0));
234*d86ed7fbStbbdev 
235*d86ed7fbStbbdev     return scene;
236*d86ed7fbStbbdev }
237*d86ed7fbStbbdev 
238*d86ed7fbStbbdev void rt_deletescene(SceneHandle scene) {
239*d86ed7fbStbbdev     if (scene != nullptr)
240*d86ed7fbStbbdev         free(scene);
241*d86ed7fbStbbdev }
242*d86ed7fbStbbdev 
243*d86ed7fbStbbdev void apitextotex(apitexture *apitex, texture *tex) {
244*d86ed7fbStbbdev     switch (apitex->texturefunc) {
245*d86ed7fbStbbdev         case 0: tex->texfunc = (color(*)(void *, void *, void *))(standard_texture); break;
246*d86ed7fbStbbdev 
247*d86ed7fbStbbdev         case 1: tex->texfunc = (color(*)(void *, void *, void *))(checker_texture); break;
248*d86ed7fbStbbdev 
249*d86ed7fbStbbdev         case 2: tex->texfunc = (color(*)(void *, void *, void *))(grit_texture); break;
250*d86ed7fbStbbdev 
251*d86ed7fbStbbdev         case 3: tex->texfunc = (color(*)(void *, void *, void *))(marble_texture); break;
252*d86ed7fbStbbdev 
253*d86ed7fbStbbdev         case 4: tex->texfunc = (color(*)(void *, void *, void *))(wood_texture); break;
254*d86ed7fbStbbdev 
255*d86ed7fbStbbdev         case 5: tex->texfunc = (color(*)(void *, void *, void *))(gnoise_texture); break;
256*d86ed7fbStbbdev 
257*d86ed7fbStbbdev         case 6: tex->texfunc = (color(*)(void *, void *, void *))(cyl_checker_texture); break;
258*d86ed7fbStbbdev 
259*d86ed7fbStbbdev         case 7:
260*d86ed7fbStbbdev             tex->texfunc = (color(*)(void *, void *, void *))(image_sphere_texture);
261*d86ed7fbStbbdev             tex->img = AllocateImage((char *)apitex->imap);
262*d86ed7fbStbbdev             break;
263*d86ed7fbStbbdev 
264*d86ed7fbStbbdev         case 8:
265*d86ed7fbStbbdev             tex->texfunc = (color(*)(void *, void *, void *))(image_cyl_texture);
266*d86ed7fbStbbdev             tex->img = AllocateImage((char *)apitex->imap);
267*d86ed7fbStbbdev             break;
268*d86ed7fbStbbdev 
269*d86ed7fbStbbdev         case 9:
270*d86ed7fbStbbdev             tex->texfunc = (color(*)(void *, void *, void *))(image_plane_texture);
271*d86ed7fbStbbdev             tex->img = AllocateImage((char *)apitex->imap);
272*d86ed7fbStbbdev             break;
273*d86ed7fbStbbdev 
274*d86ed7fbStbbdev         default: tex->texfunc = (color(*)(void *, void *, void *))(standard_texture); break;
275*d86ed7fbStbbdev     }
276*d86ed7fbStbbdev 
277*d86ed7fbStbbdev     tex->ctr = apitex->ctr;
278*d86ed7fbStbbdev     tex->rot = apitex->rot;
279*d86ed7fbStbbdev     tex->scale = apitex->scale;
280*d86ed7fbStbbdev     tex->uaxs = apitex->uaxs;
281*d86ed7fbStbbdev     tex->vaxs = apitex->vaxs;
282*d86ed7fbStbbdev     tex->ambient = apitex->ambient;
283*d86ed7fbStbbdev     tex->diffuse = apitex->diffuse;
284*d86ed7fbStbbdev     tex->specular = apitex->specular;
285*d86ed7fbStbbdev     tex->opacity = apitex->opacity;
286*d86ed7fbStbbdev     tex->col = apitex->col;
287*d86ed7fbStbbdev 
288*d86ed7fbStbbdev     tex->islight = 0;
289*d86ed7fbStbbdev     tex->shadowcast = 1;
290*d86ed7fbStbbdev     tex->phong = 0.0;
291*d86ed7fbStbbdev     tex->phongexp = 0.0;
292*d86ed7fbStbbdev     tex->phongtype = 0;
293*d86ed7fbStbbdev }
294*d86ed7fbStbbdev 
295*d86ed7fbStbbdev void *rt_texture(apitexture *apitex) {
296*d86ed7fbStbbdev     texture *tex;
297*d86ed7fbStbbdev 
298*d86ed7fbStbbdev     tex = (texture *)rt_getmem(sizeof(texture));
299*d86ed7fbStbbdev     apitextotex(apitex, tex);
300*d86ed7fbStbbdev     return (tex);
301*d86ed7fbStbbdev }
302*d86ed7fbStbbdev 
303*d86ed7fbStbbdev void rt_tex_color(void *voidtex, color col) {
304*d86ed7fbStbbdev     texture *tex = (texture *)voidtex;
305*d86ed7fbStbbdev     tex->col = col;
306*d86ed7fbStbbdev }
307*d86ed7fbStbbdev 
308*d86ed7fbStbbdev void rt_tex_phong(void *voidtex, apiflt phong, apiflt phongexp, int type) {
309*d86ed7fbStbbdev     texture *tex = (texture *)voidtex;
310*d86ed7fbStbbdev     tex->phong = phong;
311*d86ed7fbStbbdev     tex->phongexp = phongexp;
312*d86ed7fbStbbdev     tex->phongtype = type;
313*d86ed7fbStbbdev }
314*d86ed7fbStbbdev 
315*d86ed7fbStbbdev void rt_light(void *tex, vector ctr, apiflt rad) {
316*d86ed7fbStbbdev     point_light *li;
317*d86ed7fbStbbdev 
318*d86ed7fbStbbdev     li = newlight(tex, (vector)ctr, rad);
319*d86ed7fbStbbdev 
320*d86ed7fbStbbdev     li->tex->islight = 1;
321*d86ed7fbStbbdev     li->tex->shadowcast = 1;
322*d86ed7fbStbbdev     li->tex->diffuse = 0.0;
323*d86ed7fbStbbdev     li->tex->specular = 0.0;
324*d86ed7fbStbbdev     li->tex->opacity = 1.0;
325*d86ed7fbStbbdev 
326*d86ed7fbStbbdev     add_light(li);
327*d86ed7fbStbbdev     add_object((object *)li);
328*d86ed7fbStbbdev }
329*d86ed7fbStbbdev 
330*d86ed7fbStbbdev void rt_scalarvol(void *tex,
331*d86ed7fbStbbdev                   vector min,
332*d86ed7fbStbbdev                   vector max,
333*d86ed7fbStbbdev                   int xs,
334*d86ed7fbStbbdev                   int ys,
335*d86ed7fbStbbdev                   int zs,
336*d86ed7fbStbbdev                   char *fname,
337*d86ed7fbStbbdev                   void *invol) {
338*d86ed7fbStbbdev     add_object((object *)newscalarvol(
339*d86ed7fbStbbdev         tex, (vector)min, (vector)max, xs, ys, zs, fname, (scalarvol *)invol));
340*d86ed7fbStbbdev }
341*d86ed7fbStbbdev 
342*d86ed7fbStbbdev void rt_extvol(void *tex, vector min, vector max, int samples, flt (*evaluator)(flt, flt, flt)) {
343*d86ed7fbStbbdev     add_object((object *)newextvol(tex, (vector)min, (vector)max, samples, evaluator));
344*d86ed7fbStbbdev }
345*d86ed7fbStbbdev 
346*d86ed7fbStbbdev void rt_box(void *tex, vector min, vector max) {
347*d86ed7fbStbbdev     add_object((object *)newbox(tex, (vector)min, (vector)max));
348*d86ed7fbStbbdev }
349*d86ed7fbStbbdev 
350*d86ed7fbStbbdev void rt_cylinder(void *tex, vector ctr, vector axis, apiflt rad) {
351*d86ed7fbStbbdev     add_object(newcylinder(tex, (vector)ctr, (vector)axis, rad));
352*d86ed7fbStbbdev }
353*d86ed7fbStbbdev 
354*d86ed7fbStbbdev void rt_fcylinder(void *tex, vector ctr, vector axis, apiflt rad) {
355*d86ed7fbStbbdev     add_object(newfcylinder(tex, (vector)ctr, (vector)axis, rad));
356*d86ed7fbStbbdev }
357*d86ed7fbStbbdev 
358*d86ed7fbStbbdev void rt_plane(void *tex, vector ctr, vector norm) {
359*d86ed7fbStbbdev     add_object(newplane(tex, (vector)ctr, (vector)norm));
360*d86ed7fbStbbdev }
361*d86ed7fbStbbdev 
362*d86ed7fbStbbdev void rt_ring(void *tex, vector ctr, vector norm, apiflt a, apiflt b) {
363*d86ed7fbStbbdev     add_object(newring(tex, (vector)ctr, (vector)norm, a, b));
364*d86ed7fbStbbdev }
365*d86ed7fbStbbdev 
366*d86ed7fbStbbdev void rt_sphere(void *tex, vector ctr, apiflt rad) {
367*d86ed7fbStbbdev     add_object(newsphere(tex, (vector)ctr, rad));
368*d86ed7fbStbbdev }
369*d86ed7fbStbbdev 
370*d86ed7fbStbbdev void rt_tri(void *tex, vector v0, vector v1, vector v2) {
371*d86ed7fbStbbdev     object *trn;
372*d86ed7fbStbbdev 
373*d86ed7fbStbbdev     trn = newtri(tex, (vector)v0, (vector)v1, (vector)v2);
374*d86ed7fbStbbdev 
375*d86ed7fbStbbdev     if (trn != nullptr) {
376*d86ed7fbStbbdev         add_object(trn);
377*d86ed7fbStbbdev     }
378*d86ed7fbStbbdev }
379*d86ed7fbStbbdev 
380*d86ed7fbStbbdev void rt_stri(void *tex, vector v0, vector v1, vector v2, vector n0, vector n1, vector n2) {
381*d86ed7fbStbbdev     object *trn;
382*d86ed7fbStbbdev 
383*d86ed7fbStbbdev     trn = newstri(tex, (vector)v0, (vector)v1, (vector)v2, (vector)n0, (vector)n1, (vector)n2);
384*d86ed7fbStbbdev 
385*d86ed7fbStbbdev     if (trn != nullptr) {
386*d86ed7fbStbbdev         add_object(trn);
387*d86ed7fbStbbdev     }
388*d86ed7fbStbbdev }
389*d86ed7fbStbbdev 
390*d86ed7fbStbbdev void rt_quadsphere(void *tex, vector ctr, apiflt rad) {
391*d86ed7fbStbbdev     quadric *q;
392*d86ed7fbStbbdev     flt factor;
393*d86ed7fbStbbdev     q = (quadric *)newquadric();
394*d86ed7fbStbbdev     factor = 1.0 / (rad * rad);
395*d86ed7fbStbbdev     q->tex = (texture *)tex;
396*d86ed7fbStbbdev     q->ctr = ctr;
397*d86ed7fbStbbdev 
398*d86ed7fbStbbdev     q->mat.a = factor;
399*d86ed7fbStbbdev     q->mat.b = 0.0;
400*d86ed7fbStbbdev     q->mat.c = 0.0;
401*d86ed7fbStbbdev     q->mat.d = 0.0;
402*d86ed7fbStbbdev     q->mat.e = factor;
403*d86ed7fbStbbdev     q->mat.f = 0.0;
404*d86ed7fbStbbdev     q->mat.g = 0.0;
405*d86ed7fbStbbdev     q->mat.h = factor;
406*d86ed7fbStbbdev     q->mat.i = 0.0;
407*d86ed7fbStbbdev     q->mat.j = -1.0;
408*d86ed7fbStbbdev 
409*d86ed7fbStbbdev     add_object((object *)q);
410*d86ed7fbStbbdev }
411