Tachyon (current)  Current Main Branch
fire.c
Go to the documentation of this file.
1 /*
2  * fire.c - This file contains a Tachyon demo program/driver
3  *
4  * (C) Copyright 1994-2022 John E. Stone
5  * SPDX-License-Identifier: BSD-3-Clause
6  *
7  * $Id: fire.c,v 1.25 2022/02/18 18:18:36 johns Exp $
8  *
9  */
10 
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <math.h>
15 #include "tachyon.h"
16 
17 #if defined(USEOMF)
18 #include "omfwrite.h"
19  /* AVR26 Resolution */
20 #define XRES 640
21 #define YRES 496
22 #else
23  /* MPEG-1 Resolution */
24 #define XRES 640
25 #define YRES 480
26 #endif
27 
28 #define XS 96
29 #define YS 96
30 #define ZS 64
31 #define NUMFLAMES 120
32 #define MAXFRAMES 600
33 #define FIREOPACITY 14.0
34 
35 #define RAD 6.28
36 #define MXV 255
37 
38 typedef struct { /* Scalar Volume Visualization Data */
39  int loaded; /* Volume data memory residence flag */
40  int xres; /* volume X axis size */
41  int yres; /* volume Y axis size */
42  int zres; /* volume Z axis size */
43  apiflt opacity; /* opacity per unit length */
44  char name[96]; /* Volume data filename */
45  unsigned char * data; /* pointer to raw byte volume data */
46 } scalarvol;
47 
48 typedef struct {
49  int x;
50  int y;
51 } flm;
52 
53 #ifdef cube
54 #define RFILE "/cfs/johns/anim/frame"
55 #endif
56 
57 #ifndef cube
58 #define RFILE "frame"
59 #endif
60 
61 int rt_mynode(void); /* proto */
62 
63 unsigned char fire[2][XS*YS*ZS + 10000];
65 
66 void updatefire(void) {
67  int x, y, z, i;
68  int xx, addr, addr2, addr3, addr4;
69 
70  for (i=0; i<NUMFLAMES; i++) {
71  flames[i].x += (rand() % 7) - 3;
72  flames[i].y += (rand() % 7) - 3;
73 
74  if (flames[i].x > (XS - 3))
75  flames[i].x = 3;
76  if (flames[i].x < 3)
77  flames[i].x = (XS - 3);
78  if (flames[i].y > (YS - 3))
79  flames[i].y = 3;
80  if (flames[i].y < 3)
81  flames[i].y = (YS - 3);
82 
83  addr = (XS*flames[i].y) + flames[i].x;
84  fire[0][addr - 1 ] = MXV;
85  fire[0][addr ] = MXV;
86  fire[0][addr + 1 ] = MXV;
87  fire[0][addr - 1 - XS] = MXV;
88  fire[0][addr - XS] = MXV;
89  fire[0][addr + 1 - XS] = MXV;
90  fire[0][addr - 1 + XS] = MXV;
91  fire[0][addr + XS] = MXV;
92  fire[0][addr + 1 + XS] = MXV;
93 
94  addr = addr + XS*YS;
95  fire[0][addr - 1 ] = MXV;
96  fire[0][addr ] = MXV;
97  fire[0][addr + 1 ] = MXV;
98  fire[0][addr - 1 - XS] = MXV;
99  fire[0][addr - XS] = MXV;
100  fire[0][addr + 1 - XS] = MXV;
101  fire[0][addr - 1 + XS] = MXV;
102  fire[0][addr + XS] = MXV;
103  fire[0][addr + 1 + XS] = MXV;
104 
105  addr = addr + XS*YS;
106  fire[0][addr - 1 ] = MXV;
107  fire[0][addr ] = MXV;
108  fire[0][addr + 1 ] = MXV;
109  fire[0][addr + XS] = MXV;
110  fire[0][addr - XS] = MXV;
111  }
112 
113  for (z=0; z<(ZS - 1); z++) {
114  addr3 = z*XS*YS;
115  for (y=1; y<(YS - 1); y++) {
116  addr2 = y*XS + addr3;
117  for (x=1; x<(XS - 1); x++) {
118  addr = x + addr2;
119 
120 /* NOTE: This address code takes the 26 points in the box surrounding
121  the original point, and averages them with together, to generate
122  the new point. If you desire speed, comment out everything
123  after the "first 6 points"
124  Remember to change the divisor on the line "xx = xx / 26"
125 */
126 
127  xx = fire[0][addr + 1 ] + /* first 6 adjacent neighbors */
128  fire[0][addr - 1 ] +
129  fire[0][addr + XS ] +
130  fire[0][addr - XS ] +
131  fire[0][addr + XS*YS] +
132  fire[0][addr - XS*YS] +
133 
134  fire[0][addr - 1 + XS] + /* middle 4 points */
135  fire[0][addr + 1 + XS] +
136  fire[0][addr - 1 - XS] +
137  fire[0][addr + 1 - XS];
138 
139  addr4=addr - XS*YS; /* bottom 8 points */
140  xx += fire[0][addr4 - 1] +
141  fire[0][addr4 + 1];
142  addr4=addr + XS - XS*YS;
143  xx += fire[0][addr4 - 1] +
144  fire[0][addr4 ] +
145  fire[0][addr4 + 1];
146  addr4=addr - XS - XS*YS;
147  xx += fire[0][addr4 - 1] +
148  fire[0][addr4 ] +
149  fire[0][addr4 + 1];
150 
151  addr4=addr + XS*YS; /* top 8 points */
152  xx += fire[0][addr4 - 1] +
153  fire[0][addr4 + 1];
154  addr4=addr + XS + XS*YS;
155  xx += fire[0][addr4 - 1] +
156  fire[0][addr4 ] +
157  fire[0][addr4 + 1];
158  addr4=addr - XS + XS*YS;
159  xx += fire[0][addr4 - 1] +
160  fire[0][addr4 ] +
161  fire[0][addr4 + 1];
162 
163  xx = xx / 26;
164 
165  if (xx > 1)
166  fire[1][addr + XS*YS] = (unsigned char) xx - 1;
167  else
168  fire[1][addr + XS*YS] = 0;
169 
170  }
171  }
172  }
173  memcpy(&fire[0], &fire[1], (XS*YS*ZS));
174 }
175 
176 int main(int argc, char **argv) {
177  SceneHandle scene;
178  int i, antialiasing;
179  apiflt zoom, aspectratio;
180  apivector Ccenter, Cview, Cup;
181  apitexture tex1, tex2;
182  apitexture p1,p2;
183  scalarvol vol;
184  apiflt xc,yc;
185  void * t1, * t2, * vt1, * lt1;
186  char fname[1000];
187  char fname2[2000];
188 #ifdef USEOMF
189  int yy;
190  unsigned char * rawimage;
191  unsigned char * interlacedimage;
192  void * omfhandle;
193 #endif
194 
195  rt_initialize(&argc, &argv);
196 
197  scene = rt_newscene();
198 
199 #ifdef USEOMF
200  rawimage = malloc(XRES*YRES*4);
201  interlacedimage = malloc(XRES*YRES*4);
202 
203  omfhandle = OMFopen(XRES, YRES, AVR26, "fire.omf");
204 #endif
205 
206  for (i=0; i<NUMFLAMES; i++) { /* init the little flames */
207  flames[i].x=rand() % XS;
208  flames[i].y=rand() % YS;
209  }
210 
211  aspectratio=1.0;
212  antialiasing=0;
213  zoom=1.0;
214 
215  Ccenter = rt_vector(0.0, 0.0, 0.0);
216  Cview = rt_vector(1.0, 0.0, 0.0);
217  Cup = rt_vector(0.0, 0.0, 1.0);
218 
219  tex1.col = rt_color(1.0, 1.0, 1.0);
220  tex1.ambient=1.0;
221  tex1.diffuse=0.0;
222  tex1.specular=0.0;
223  tex1.opacity=FIREOPACITY;
224  tex1.texturefunc=0;
225  tex2=tex1;
226 
227 
228  vol.loaded=1;
229  vol.data=fire[1];
230 
231  p1.col = rt_color(1.0, 1.0, 1.0);
232  p1.ambient=0.3;
233  p1.diffuse=0.8;
234  p1.specular=0.0;
235  p1.opacity=1.0;
236 
237  p2=p1;
238 
239  p1.texturefunc=9;
240  p1.ctr = rt_vector(0.0, 0.0, 0.0);
241  p1.rot = rt_vector(0.0, 0.0, 0.0);
242  p1.scale = rt_vector(0.1, 0.1, 0.1);
243  p1.uaxs = rt_vector(1.0, 0.0, 0.0);
244  p1.vaxs = rt_vector(0.0, 1.0, 0.0);
245 
246  strcpy((char *) &p1.imap, "/disk7/cube/imaps/leafy261.ppm");
247 
248  t1=rt_texture(scene, &p1);
249 
250  p2.ambient=0.1;
251  p2.diffuse=0.1;
252  p2.specular=0.8;
253 
254  t2=rt_texture(scene, &p2);
255  vt1=rt_texture(scene, &tex2);
256  lt1=rt_texture(scene, &tex1);
257 
258  rt_resolution(scene, XRES, YRES);
259  rt_verbose(scene, 0);
260 
261  rt_light(scene, lt1, rt_vector(0.0, 0.0, 40.0), 1.0);
262  rt_scalarvol(scene, vt1, rt_vector(-1.0, -1.0, -1.0),
263  rt_vector(1.0, 1.0, 1.0), XS, YS, ZS, "", &vol);
264 
265  rt_plane(scene, t1, rt_vector(0.0, 0.0, -1.01), rt_vector(0.0, 0.0, 1.0));
266 
267  rt_sphere(scene, t2, rt_vector(0.0, 0.0, 1.8), 0.8);
268 
269  for (i=0; i<MAXFRAMES; i++) {
270  sprintf(fname,".%4.4d.tga",i);
271  strcpy(fname2,RFILE);
272  strcat(fname2, fname);
273 
274 #ifdef USEOMF
275  rt_outputfile(scene, "fire.tga");
276  rt_rawimage_rgb24(scene, rawimage);
277 #else
278  rt_outputfile(scene, fname2);
279 #endif
280 
281  if (rt_mynode()==0) printf("Rendering: %s \n",fname2);
282 
283  xc=cos(6.28 * i / (1.0 * MAXFRAMES));
284  yc=sin(6.28 * i / (1.0 * MAXFRAMES));
285  Ccenter.x = xc*3.2; Ccenter.y = yc*3.2;
286  Cview.x = -xc; Cview.y = -yc;
287 
288  srand(i); /* reset random seed.. */
289  /* this was what used to cause antialiased fire to choke.. */
290  updatefire(); /* run one iteration of the fire code */
291 
292  rt_camera_setup(scene, zoom, aspectratio, antialiasing,
293  6, Ccenter, Cview, Cup);
294 
295  rt_renderscene(scene);
296 
297 #ifdef USEOMF
298  for (yy=0; yy<YRES; yy+=2) {
299  memcpy(&interlacedimage[(yy>>1)*XRES*3], &rawimage[yy*XRES*3], XRES*3);
300  memcpy(&interlacedimage[((yy>>1)+1)*XRES*3], &rawimage[(yy+1)*XRES*3], XRES*3);
301  }
302 
303  OMFwriteframe(omfhandle, interlacedimage);
304 #endif
305  }
306 
307 #ifdef USEOMF
308  OMFclose(omfhandle);
309  free(rawimage);
310  free(interlacedimage);
311 #endif
312 
313  rt_finalize();
314 
315  return 0;
316 }
317 
int main(int argc, char **argv)
Definition: fire.c:176
void rt_camera_setup(SceneHandle voidscene, flt zoom, flt aspectratio, int antialiasing, int raydepth, apivector camcent, apivector viewvec, apivector upvec)
Define a camera for a perspective projection, given the specified zoom factor, aspect ratio...
Definition: api.c:229
void * rt_texture(SceneHandle sc, apitexture *apitex)
Translate a texture definition into the internal format used by Tachyon, and returns an opaque pointe...
Definition: api.c:933
#define RFILE
Definition: fire.c:58
#define ZS
Definition: fire.c:30
apicolor col
base object color
Definition: tachyon.h:67
apivector rot
rotation of texture around origin
Definition: tachyon.h:74
void rt_resolution(SceneHandle voidscene, int hres, int vres)
Set the horizontal and vertical resolution (in pixels) for the specified scene.
Definition: api.c:372
flt diffuse
diffuse reflection
Definition: tachyon.h:70
flt opacity
how opaque the object is
Definition: tachyon.h:72
flt specular
specular reflection
Definition: tachyon.h:71
int loaded
Definition: animskull.c:20
apicolor rt_color(flt r, flt g, flt b)
Helper function to make colors.
Definition: api.c:169
apivector ctr
origin of texture
Definition: tachyon.h:73
char imap[96]
name of image map
Definition: tachyon.h:79
void rt_renderscene(SceneHandle voidscene)
Render the current scene.
Definition: api.c:180
void rt_sphere(SceneHandle scene, void *tex, apivector ctr, flt rad)
Define a sphere with associated texture, center, and radius.
Definition: api.c:1212
void rt_scalarvol(SceneHandle scene, void *tex, apivector min, apivector max, int xs, int ys, int zs, const char *fname, void *voidvol)
Define an axis-aligned scalar volumetric data set, loaded from a file.
Definition: api.c:1146
int rt_initialize(int *argc, char ***argv)
Initialize Tachyon library, must be first Tachyon API called.
Definition: api.c:70
flt x
X coordinate or direction component.
Definition: tachyon.h:54
flt apiflt
for backward compatibility
Definition: tachyon.h:49
flt y
Y coordinate or direction component.
Definition: tachyon.h:55
apivector scale
scale of texture in x,y,z
Definition: tachyon.h:75
SceneHandle rt_newscene(void)
Allocate, initialize, and return a handle for a new scene.
Definition: api.c:698
int x
Definition: fire.c:49
void rt_rawimage_rgb24(SceneHandle voidscene, unsigned char *img)
Have Tachyon save the output image in the specified memory area, in raw 24-bit, packed, pixel interleaved, unsigned RGB bytes.
Definition: api.c:419
void rt_outputfile(SceneHandle voidscene, const char *outname)
Set the filename for the output image for the specified scene.
Definition: api.c:350
apivector uaxs
planar map u axis
Definition: tachyon.h:76
#define YRES
Definition: fire.c:25
void * SceneHandle
Definition: tachyon.h:51
#define XRES
Definition: fire.c:24
int texturefunc
which texture function to use
Definition: tachyon.h:66
#define NUMFLAMES
Definition: fire.c:31
apivector rt_vector(flt x, flt y, flt z)
Helper function to make vectors.
Definition: api.c:159
flt ambient
ambient lighting
Definition: tachyon.h:69
apivector vaxs
planar map v axis
Definition: tachyon.h:77
void rt_finalize(void)
Shut down Tachyon library for good, at final use before program termination.
Definition: api.c:153
void updatefire(void)
Definition: fire.c:66
unsigned char fire[2][XS *YS *ZS+10000]
Definition: fire.c:63
#define FIREOPACITY
Definition: fire.c:33
#define YS
Definition: fire.c:29
flm flames[NUMFLAMES+10]
Definition: fire.c:64
int y
Definition: fire.c:50
void rt_plane(SceneHandle scene, void *tex, apivector ctr, apivector norm)
Define a plane.
Definition: api.c:1186
Definition: fire.c:48
Tachyon public API function prototypes and declarations used to drive the ray tracing engine...
unsigned char * data
Definition: animskull.c:26
void * rt_light(SceneHandle voidscene, void *tex, apivector ctr, flt rad)
Define a point light with associated texture, position, and radius.
Definition: api.c:1049
#define MXV
Definition: fire.c:36
int rt_mynode(void)
distributed memory parallel node rank
Definition: api.c:49
#define MAXFRAMES
Definition: fire.c:32
void rt_verbose(SceneHandle voidscene, int v)
Enables or Disables verbose messages from the Tachyon library during rendering.
Definition: api.c:414
#define XS
Definition: fire.c:28