/*
 * linalg.h
 *
 *	@(#)linalg.h 1.10 97/1/19 23:18:35
 *
 * Copyright (c) 1997, Sun Microsystems Computer Company, Mountain View, CA
 *
 *			All Rights Reserved
 *
 *	This is a program for viewing and manipulating 3D objects.  It is
 *      developed by Mike M. Chow with helpful advice from many people at 
 *      SMCC, especially Scott R. Nelson.
 *
 *      Headers for linear algebra routines.
 */

#ifndef _modelviewer_linalg_
#define _modelviewer_linalg_

#define minf(x, y)  (x < y) ? x : y
#define maxf(x, y)  (x > y) ? x : y


extern double IdentityMat[16];

typedef struct Plane Plane;

/* General plane equation:  Nx*x + Ny*y + Nz*z + d = 0 */
struct Plane{
  Point normal;
  float d;
  Point p; /* p is any point on plane */
};



#define SIGN3(A) (((A)[0]<0)?4:0 | ((A)[1]<0)?2:0 | ((A)[2]<0)?1:0)

#define CROSS(C, A, B)   (C)[0] = (A)[1] * (B)[2] - (A)[2] * (B)[1]; (C)[1] = -(A)[0] * (B)[2] + (A)[2] * (B)[0];(C)[2] = (A)[0] * (B)[1] - (A)[1] * (B)[0]

float sqrtDist(Point a, Point b);
			
void   pointSet(Point p, float x, float y, float z);
float *pointAdd(Point result, Point a, Point b);
float *pointSub(Point result, Point a, Point b);
float *pointMulScalar(Point result, Point a, float b);
float *pointDivScalar(Point result, Point a, float b);
float  pointDot(Point v0,   Point v1);
void   pointCross(Point cp, Point v0, Point v1, Point v2);
float  pointLength(Point p);
void   pointNormalize(Point p);


void matInit(float a[16]);
void matMakeIdentity(float m[16]);
void matPrint(float a[16]);
void matCopy(float r[16], float a[16]);
void matTranspose(float r[16], float a[16]);
void matMult(float r[16], float a[16], float b[16]);
void matMultVec(float out[3],  float matrix[16], float in[3]);
int  matInverse(float inverse[16], float src[16]);
void planeProject(Plane *plane, Point pt, Point proj,
	     float *dist, Point error);
Plane *planeCreate(Point normal, Point p1);
Plane *planeCreate2(Point p1, Point p2, Point p3);

int ptSameSide(Point p1, Point p2, Point inPt, 
	       Point testPt, int axis);
int ptInPolygon(Point pts[], int numPts, Point testPt);
int ptInFacet(Point testPt, Facet *fptr);
int ptInFacetOrig(Point testPt, Facet *fptr);

#endif
