/****************************************************************************/
/*                                                                          */
/*  VolVis is a volume visualization system for investigating, manipulating */
/*  and rendering geometric and volumetric data.                            */
/*                                                                          */
/*  Copyright (C) 1993 by the Research Foundation of the State University   */
/*                            of New York                                   */
/*                                                                          */
/*  This program is free software; you can redistribute it and/or modify    */
/*  it under the terms of the GNU General Public License as published by    */
/*  the Free Software Foundation; either version 1, or (at your option)     */
/*  any later version.                                                      */
/*                                                                          */
/*  This program 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 this program; if not, write to the Free Software             */
/*  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.               */
/*                                                                          */
/*  For information on VolVis, contact us at:                               */
/*                                                                          */
/*                volvis@cs.sunysb.edu                         (email)      */
/*                                                                          */
/*                Lisa Sobierajski & Ricardo Avila             (US Mail)    */
/*                Department of Computer Science                            */
/*                State University of New York at Stony Brook               */
/*                Stony Brook, New York  11794-4400                         */
/*                                                                          */
/****************************************************************************/



/*
 *                  File: C_macros.h
 *                Author: Lisa Sobierajski & Rick Avila
 *                  Date:
 *           Description:
 *  Modification History:
 *
 *         who?         when?           why?
 *    -----------------------------------------------------------
 *
 */

/************************************************************************/
/*                                                                      */
/*	                      Macros					*/
/*                                                                      */
/************************************************************************/

/*	Debug Macro						*/
/*	Example: C_DEBUG( ("value = %d\n", val) );		*/
#define C_DEBUG(x)		printf x

/*    Round A Value                                             */
#define C_Round(x)              (((x) < 0.0)?((int)((x)-0.5)):((int)((x)+0.5)))

/*    Convert degrees to radians				*/
#define C_Deg_To_Rad(x)        (x * M_PI/180.0)
 
/*    Convert radians to degrees				*/
#define C_Rad_To_Deg(x)        (x * 180.0/M_PI)

/*    Square a number						*/
#define C_Square(x)            (( x ) * ( x ))

/*    Cube a number						*/
#define C_Cube(x)            (( x ) * ( x ) * ( x ))

/*    Get the sign of a number					*/
#define C_Sign(x)              (( (x) < 0 )?( -1 ):( 1 ))

/*    Is x between y and z?					*/
#define C_In_Range(x,y,z)      ((x) >= (y) && (x) <= (z))

/*    Absolute value macro 					*/
#define C_Absolute(x)             (((x) < 0)?(-(x)):(x))

/*    Floor function						*/
# define C_Floor(x)     ((x) < 0.0)?((int)((x)-1.0)):((int)(x))


/*    Cube Root Macro - If your machine doesn't have cbrt(), follow 	*/
/*    this Hewlett-Packard example.					*/
#ifdef C_HP
#define C_cbrt(x) ((x<0.0)?(-pow((-x),0.333333333333333)):(pow((x),0.333333333333333)))
#else
#define C_cbrt(x) (cbrt(x))
#endif

/*    Trilinear interpolation: x,y,z are the three weights for  */
/*    the x, y, and z directions, and a,b,c,d,e,f,g, and h are  */
/*    the 8 vertices (values) to interpolate between.           */
/*    (x, y, and z are the distances from point a along the x,  */
/*    y, and z axis respectively. )                             */
/*                                                              */
/*                                                              */
/*                         g----------------h                   */
/*            Y           /|               /|                   */
/*                       / |              / |                   */
/*                      /  |             /  |                   */
/*            |        c----------------d   |                   */
/*            |        |   |            |   |                   */
/*            |        |   |            |   |                   */
/*            |        |   |            |   |                   */
/*            |      Z |   |            |   |                   */
/*            |        |   e------------|---f                   */
/*            |     /  |  /             |  /                    */
/*            |    /   | /              | /                     */
/*            |   /    |/               |/                      */
/*            |  /     a----------------b                       */
/*            | /                                               */
/*            |/                                                */
/*            o------------------  X                            */
/*                                                              */
/*                                                              */

