home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Best Objectech Shareware Selections
/
UNTITLED.iso
/
boss
/
grap
/
util
/
022
/
rayopt.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-04-29
|
55KB
|
2,166 lines
/*-------------------------------------------------------------------------
Triangle Bounder/Smoother for POV-Ray
Copyright (c) 1993 Steve Anger
A number of C routines that can be used to generate POV-Ray ray tracer
files from triangle data. Supports generation of smooth triangles and an
optimal set of bounding shapes for much faster traces. Output files are
compatible with POV-Ray v1.0. This program may be freely modified and
distributed.
Compuserve: 70714,3113
YCCMR BBS: (708)358-5611
--------------------------------------------------------------------------*/
#ifdef __TURBOC__
#include <alloc.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
#include "vect.h"
#include "rayopt.h"
#if defined(applec) || defined(THINK_C)
#include "RAW2POV.mac.h"
#else
#define COOPERATE
#endif
#define HASHSIZE 1000 /* Size of hash table for vertex lookup */
#define DEGEN_TOL (1e-8) /* float comparison tolerance for checking */
/* for degenerate triangles */
#define MAX_TEX 500 /* Maximum allowable number of texture */
/* declarations */
#define POV10 0
#define POV20 1
#define VIVID 2
#define POLYRAY 3
#ifndef MAXFLOAT
#define MAXFLOAT (1e37)
#endif
typedef struct {
float red;
float green;
float blue;
} Palette;
typedef char *Texture;
typedef struct {
unsigned vert[3];
unsigned text_index;
char text_type;
char flag;
} Triangle;
/* Linked list of triangles */
typedef struct TList {
Triangle *tri;
struct TList *next;
} TriList;
/* Double linked list of triangles */
typedef struct TList2 {
Triangle *tri;
struct TList2 *prev;
struct TList2 *next;
} TriList2;
/* List of triangle vertices */
typedef struct VList {
unsigned vert;
struct VList *next;
} VertList;
/* List of triangle groups */
typedef struct GTree {
TriList2 *index[3]; /* Triangles indexed by x, y, and z coord */
Vector vmin; /* min/max extents of triangle vertices */
Vector vmax; /* " " " " " */
float area; /* Total surface area of bounding region */
unsigned obj_cnt; /* Total number of triangles in group */
int child_cnt; /* Number of children */
int split_cnt; /* Number of times this node has been split */
struct GTree *parent; /* Parent of this node */
struct GTree *next; /* Next node at this level */
struct GTree *child; /* First child of this ndoe */
} GroupTree;
static Palette *ptable; /* Palette table */
static unsigned pmax; /* Maximum size of table */
static unsigned psize; /* Current size */
static Texture *ttable; /* Named texture table */
static unsigned tmax; /* Maximum size of table */
static unsigned tsize; /* Current size */
static Vector *vtable; /* Vertice table */
static unsigned vmax; /* Maximum size of table */
static unsigned vsize; /* Current size */
static Vector gmin = {+MAXFLOAT, +MAXFLOAT, +MAXFLOAT};
static Vector gmax = {-MAXFLOAT, -MAXFLOAT, -MAXFLOAT};
static Matrix trans_matrix;
static int use_transform = 0;
static VertList **vert_hash; /* Hash table for looking up vertices */
static TriList **tri_index; /* Index for smooth triangle generation */
static GroupTree *groot; /* Tree representing the object hierarchy */
static int initialized = 0;
static int quiet_mode = 0;
static int bound_mode = 0;
static float smooth_angle = 0.0;
static unsigned vert_init = 0;
static int dec_point = 4;
static int out_format = POV10;
static char out_file[64] = "rayopt.pov";
static char inc_file[64] = "rayopt.inc";
static unsigned tot_bounds = 0;
static unsigned object_cnt = 0;
static Vector last_vmin = {0.0, 0.0, 0.0};
static Vector last_vmax = {0.0, 0.0, 0.0};
static unsigned last_vert_cnt = 0;
static unsigned last_tri_cnt = 0;
static float last_index = 0.0;
static unsigned last_bounds = 0;
static Palette last_pal;
static char last_texture[64] = "";
static unsigned texture_index;
static char texture_type;
static char object_name[64] = "";
static float orig_tpr; /* Number of Tests Per Ray before optimization */
static float final_tpr; /* " " " " " after optimization */
static float bound_cost; /* Cost of testing a bound relative to testing */
/* a triangle */
/* Function prototypes */
void init_object (void);
void cleanup_object (void);
float calc_tpr (GroupTree *gnode);
GroupTree *create_group (void);
void delete_tree (GroupTree *gnode);
void optimize_tree (GroupTree *gnode);
void test_split (GroupTree *gnode, int axis, float *best_rtpr, TriList2 **
best_loc);
void split_group (GroupTree *gnode, int axis, TriList2 *split_loc, GroupTree *
*group_a, GroupTree **group_b);
void write_file (void);
void write_pov10_tree (FILE *f, GroupTree *gnode, int level);
void write_pov10_texture (FILE *f, Triangle *tri);
void write_pov10_transform (FILE *f, Matrix matrix);
void write_pov10_header (FILE *f);
void write_pov10_triangle (FILE *f, Triangle *tri, int one_texture);
void write_pov10_bound (FILE *f, GroupTree *gnode);
void write_pov20_tree (FILE *f, GroupTree *gnode, int level);
void write_pov20_texture (FILE *f, Triangle *tri);
void write_pov20_transform (FILE *f, Matrix matrix);
void write_pov20_header (FILE *f);
void write_pov20_triangle (FILE *f, Triangle *tri, int one_texture);
void write_pov20_bound (FILE *f, GroupTree *gnode);
void write_vivid_tree (FILE *f, GroupTree *gnode);
void write_vivid_transform (FILE *f, Matrix matrix);
void write_vivid_texture (FILE *f, Triangle *tri);
void write_vivid_header (FILE *f);
void write_vivid_triangle (FILE *f, Triangle *tri);
void write_polyray_tree (FILE *f, GroupTree *gnode);
void write_polyray_transform (FILE *f, Matrix matrix);
void write_polyray_texture (FILE *f, Triangle *tri);
void write_polyray_header (FILE *f);
void write_polyray_triangle (FILE *f, Triangle *tri);
void update_node (GroupTree *gnode);
void sort_indexes (GroupTree *gnode);
void quick_sort (TriList2 *start, TriList2 *end, int axis);
float surf_area (float a, float b, float c);
float max_vertex (Triangle *tri, int axis);
float min_vertex (Triangle *tri, int axis);
float avg_vertex (Triangle *tri, int axis);
void build_tri_index (void);
void dump_tri_index (void);
void vert_normal (Triangle *t, Vector *norm);
void tri_normal (Triangle *t, Vector normal);
unsigned pal_lookup (float red, float green, float blue);
unsigned texture_lookup (char *texture_name);
unsigned vert_lookup (float x, float y, float z);
int degen_tri (float ax, float ay, float az, float bx, float by, float bz,
float cx, float cy, float cz);
void abortmsg (char *msg, int exit_code);
float fmin (float a, float b);
float fmax (float a, float b);
void add_ext (char *fname, char *ext, int force);
void cleanup_name (char *name);
void opt_set_format (int format)
{
if (format != POV10 && format != POV20 && format != VIVID && format != POLYRAY)
abortmsg ("ERROR: Invalid parameter passed to opt_set_format.", 1);
out_format = format;
}
void opt_set_fname (char *out_name, char *inc_name)
{
FILE *f;
strcpy (out_file, out_name);
if (strlen(inc_name) > 0)
strcpy (inc_file, inc_name);
else {
strcpy (inc_file, out_file);
switch (out_format) {
case POV10:
case POV20: add_ext (inc_file, "inc", 1);
break;
case VIVID: add_ext (inc_file, "vo", 1);
break;
case POLYRAY: add_ext (inc_file, "inc", 1);
break;
}
}
if (strcmp (out_file, inc_file) == 0)
abortmsg ("Main file and include file cannot have the same name", 1);
if ((f = fopen (out_file, "w")) == NULL