home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Current Shareware 1994 January
/
SHAR194.ISO
/
graphuti
/
rawpov18.zip
/
SOURCE.ZIP
/
RAW2POV.C
next >
Wrap
C/C++ Source or Header
|
1993-10-02
|
18KB
|
769 lines
/*-------------------------------------------------------------------------
RAW to POV-Ray Converter
Copyright (c) 1993 Steve Anger
Reads a list of triangle coordinates in raw ASCII text format and
outputs a POV-Ray compatable file. Automatically adds bounding shapes
and produces smooth triangles. This file may be freely modified and
distributed.
CompuServe: 70714,3113
Internet: 70714.3113@compuserve.com
YCCMR BBS: (708)358-5611
--------------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <values.h>
#include <ctype.h>
#include "vect.h"
#include "rayopt.h"
#if defined(applec) || defined(THINK_C)
#include "RAW2POV.mac.h"
#else
#define COOPERATE
#endif
#ifdef __TURBOC__
extern unsigned _stklen = 16384;
#endif
#ifndef FALSE
#define FALSE 0
#define TRUE 1
#endif
#define OFF 0
#define ON 1
#define AUTO 2
#define VERSION "v1.8"
#define MAX_TEXTURE 500
#define DEFAULT 0
#define FRACTINT 1
#define TEXTURE 2
#define POV10 0
#define POV20 1
#define VIVID 2
#define POLYRAY 3
/* Function prototypes */
static void process_args (int argc, char *argv[]);
static void parse_option (char *option);
static char *next_token (FILE *f);
static int parse_input (FILE *f);
static void make_camera (void);
static void update_txtlist (char *new_texture);
static void fswap (float *a, float *b);
static char upcase (char c);
static void write_light (FILE *f, Vector pos);
static void write_camera (FILE *f, Vector pos, Vector target);
static void write_texture (FILE *f, char *mat);
static void write_intro (FILE *f);
static char infile[64]; /* Name of input file */
static char outfile[64]; /* Name of output file */
static float smooth; /* Smooth triangles with angles < this value */
static int bound; /* Type of bounding shape to use */
static int verbose; /* Verbose status messages */
static int one_object; /* Optimize file as a single object */
static int swap_yz; /* Swap Y and Z coordinates */
static int internal_bounding;/* Use internal bounding for POV-Ray */
static int camera; /* Place a camera and light source in scene file */
static int iformat; /* Input file format type */
static int oformat; /* Output format */
static long line_cnt; /* Line number */
static float ax, ay, az;
static float bx, by, bz;
static float cx, cy, cz;
static float red, green, blue;
static char new_obj_name[80];
static char new_texture[80];
static char **txtlist;
static int txtcnt = 0;
int main (int argc, char *argv[])
{
FILE *f, *g;
int obj_cnt, tri_cnt;
int done, i;
char obj_name[80] = "";
txtlist = malloc((MAX_TEXTURE+1) * sizeof(char *));
if (txtlist == NULL)
abortmsg ("Out of memory", 1);
process_args (argc, argv);
f = fopen (infile, "r");
if (f == NULL) {
printf ("Error opening input file %s\n", infile);
exit(1);
}
opt_set_format (oformat);
opt_set_dec (4);
opt_set_bound (bound);
opt_set_smooth (smooth);
opt_set_quiet (!verbose);
opt_set_fname (outfile, "");
/* Use the name of the file as default object name */
strcpy (obj_name, infile);
add_ext (obj_name, "", 1);
line_cnt = 0;
obj_cnt = 0;
tri_cnt = 0;
done = 0;
printf ("Reading file...\n");
g = fopen (outfile, "a");
write_intro (g);
fclose(g);
while (!done) {
COOPERATE /* support multitasking */
switch (parse_input (f)) {
/* End of file */
case 0: done = 1;
break;
/* New triangle with RGB color */
case 1: opt_set_color (red, green, blue);
opt_add_tri (ax, ay, az, bx, by, bz, cx, cy, cz);
++tri_cnt;
break;
/* New triangle with named texture */
case 2: update_txtlist (new_texture);
opt_set_texture (new_texture);
opt_add_tri (ax, ay, az, bx, by, bz, cx, cy, cz);
++tri_cnt;
break;
/* New object */
case 3: if (!one_object) {
if (tri_cnt > 0) {
opt_write_file (obj_name);
++obj_cnt;
}
strcpy (obj_name, new_obj_name);
printf ("Working on: %s\n", obj_name);
}
break;
}
}
fclose (f);
opt_write_pov (obj_name);
++obj_cnt;
printf ("\n");
g = fopen (outfile, "a");
if (txtcnt > 0)
fprintf (g, "\n/* Named textures, modify as needed */\n");
for (i = 0; i < txtcnt; i++) {
write_texture (g, txtlist[i]);
free (txtlist[i]);
}
fclose(g);
opt_finish();
if (camera)
make_camera();
free(txtlist);
return 0;
}
static void process_args (int argc, char *argv[])
{
int i;
char *env_opt, *option;
printf ("\n");
printf ("RAW to POV-Ray (and others) Converter %s - Copyright (c) 1993 Steve Anger\n", VERSION);
#if defined(__GNUC__) && defined(i386)
printf ("32 bit version. DOS Extender Copyright (c) 1991 DJ Delorie\n");
#endif
printf ("This program is freely distributable\n");
printf ("\n");
if (argc < 2) {
printf ("Usage: raw2pov inputfile[.raw] [outputfile[.pov]] [options]\n\n");
printf ("Options: -snnn - Smooth triangles with angles < nnn\n");
printf (" +v, -v - Turn verbose status messages on or off\n");
printf (" +i, -i - Turn internal bounding on or off\n");
printf (" -1 - Generate one object only\n");
printf (" -x - Exchange the Y and Z coords\n");
printf (" -c - Add camera and light source\n");
printf (" -fc - Input file in fractint color format\n");
printf (" -ft - Input file has textures specified\n");
printf (" -op - Output to POV-Ray 2.0 format (default)\n");
printf (" -op1 - Output to POV-Ray 1.0 format\n");
printf (" -ov - Output to Vivid format\n");
printf (" -ol - Output to poLyray format\n");
printf ("\nex. raw2pov chess.raw chess.pov\n\n");
exit(1);
}
infile[0] = '\0';
outfile[0] = '\0';
smooth = 70.0;
bound = 0;
verbose = 0;
one_object = 0;
swap_yz = 0;
camera = 0;
internal_bounding = AUTO;
iformat = DEFAULT;
oformat = POV20;
/* Parse the enviroment string options */
env_opt = getenv ("RAW2POV");
if (env_opt != NULL) {
option = strtok (env_opt, " ");
while (option != NULL) {
parse_option (option);
option = strtok (NULL, " ");
}
}
/* Parse the command line options */
for (i = 1; i < argc; i++)
parse_option (argv[i]);
if (strlen(infile) == 0)
abortmsg ("No input file specified", 1);
if (strlen(outfile) == 0) {
strcpy (outfile, infile);
switch (oformat) {
case POV10:
case POV20: add_ext (outfile, "pov", 1); break;
case VIVID: add_ext (outfile, "v", 1); break;
case POLYRAY: add_ext (outfile, "pi", 1); break;
}
}
else {
switch (oformat) {
case POV10:
case POV20: add_ext (outfile, "pov", 0); break;
case VIVID: add_ext (outfile, "v", 0); break;
case POLYRAY: add_ext (outfile, "pi", 0); break;
}
}
switch (internal_bounding) {
case OFF: bound = 2; break;
case ON: bound = 0; break;
case AUTO: bound = (oformat == POV10) ? 0 : 2; break;
}
}
static void parse_option (char *option)
{
if (option[0] == '-' || option[0] == '+') {
switch (upcase(option[1])) {
case 'C': camera = TRUE;
break;
case 'F': if (upcase(option[2]) == 'C')
iformat = FRACTINT;
else if (upcase(option[2]) == 'T')
iformat = TEXTURE;
break;
case 'I': if (option[0] == '-')
internal_bounding = OFF;
else
internal_bounding = ON;
break;
case 'O': switch (upcase (option[2])) {
case 'P': if (option[3] == '1')
oformat = POV10;
else
oformat = POV20;
break;
case 'V': oformat = VIVID;
break;
case 'L': oformat = POLYRAY;
break;
}
break;
case 'S': if (option[2] == '\0')
smooth = 70.0;
else
sscanf (&option[2], "%f", &smooth);
break;
case 'U': printf ("Warning: -u parameter no long has any effect\n");
printf (" use +i or -i instead.\n");
break;
case 'V': if (option[0] == '-')
verbose = FALSE;
else
verbose = TRUE;
break;
case '1': one_object = TRUE;
break;
case 'X': swap_yz = TRUE;
break;
default : printf ("\nInvalid option -%c\n", option[1]);
exit (1);
}
}
else if (strlen(infile) == 0) {
strcpy (infile, option);
add_ext (infile, "raw", 0);
}
else if (strlen(outfile) == 0)
strcpy (outfile, option);
else
abortmsg ("Too many file names specified.\n", 1);
}
static char *next_token (FILE *f)
{
static char token[128];
int index, comment;
char ch;
index = 0;
comment = 0;
strcpy (token, "");
/* Skip the white space */
while (1) {
ch = fgetc (f);
if (feof(f))
break;
if (ch == '\n')
++line_cnt;
else if (ch == '{')
comment += 1;
else if (ch == '}')
comment = (comment > 0) ? (comment - 1) : 0;
else if (!isspace(ch) && !comment)
break;
}
if (feof(f))
return token;
ungetc (ch, f);
while (1) {
ch = fgetc (f);
if (feof(f))
break;
if (ch == '\n')
++line_cnt;
if (isspace(ch))
break;
if (index < 127)
token[index++] = ch;
}
token[index] = '\0';
return token;
}
static int parse_input (FILE *f)
{
int token_cnt, expected, result;
char *token;
char tokens[12][64];
token_cnt = 0;
expected = 0;
result = -1;
/* How many tokens to expect per triangle */
switch (iformat) {
case DEFAULT: expected = 9; break;
case FRACTINT: expected = 12; break;
case TEXTURE: expected = 10; break;
}
do {
token = next_token (f);
if (strlen(token) == 0)
break;
if (!isdigit(token[0]) && token[0] != '+' && token[0] != '-' && token[0] != '.') {
if (token_cnt == 0) {
strcpy (new_obj_name, token);
cleanup_name (new_obj_name);
return 3; /* New object name */
}
else if (token_cnt != 9 || expected != 10) {
printf ("Error in input file, line %ld. Misplaced object name.\n", line_cnt);
exit(1);
}
}
strcpy (tokens[token_cnt++], token);
} while (token_cnt < expected);
if (token_cnt == 0)
return 0; /* End of file */
if (token_cnt != expected) {
printf ("Error in input file, line %ld. Unexpected end of file.\n", line_cnt);
exit(1);
}
switch (iformat) {
case DEFAULT: /* Ax Ay Az Bx By Bz Cx Cy Cz */
red = 1.0;
green = 1.0;
blue = 1.0;
ax = atof(tokens[0]);
ay = atof(tokens[1]);
az = atof(tokens[2]);
bx = atof(tokens[3]);
by = atof(tokens[4]);
bz = atof(tokens[5]);
cx = atof(tokens[6]);
cy = atof(tokens[7]);
cz = atof(tokens[8]);
result = 1;
break;
case FRACTINT: /* R G B Ax Ay Az Bx By Bz Cx Cy Cz */
red = atof(tokens[0]);
green = atof(tokens[1]);
blue = atof(tokens[2]);
ax = atof(tokens[3]);
ay = atof(tokens[4]);
az = atof(tokens[5]);
bx = atof(tokens[6]);
by = atof(tokens[7]);
bz = atof(tokens[8]);
cx = atof(tokens[9]);
cy = atof(tokens[10]);
cz = atof(tokens[11]);
result = 1;
break;
case TEXTURE: /* Ax Ay Az Bx By Bz Cx Cy Cz Texture */
ax = atof(tokens[0]);
ay = atof(tokens[1]);
az = atof(tokens[2]);
bx = atof(tokens[3]);
by = atof(tokens[4]);
bz = atof(tokens[5]);
cx = atof(tokens[6]);
cy = atof(tokens[7]);
cz = atof(tokens[8]);
strcpy (new_texture, tokens[9]);
cleanup_name (new_texture);
result = 2;
break;
}
if (swap_yz) {
fswap (&ay, &az);
fswap (&by, &bz);
fswap (&cy, &cz);
}
return result;
}
static void make_camera()
{
Vector gmin, gmax, look;
Vector size, scale, temp;
float maxdim;
FILE *f;
f = fopen (outfile, "a");
opt_get_glimits (&gmin[X], &gmin[Y], &gmin[Z], &gmax[X], &gmax[Y], &gmax[Z]);
look[X] = (gmin[X] + gmax[X])/2.0;
look[Y] = (gmin[Y] + gmax[Y])/2.0;
look[Z] = (gmin[Z] + gmax[Z])/2.0;
size[X] = gmax[X] - gmin[X];
size[Y] = gmax[Y] - gmin[Y];
size[Z] = gmax[Z] - gmin[Z];
maxdim = -MAXINT;
if (size[X] > maxdim) maxdim = size[X];
if (size[Y] > maxdim) maxdim = size[Y];
if (size[Z] > maxdim) maxdim = size[Z];
if (oformat != POV10 && oformat != POV20)
fswap (&size[Y], &size[Z]);
if (size[X] > size[Z]) {
scale[X] = 0.3;
scale[Y] = 0.4;
scale[Z] = -1.3;
}
else {
scale[X] = 1.3;
scale[Y] = 0.4;
scale[Z] = 0.3;
}
if (oformat != POV10 && oformat != POV20)
fswap (&scale[Y], &scale[Z]);
fprintf (f, "\n");
vect_scale (temp, scale, maxdim);
vect_add (temp, temp, look);
write_camera (f, temp, look);
vect_scale (temp, scale, 4.0*maxdim);
vect_add (temp, temp, look);
write_light (f, temp);
fclose(f);
}
static void update_txtlist (char *new_texture)
{
int i;
for (i = 0; i < txtcnt; i++) {
if (strcmp (new_texture, txtlist[i]) == 0)
break;
}
if (i < txtcnt)
return;
if (i == MAX_TEXTURE)
abortmsg ("Too many textures", 1);
txtlist[i] = malloc (strlen (new_texture) + 1);
strcpy (txtlist[i], new_texture);
++txtcnt;
}
static void fswap (float *a, float *b)
{
float temp;
temp = *a;
*a = *b;
*b = temp;
}
/* Convert character 'c' top upper case */
static char upcase (char c)
{
if (c >= 'a' && c <= 'z')
c = c - 'a' + 'A';
return c;
}
static void write_light (FILE *f, Vector pos)
{
switch (oformat) {
case POV10:
fprintf (f, "object {\n");
fprintf (f, " light_source { <%.4f %.4f %.4f> color White }\n",
pos[X], pos[Y], pos[Z]);
fprintf (f, "}\n\n");
break;
case POV20:
fprintf (f, "light_source {\n");
fprintf (f, " <%.4f, %.4f, %.4f> color White\n",
pos[X], pos[Y], pos[Z]);
fprintf (f, "}\n\n");
break;
case VIVID:
fprintf (f, "light {\n");
fprintf (f, " type point\n");
fprintf (f, " position %.4f %.4f %.4f\n",
pos[X], pos[Y], pos[Z]);
fprintf (f, " color white\n");
fprintf (f, "}\n\n");
break;
case POLYRAY:
fprintf (f, "light white, <%.4f, %.4f, %.4f>\n\n",
pos[X], pos[Y], pos[Z]);
break;
}
}
static void write_camera (FILE *f, Vector pos, Vector target)
{
switch (oformat) {
case POV10:
fprintf (f, "camera {\n");
fprintf (f, " location <%.4f %.4f %.4f>\n",
pos[X], pos[Y], pos[Z]);
fprintf (f, " look_at <%.4f %.4f %.4f>\n",
target[X], target[Y], target[Z]);
fprintf (f, "}\n\n");
break;
case POV20:
fprintf (f, "camera {\n");
fprintf (f, " location <%.4f, %.4f, %.4f>\n",
pos[X], pos[Y], pos[Z]);
fprintf (f, " look_at <%.4f, %.4f, %.4f>\n",
target[X], target[Y], target[Z]);
fprintf (f, "}\n\n");
break;
case VIVID:
fprintf (f, "studio {\n");
fprintf (f, " from %.4f %.4f %.4f\n",
pos[X], pos[Y], pos[Z]);
fprintf (f, " at %.4f %.4f %.4f\n",
target[X], target[Y], target[Z]);
fprintf (f, " up 0 0 1\n");
fprintf (f, " angle 60.0\n");
fprintf (f, " aspect 4/3\n");
fprintf (f, " resolution 320 200\n");
fprintf (f, " antialias none\n");
fprintf (f, "}\n\n");
break;
case POLYRAY:
fprintf (f, "viewpoint {\n");
fprintf (f, " from <%.4f, %.4f, %.4f>\n",
pos[X], pos[Y], pos[Z]);
fprintf (f, " at <%.4f, %.4f, %.4f>\n",
target[X], target[Y], target[Z]);
fprintf (f, " up <0, 0, 1>\n");
fprintf (f, " angle 60.0\n");
fprintf (f, " aspect -4/3\n");
fprintf (f, " resolution 320, 200\n");
fprintf (f, "}\n\n");
break;
}
}
static void write_texture (FILE *f, char *mat)
{
switch (oformat) {
case POV10:
fprintf (f, "#declare %s = texture {\n", mat);
fprintf (f, " Shiny\n");
fprintf (f, " color White\n");
fprintf (f, "}\n\n");
break;
case POV20:
fprintf (f, "#declare %s = texture {\n", mat);
fprintf (f, " finish { Shiny }\n");
fprintf (f, " pigment { White }\n");
fprintf (f, "}\n\n");
break;
case VIVID:
fprintf (f, "#define %s \\ \n", mat);
fprintf (f, " surface { \\ \n");
fprintf (f, " ambient 0.1*white \\ \n");
fprintf (f, " diffuse 0.8*white \\ \n");
fprintf (f, " shine 70, white \\ \n");
fprintf (f, " }\n\n");
break;
case POLYRAY:
fprintf (f, "define %s\n", mat);
fprintf (f, "texture {\n");
fprintf (f, " surface {\n");
fprintf (f, " ambient white, 0.1\n");
fprintf (f, " diffuse white, 0.8\n");
fprintf (f, " microfacet Reitz 20\n");
fprintf (f, " }\n");
fprintf (f, "}\n\n");
break;
}
}
static void write_intro (FILE *f)
{
switch (oformat) {
case POV10:
case POV20:
fprintf (f, "#include \"colors.inc\"\n");
fprintf (f, "#include \"shapes.inc\"\n");
fprintf (f, "#include \"textures.inc\"\n");
fprintf (f, "\n");
break;
case VIVID:
fprintf (f, "#include color.vc\n");
fprintf (f, "\n");
break;
case POLYRAY:
fprintf (f, "include \"colors.inc\"\n");
fprintf (f, "\n");
break;
}
}