/*
    Copyright 2005-2010 Intel Corporation.  All Rights Reserved.

    This file is part of Threading Building Blocks.

    Threading Building Blocks is free software; you can redistribute it
    and/or modify it under the terms of the GNU General Public License
    version 2 as published by the Free Software Foundation.

    Threading Building Blocks is distributed in the hope that it will be
    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Threading Building Blocks; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

    As a special exception, you may use this file as part of a free software
    library without restriction.  Specifically, if other files instantiate
    templates or use macros or inline functions from this file, or you compile
    this file and link it with other files to produce an executable, this
    file does not by itself cause the resulting executable to be covered by
    the GNU General Public License.  This exception does not however
    invalidate any other reasons why the executable file might be covered by
    the GNU General Public License.
*/

/*
    The original source for this example is
    Copyright (c) 1994-2008 John E. Stone
    All rights reserved.

    Redistribution and use in source and binary forms, with or without
    modification, are permitted provided that the following conditions
    are met:
    1. Redistributions of source code must retain the above copyright
       notice, this list of conditions and the following disclaimer.
    2. Redistributions in binary form must reproduce the above copyright
       notice, this list of conditions and the following disclaimer in the
       documentation and/or other materials provided with the distribution.
    3. The name of the author may not be used to endorse or promote products
       derived from this software without specific prior written permission.

    THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
    OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
    OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
    SUCH DAMAGE.
*/

#if __MINGW32__
#include <malloc.h>
#elif _WIN32
#include <malloc.h>
#define alloca _alloca
#elif __FreeBSD__
#include <stdlib.h>
#else
#include <alloca.h>
#endif

/* 
 * types.h - This file contains all of the type definitions for the raytracer
 *
 *  $Id: types.h,v 1.2 2007-02-22 17:54:16 dpoulsen Exp $
 */

#define MAXOCTNODES 25       /* subdivide octants /w > # of children */
#define SPEPSILON 0.000001   /* amount to crawl down a ray           */
#define EPSILON   0.000001   /* amount to crawl down a ray           */
#define TWOPI 6.2831853      /* guess                                */
#define FHUGE 1e18           /* biggest fp number we can represent   */

/* Maximum internal table sizes */
/* Use prime numbers for best memory system performance */
#define INTTBSIZE 1024       /* maximum intersections we can hold    */ 
#define MAXLIGHTS 39         /* maximum number of lights in a scene  */
#define MAXIMGS   39         /* maxiumum number of distinct images   */
#define RPCQSIZE  113	     /* number of RPC messages to queue      */

/* Parameter values for rt_boundmode() */
#define RT_BOUNDING_DISABLED 0  /* spatial subdivision/bounding disabled */
#define RT_BOUNDING_ENABLED  1  /* spatial subdivision/bounding enabled  */

/* Parameter values for rt_displaymode() */
#define RT_DISPLAY_DISABLED  0  /* video output enabled  */
#define RT_DISPLAY_ENABLED   1  /* video output disabled */

/* Ray flags */
#define RT_RAY_REGULAR   1
#define RT_RAY_SHADOW    2
#define RT_RAY_BOUNDED   4
#define RT_RAY_FINISHED  8

#ifdef USESINGLEFLT
typedef float flt;   /* generic floating point number, using float */
#else
typedef double flt;  /* generic floating point number, using double */
#endif

typedef unsigned char byte; /* 1 byte */
typedef signed int word;    /* 32 bit integer */

typedef struct {
   flt x;        /* X coordinate value */
   flt y;        /* Y coordinate value */
   flt z;        /* Z coordinate value */
} vector;

typedef struct {
   flt r;        /* Red component   */
   flt g;        /* Green component */
   flt b;        /* Blue component  */
} color;

typedef struct {
   byte r;       /* Red component   */
   byte g;       /* Green component */
   byte b;       /* Blue component  */
} bytecolor;

typedef struct {         /* Raw 24 bit image structure, for tga, ppm etc */
  int loaded;            /* image memory residence flag    */
  int xres;              /* image X axis size              */
  int yres;              /* image Y axis size              */
  int bpp;               /* image bits per pixel           */
  char name[96];         /* image filename (with path)     */
  unsigned char * data;  /* pointer to raw byte image data */
} rawimage;