/*******
#define C_Trilin(x,y,z,a,b,c,d,e,f,g,h) 		\
							\
	((a)*(1.0 - (x))*(1.0 - (y))*(1.0 - (z)) + 	\
	(b)*(x)*(1.0 - (y))*(1.0 - (z)) +		\
	(c)*(1.0 - (x))*(y)*(1.0 - (z)) + 		\
	(d)*(x)*(y)*(1.0 - (z)) + 			\
	(e)*(1.0 - (x))*(1.0 - (y))*(z) + 		\
	(f)*(x)*(1.0 - (y))*(z) + 			\
	(g)*(1.0 - (x))*(y)*(z) + 			\
	(h)*(x)*(y)*(z))
*******/

#define C_Trilin(x,y,z,a,b,c,d,e,f,g,h)			\
							\
       ((((a)*(1.0 - (z))		+		\
	  (e)*(z))*(1.0 - (y))		+		\
	 ((c)*(1.0 - (z))		+		\
	  (g)*(z))*(y))*(1.0-(x))	+		\
	(((b)*(1.0 - (z))		+		\
	  (f)*(z))*(1.0 - (y))		+		\
	 ((d)*(1.0 - (z))		+		\
	  (h)*(z))*(y))*(x))


	


/*    Bilinear interpolation: x and y are the two weights for   */
/*    the x and y directions, and a,b,c, and d, are the 4       */
/*    vertices (values) to interpolate between. (x and y are    */
/*    the distances from point a along the x and y axis         */
/*    respectively. )                                           */
/*                                                              */
/*                                                              */
/*                                                              */
/*            Y                                                 */
/*                                                              */
/*                                                              */
/*            |        c----------------d                       */
/*            |        |                |                       */
/*            |        |                |                       */
/*            |        |                |                       */
/*            |        |                |                       */
/*            |        |                |                       */
/*            |        |                |                       */
/*            |        |                |                       */
/*            |        |                |                       */
/*            |        a----------------b                       */
/*            |                                                 */
/*            |                                                 */
/*            o------------------  X                            */
/*                                                              */
/*                                                              */
#define C_Bilin(x,y,a,b,c,d) 		 		\
							\
	((a)*(1.0 - (x))*(1.0 - (y)) + 			\
	(b)*(x)*(1.0 - (y)) +				\
	(c)*(1.0 - (x))*(y) + 				\
	(d)*(x)*(y));  					\


/*    Normalize a vector.  t is a temporary variable.		*/
#define C_Normalize(a,b,c,t)			\
 						\
	t = (float) sqrt( (double)C_Square(a) + \
			  (double)C_Square(b) + \
			  (double)C_Square(c) ),\
	a /= t,					\
	b /= t,					\
	c /= t

# define C_Set_Orig(A,X,Y,Z)				\
							\
		A.origin.x = X,				\
		A.origin.y = Y,				\
		A.origin.z = Z

# define C_Set_Axes(A,XX,XY,XZ,YX,YY,YZ,ZX,ZY,ZZ)	\
							\
		A.x_axis.x = XX,			\
		A.x_axis.y = XY,			\
		A.x_axis.z = XZ,			\
		A.y_axis.x = YX,			\
		A.y_axis.y = YY,			\
		A.y_axis.z = YZ,			\
		A.z_axis.x = ZX,			\
		A.z_axis.y = ZY,			\
		A.z_axis.z = ZZ

# define C_Set_Pos(A,X,Y,Z)				\
							\
		A.x = X,				\
		A.y = Y,				\
		A.z = Z


# define C_Set_Color(A,R,G,B)				\
							\
		A.red 	= R,				\
		A.green = G,				\
		A.blue 	= B
		
# define C_Set_Colorptr(A,R,G,B)			\
							\
		A->red 	 = R,				\
		A->green = G,				\
		A->blue  = B
		

# define C_New(T)	(T *) malloc( sizeof(T) );


/************************************************************************/
/*                                                                      */
/*                      Macros for Parallel Rendering                   */
/*                                                                      */
/************************************************************************/

#ifdef C_PARALLEL_SGI
#define C_Parallel_Get_Num_Processors()		m_get_numprocs()
#define C_Parallel_Set_Num_Processors(x)	m_set_procs(x)
#define C_Parallel_Get_Processor_Id()		m_get_myid()
#define C_Parallel_Process(x)			m_fork x
#define C_Parallel_Kill_Processes()		m_kill_procs()
#define C_Parallel_Lock()			m_lock()
#define C_Parallel_Unlock()			m_unlock()
#define C_Parallel_Park()			m_park_procs()
#define C_Parallel_Release()			m_rele_procs()
#define C_Parallel_Sync()			m_sync()
#endif