typedef struct {         /* Scalar Volume Data */
  int loaded;            /* Volume data memory residence flag */
  int xres;		 /* volume X axis size                */
  int yres;		 /* volume Y axis size                */
  int zres;		 /* volume Z axis size                */
  flt opacity;		 /* opacity per unit length           */
  char name[96];         /* Volume data filename              */
  unsigned char * data;  /* pointer to raw byte volume data   */
} scalarvol;
 
typedef struct {
  color (* texfunc)(void *, void *, void *);
  int shadowcast;  /* does the object cast a shadow */
  int islight;	   /* light flag... */
  color col;       /* base object color */
  flt ambient;     /* ambient lighting */
  flt diffuse; 	   /* diffuse reflection */
  flt phong;       /* phong specular highlights */
  flt phongexp;    /* phong exponent/shininess factor */
  int phongtype;   /* phong type: 0 == plastic, nonzero == metal */
  flt specular;    /* specular reflection */
  flt opacity;     /* how opaque the object is */ 
  vector ctr;      /* origin of texture */
  vector rot;      /* rotation of texture about origin */
  vector scale;    /* scale of texture in x,y,z */
  vector uaxs;	   /* planar map U axis */
  vector vaxs;	   /* planar map V axis */
  void * img;      /* pointer to image for image mapping */
  void * obj;      /* object ptr, hack for volume shaders for now */
} texture;

typedef struct {
  void (* intersect)(void *, void *);              /* intersection func ptr  */
  void (* normal)(void *, void *, void *, void *); /* normal function ptr    */
  int (* bbox)(void *, vector *, vector *);        /* return the object bbox */
  void (* free)(void *);                           /* free the object        */
} object_methods;
 
typedef struct {
  unsigned int id;                      /* Unique Object serial number    */
  void * nextobj;                       /* pointer to next object in list */ 
  object_methods * methods;             /* this object's methods          */
  texture * tex;                        /* object texture                 */
} object; 

typedef struct {
  object * obj;  /* to object we hit                        */ 
  flt t;         /* distance along the ray to the hit point */
} intersection;

typedef struct {
  int num;                      /* number of intersections    */
  intersection closest;         /* closest intersection > 0.0 */
  intersection list[INTTBSIZE]; /* list of all intersections  */ 
} intersectstruct;

typedef struct {
  char outfilename[200];     /* name of the output image                */
  unsigned char * rawimage;  /* pointer to a raw rgb image to be stored */
  int hres;                  /* horizontal output image resolution      */
  int vres;                  /* vertical output image resolution        */
  flt aspectratio;           /* aspect ratio of output image            */
  int raydepth;              /* maximum recursion depth                 */
  int antialiasing;          /* number of antialiasing rays to fire     */
  int verbosemode;           /* verbose reporting flag                  */
  int boundmode;             /* automatic spatial subdivision flag      */
  int boundthresh;           /* threshold number of subobjects          */
  int displaymode;           /* run-time X11 display flag               */
  vector camcent;            /* center of the camera in world coords    */
  vector camviewvec;         /* view direction of the camera  (Z axis)  */
  vector camrightvec;        /* right axis for the camera     (X axis)  */
  vector camupvec;           /* up axis for the camera        (Y axis)  */
  flt camzoom;               /* zoom factor for the camera              */
  color background;          /* scene background color                  */
} scenedef;

typedef struct {
   intersectstruct * intstruct; /* ptr to thread's intersection data       */ 
   unsigned int depth;   /* levels left to recurse.. (maxdepth - curdepth) */
   unsigned int flags;   /* ray flags, any special treatment needed etc    */
   unsigned int serial;  /* serial number of the ray                       */
   unsigned int * mbox;  /* mailbox array for optimizing intersections     */
   vector o;             /* origin of the ray X,Y,Z                        */
   vector d;             /* normalized direction of the ray                */
   flt maxdist;          /* maximum distance to search for intersections   */
   vector s;		 /* startpoint of the ray (may differ from origin  */
   vector e;             /* endpoint of the ray if bounded                 */
   scenedef * scene;     /* pointer to the scene, for global parms such as */
                         /* background colors etc                          */
} ray;

typedef struct {
  int type;      /* RPC call type            */
  int from;      /* Sending processor        */
  int len;       /* length of parms in bytes */
  void * parms;  /* Parameters to RPC        */
} rpcmsg;