#ifdef C_SGI
#define C_Parallel_Get_Num_Processors()		1	
#define C_Parallel_Set_Num_Processors(x)	
#define C_Parallel_Get_Processor_Id()	        0	
#define C_Parallel_Process(x)			C_Single_Processor x
#define C_Parallel_Kill_Processes()		
#define C_Parallel_Lock()			
#define C_Parallel_Unlock()			
#define C_Parallel_Park()			
#define C_Parallel_Release()			
#define C_Parallel_Sync()		
#endif

#ifdef C_HP
#define C_Parallel_Get_Num_Processors()		1	
#define C_Parallel_Set_Num_Processors(x)	
#define C_Parallel_Get_Processor_Id()	        0	
#define C_Parallel_Process(x)			C_Single_Processor x
#define C_Parallel_Kill_Processes()		
#define C_Parallel_Lock()			
#define C_Parallel_Unlock()			
#define C_Parallel_Park()			
#define C_Parallel_Release()			
#define C_Parallel_Sync()		
#endif

#ifdef C_SUN
#define C_Parallel_Get_Num_Processors()		1	
#define C_Parallel_Set_Num_Processors(x)	
#define C_Parallel_Get_Processor_Id()	        0	
#define C_Parallel_Process(x)			C_Single_Processor x
#define C_Parallel_Kill_Processes()		
#define C_Parallel_Lock()			
#define C_Parallel_Unlock()			
#define C_Parallel_Park()			
#define C_Parallel_Release()			
#define C_Parallel_Sync()		
#endif

#ifndef C_SUN
#ifndef C_SGI
#ifndef C_HP
#define C_Parallel_Get_Num_Processors()		1	
#define C_Parallel_Set_Num_Processors(x)	
#define C_Parallel_Get_Processor_Id()	        0	
#define C_Parallel_Process(x)			C_Single_Processor x
#define C_Parallel_Kill_Processes()		
#define C_Parallel_Lock()			
#define C_Parallel_Unlock()			
#define C_Parallel_Park()			
#define C_Parallel_Release()			
#define C_Parallel_Sync()		
#endif
#endif
#endif



/* Assemble Pixel Value Macro  */
#ifdef C_SGI
#define C_Get_Pixel(j) (((j.red & 0xff00) >> 8) + (j.green & 0xff00) + ((j.blue & 0xff00) << 8))
#endif

#ifdef C_SUN
#define C_Get_Pixel(j) (((j.red & 0xff00) >> 8) + (j.green & 0xff00) + ((j.blue & 0xff00) << 8))
#endif

#ifdef C_HP
#define C_Get_Pixel(j) (((j.red & 0xff00) << 8) + (j.green & 0xff00) + ((j.blue & 0xff00) >> 8))
#endif


/************************************************************************/
/*                                                                      */
/*                      Navigator Macros                                */
/*                                                                      */
/************************************************************************/

# define C_On_Surface(P,L,H,X,Y,Z)      (!(C_In_Range(*(P+X),L,H)) || \
                                         !(C_In_Range(*(P-X),L,H)) || \
                                         !(C_In_Range(*(P+Y),L,H)) || \
                                         !(C_In_Range(*(P-Y),L,H)) || \
                                         !(C_In_Range(*(P+Z),L,H)) || \
                                         !(C_In_Range(*(P-Z),L,H)))

# define C_Get_Grey_Normal(P,A,B,C,X,Y,Z) A = (float)(*(P+X))-(float)(*(P-X));\
                                          B = (float)(*(P+Y))-(float)(*(P-Y));\
                                          C = (float)(*(P+Z))-(float)(*(P-Z))

#ifdef C_MOTIF
#define		C_GetWindow(w)	XtWindow(w)
#define		C_GetDisplay(w)	XtDisplay(w)
#endif

#ifdef C_OL
#define		C_GetWindow(w)	(XID)xv_get( w, XV_XID)
#define		C_GetDisplay(w) XV_DISPLAY_FROM_WINDOW(w)
#endif

#ifdef C_MOTIF
#define C_Destroy_UIWin(w)      XtDestroyWidget(w)
#endif

#ifndef C_MOTIF
#define C_Destroy_UIWin(w)
#endif
