summaryrefslogtreecommitdiffstats
path: root/sdl/math3d.c
diff options
context:
space:
mode:
Diffstat (limited to 'sdl/math3d.c')
-rw-r--r--sdl/math3d.c614
1 files changed, 84 insertions, 530 deletions
diff --git a/sdl/math3d.c b/sdl/math3d.c
index 7baad85..53e0fff 100644
--- a/sdl/math3d.c
+++ b/sdl/math3d.c
@@ -1,8 +1,8 @@
-/* revision 5 */
+/* revision 6 */
-/* @2009 Kamil Kaminski
+/* @2010 Kamil Kaminski
*
- * this code is not yet endian aware
+ * this code is not yet endian aware, and it won't be, screw powerpc
* the style of the syntax is original k&r except there's \n
* after the opening { and extra space after if statement,
* and for/while loops
@@ -10,7 +10,7 @@
#include "math3d.h"
-void m3dFindNormal(M3DVector3f result, const M3DVector3f point1,
+void m3dFindNormalf(M3DVector3f result, const M3DVector3f point1,
const M3DVector3f point2, const M3DVector3f point3)
{
M3DVector3f v1, v2;
@@ -27,10 +27,22 @@ void m3dFindNormal(M3DVector3f result, const M3DVector3f point1,
v2[2] = point2[2] - point3[2];
/* take the cross product of the two vectors to get the normal vector */
- m3dCrossProduct(result, v1, v2);
+ m3dCrossProductf(result, v1, v2);
}
-void m3dLoadIdentity44(M3DMatrix44f m) /* 4x4 float */
+
+void m3dLoadIdentity33f(M3DMatrix33f m)
+{
+ /* don't be fooled, this is still column major */
+ static M3DMatrix33f identity = { 1.0f, 0.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f };
+
+ memcpy(m, identity, sizeof(M3DMatrix33f));
+}
+
+
+void m3dLoadIdentity44f(M3DMatrix44f m) /* 4x4 float */
{
/* don't be fooled, this is still column major */
static M3DMatrix44f identity = { 1.0f, 0.0f, 0.0f, 0.0f,
@@ -41,8 +53,35 @@ void m3dLoadIdentity44(M3DMatrix44f m) /* 4x4 float */
memcpy(m, identity, sizeof(M3DMatrix44f));
}
+/* calculate the plane equation of the plane that the three specified points lay in
+ * the points are given in clockwise winding order, with normal pointing out of clockwise face
+ * planeEq contains the a, b, c, and d of the plane equation coefficients
+ */
+void m3dGetPlaneEquationf(M3DVector4f planeEq, const M3DVector3f p1,
+ const M3DVector3f p2, const M3DVector3f p3)
+{
+ /* get two vectors... do the cross product */
+ M3DVector3f v1, v2;
+
+ /* v1 = p3 - p1 */
+ v1[0] = p3[0] - p1[0];
+ v1[1] = p3[1] - p1[1];
+ v1[2] = p3[2] - p1[2];
+
+ /* v2 = p2 - p1 */
+ v2[0] = p2[0] - p1[0];
+ v2[1] = p2[1] - p1[1];
+ v2[2] = p2[2] - p1[2];
+
+ /* unit normal to plane - Not sure which is the best way here */
+ m3dCrossProductf(planeEq, v1, v2);
+ m3dNormalizeVectorf(planeEq);
+ /* back substitute to get d */
+ planeEq[3] = -(planeEq[0] * p3[0] + planeEq[1] * p3[1] + planeEq[2] * p3[2]);
+}
+
/* creates a 4x4 rotation matrix, takes radians not degrees */
-void m3dRotationMatrix44(M3DMatrix44f m, float angle, float x, float y, float z)
+void m3dRotationMatrix44f(M3DMatrix44f m, float angle, float x, float y, float z)
{
float mag, s, c;
float xx, yy, zz, xy, yz, zx, xs, ys, zs, one_c;
@@ -55,7 +94,7 @@ void m3dRotationMatrix44(M3DMatrix44f m, float angle, float x, float y, float z)
/* identity matrix */
if (mag == 0.0f)
{
- m3dLoadIdentity44(m);
+ m3dLoadIdentity44f(m);
return;
}
@@ -101,373 +140,50 @@ void m3dRotationMatrix44(M3DMatrix44f m, float angle, float x, float y, float z)
#undef M
}
-/* draw a torus (doughnut), using the current 1d texture for light shading */
-/* this funct accepts 4x4 trans matrix to be applied to the vertices */
-void gltDrawTorus(GLfloat majorRadius, GLfloat minorRadius, GLint numMajor,
- GLint numMinor)
-{
- M3DVector3f vNormal;
- double majorStep = 2.0f * M3D_PI / numMajor;
- double minorStep = 2.0f * M3D_PI / numMinor;
- int i, j;
-
- for (i = 0; i < numMajor; ++i)
- {
- double a0 = i * majorStep;
- double a1 = a0 + majorStep;
- GLfloat x0 = (GLfloat) cos(a0);
- GLfloat y0 = (GLfloat) sin(a0);
- GLfloat x1 = (GLfloat) cos(a1);
- GLfloat y1 = (GLfloat) sin(a1);
-
- glBegin(GL_TRIANGLE_STRIP);
- for (j = 0; j <= numMinor; ++j)
- {
- double b = j * minorStep;
- GLfloat c = (GLfloat) cos(b);
- GLfloat r = minorRadius * c + majorRadius;
- GLfloat z = minorRadius * (GLfloat) sin(b);
-
- glTexCoord2f((float) (i) / (float) (numMajor), (float) (j) \
- / (float) (numMinor));
- vNormal[0] = x0 * c;
- vNormal[1] = y0 * c;
- vNormal[2] = z / minorRadius;
- m3dNormalizeVector(vNormal);
- glNormal3fv(vNormal);
- glVertex3f(x0 * r, y0 * r, z);
-
- glTexCoord2f((float) (i + 1) / (float) (numMajor), (float) (j) \
- / (float) (numMinor));
- vNormal[0] = x1 * c;
- vNormal[1] = y1 * c;
- vNormal[2] = z / minorRadius;
- m3dNormalizeVector(vNormal);
- glNormal3fv(vNormal);
- glVertex3f(x1 * r, y1 * r, z);
- }
- glEnd();
- }
-}
-
-/* this function just specifically draws the jet */
-/* FIXME needs to accepts parameters of location and lightning */
-void DrawJet(int nShadow)
-{
- M3DVector3f vNormal;
-
- /* nose cone, set material color, note we only have to set to black
- * for the shadow once
- */
- if (nShadow == 0)
- glColor3ub(128, 128, 128);
- else
- glColor3ub(0, 0, 0);
-
- /* nose cone, points straight down, set material color */
- /* follow few lines use manual approach */
- glBegin(GL_TRIANGLES);
- glNormal3f(0.0f, -1.0f, 0.0f);
- glNormal3f(0.0f, -1.0f, 0.0f);
- glVertex3f(0.0f, 0.0f, 60.0f);
- glVertex3f(-15.0f, 0.0f, 30.0f);
- glVertex3f(15.0f, 0.0f, 30.0f);
-
- /* verticies for this panel */
- {
- M3DVector3f vPoints[3] = { {15.0f, 0.0f, 30.0f}
- ,
- {0.0f, 15.0f, 30.0f}
- ,
- {0.0f, 0.0f, 60.0f}
- };
-
- /* calculate the normal for the plane */
- m3dFindNormal(vNormal, vPoints[0], vPoints[1], vPoints[2]);
- glNormal3fv(vNormal);
- glVertex3fv(vPoints[0]);
- glVertex3fv(vPoints[1]);
- glVertex3fv(vPoints[2]);
- }
-
- {
- M3DVector3f vPoints[3] = { {0.0f, 0.0f, 60.0f}
- ,
- {0.0f, 15.0f, 30.0f}
- ,
- {-15.0f, 0.0f, 30.0f}
- };
-
- m3dFindNormal(vNormal, vPoints[0], vPoints[1], vPoints[2]);
- glNormal3fv(vNormal);
- glVertex3fv(vPoints[0]);
- glVertex3fv(vPoints[1]);
- glVertex3fv(vPoints[2]);
- }
-
- /* body of the plane */
- {
- M3DVector3f vPoints[3] = { {-15.0f, 0.0f, 30.0f}
- ,
- {0.0f, 15.0f, 30.0f}
- ,
- {0.0f, 0.0f, -56.0f}
- };
-
- m3dFindNormal(vNormal, vPoints[0], vPoints[1], vPoints[2]);
- glNormal3fv(vNormal);
- glVertex3fv(vPoints[0]);
- glVertex3fv(vPoints[1]);
- glVertex3fv(vPoints[2]);
- }
-
- {
- M3DVector3f vPoints[3] = { {0.0f, 0.0f, -56.0f}
- ,
- {0.0f, 15.0f, 30.0f}
- ,
- {15.0f, 0.0f, 30.0f}
- };
-
- m3dFindNormal(vNormal, vPoints[0], vPoints[1], vPoints[2]);
- glNormal3fv(vNormal);
- glVertex3fv(vPoints[0]);
- glVertex3fv(vPoints[1]);
- glVertex3fv(vPoints[2]);
- }
-
- glNormal3f(0.0f, -1.0f, 0.0f);
- glVertex3f(15.0f, 0.0f, 30.0f);
- glVertex3f(-15.0f, 0.0f, 30.0f);
- glVertex3f(0.0f, 0.0f, -56.0f);
-
- /* left wing, large triangle for bottom of wing */
- {
- M3DVector3f vPoints[3] = { {0.0f, 2.0f, 27.0f}
- ,
- {-60.0f, 2.0f, -8.0f}
- ,
- {60.0f, 2.0f, -8.0f}
- };
-
- m3dFindNormal(vNormal, vPoints[0], vPoints[1], vPoints[2]);
- glNormal3fv(vNormal);
- glVertex3fv(vPoints[0]);
- glVertex3fv(vPoints[1]);
- glVertex3fv(vPoints[2]);
- }
-
- {
- M3DVector3f vPoints[3] = { {60.0f, 2.0f, -8.0f}
- ,
- {0.0f, 7.0f, -8.0f}
- ,
- {0.0f, 2.0f, 27.0f}
- };
-
- m3dFindNormal(vNormal, vPoints[0], vPoints[1], vPoints[2]);
- glNormal3fv(vNormal);
- glVertex3fv(vPoints[0]);
- glVertex3fv(vPoints[1]);
- glVertex3fv(vPoints[2]);
- }
-
- {
- M3DVector3f vPoints[3] = { {60.0f, 2.0f, -8.0f}
- ,
- {-60.0f, 2.0f, -8.0f}
- ,
- {0.0f, 7.0f, -8.0f}
- };
-
- m3dFindNormal(vNormal, vPoints[0], vPoints[1], vPoints[2]);
- glNormal3fv(vNormal);
- glVertex3fv(vPoints[0]);
- glVertex3fv(vPoints[1]);
- glVertex3fv(vPoints[2]);
- }
-
- {
- M3DVector3f vPoints[3] = { {0.0f, 2.0f, 27.0f}
- ,
- {0.0f, 7.0f, -8.0f}
- ,
- {-60.0f, 2.0f, -8.0f}
- };
-
- m3dFindNormal(vNormal, vPoints[0], vPoints[1], vPoints[2]);
- glNormal3fv(vNormal);
- glVertex3fv(vPoints[0]);
- glVertex3fv(vPoints[1]);
- glVertex3fv(vPoints[2]);
- }
-
- /* tail section */
- /* bottom of back fin */
- glNormal3f(0.0f, -1.0f, 0.0f);
- glVertex3f(-30.0f, -0.50f, -57.0f);
- glVertex3f(30.0f, -0.50f, -57.0f);
- glVertex3f(0.0f, -0.50f, -40.0f);
-
- {
- M3DVector3f vPoints[3] = { {0.0f, -0.5f, -40.0f}
- ,
- {30.0f, -0.5f, -57.0f}
- ,
- {0.0f, 4.0f, -57.0f}
- };
-
- m3dFindNormal(vNormal, vPoints[0], vPoints[1], vPoints[2]);
- glNormal3fv(vNormal);
- glVertex3fv(vPoints[0]);
- glVertex3fv(vPoints[1]);
- glVertex3fv(vPoints[2]);
- }
-
- {
- M3DVector3f vPoints[3] = { {0.0f, 4.0f, -57.0f}
- ,
- {-30.0f, -0.5f, -57.0f}
- ,
- {0.0f, -0.5f, -40.0f}
- };
-
- m3dFindNormal(vNormal, vPoints[0], vPoints[1], vPoints[2]);
- glNormal3fv(vNormal);
- glVertex3fv(vPoints[0]);
- glVertex3fv(vPoints[1]);
- glVertex3fv(vPoints[2]);
- }
-
- {
- M3DVector3f vPoints[3] = { {30.0f, -0.5f, -57.0f}
- ,
- {-30.0f, -0.5f, -57.0f}
- ,
- {0.0f, 4.0f, -57.0f}
- };
-
- m3dFindNormal(vNormal, vPoints[0], vPoints[1], vPoints[2]);
- glNormal3fv(vNormal);
- glVertex3fv(vPoints[0]);
- glVertex3fv(vPoints[1]);
- glVertex3fv(vPoints[2]);
- }
-
- {
- M3DVector3f vPoints[3] = { {0.0f, 0.5f, -40.0f}
- ,
- {3.0f, 0.5f, -57.0f}
- ,
- {0.0f, 25.0f, -65.0f}
- };
-
- m3dFindNormal(vNormal, vPoints[0], vPoints[1], vPoints[2]);
- glNormal3fv(vNormal);
- glVertex3fv(vPoints[0]);
- glVertex3fv(vPoints[1]);
- glVertex3fv(vPoints[2]);
- }
-
- {
- M3DVector3f vPoints[3] = { {0.0f, 25.0f, -65.0f}
- ,
- {-3.0f, 0.5f, -57.0f}
- ,
- {0.0f, 0.5f, -40.0f}
- };
-
- m3dFindNormal(vNormal, vPoints[0], vPoints[1], vPoints[2]);
- glNormal3fv(vNormal);
- glVertex3fv(vPoints[0]);
- glVertex3fv(vPoints[1]);
- glVertex3fv(vPoints[2]);
- }
-
- {
- M3DVector3f vPoints[3] = { {3.0f, 0.5f, -57.0f}
- ,
- {-3.0f, 0.5f, -57.0f}
- ,
- {0.0f, 25.0f, -65.0f}
- };
-
- m3dFindNormal(vNormal, vPoints[0], vPoints[1], vPoints[2]);
- glNormal3fv(vNormal);
- glVertex3fv(vPoints[0]);
- glVertex3fv(vPoints[1]);
- glVertex3fv(vPoints[2]);
- }
-
- glEnd();
-}
-
-void gltDrawUnitAxes(void)
+/* create a projection to "squish" an object into the plane.
+ * use m3dGetPlaneEquationf(planeEq, point1, point2, point3); to get a plane equation
+ */
+void m3dMakePlanarShadowMatrixf(M3DMatrix44f proj, const M3DVector4f planeEq,
+ const M3DVector3f vLightPos)
{
- GLUquadricObj *pObj; /* temporary, used for quadrics */
-
- /* measurements */
- float fAxisRadius = 0.025f;
- float fAxisHeight = 1.0f;
- float fArrowRadius = 0.06f;
- float fArrowHeight = 0.1f;
-
- /* setup the quadric object */
- pObj = gluNewQuadric();
- gluQuadricDrawStyle(pObj, GLU_FILL);
- gluQuadricNormals(pObj, GLU_SMOOTH);
- gluQuadricOrientation(pObj, GLU_OUTSIDE);
- gluQuadricTexture(pObj, GLU_FALSE);
-
- /* draw the blue z axis first with arrowed head */
- glColor3f(0.0f, 0.0f, 1.0f);
- gluCylinder(pObj, fAxisRadius, fAxisRadius, fAxisHeight, 10, 1);
- glPushMatrix();
- glTranslatef(0.0f, 0.0f, 1.0f);
- gluCylinder(pObj, fArrowRadius, 0.0f, fArrowHeight, 10, 1);
- glRotatef(180.0f, 1.0f, 0.0f, 0.0f);
- gluDisk(pObj, fAxisRadius, fArrowRadius, 10, 1);
- glPopMatrix();
-
- /* draw the red x axis 2nd with arrowed head */
- glColor3f(1.0f, 0.0f, 0.0f);
- glPushMatrix();
- glRotatef(90.0f, 0.0f, 1.0f, 0.0f);
- gluCylinder(pObj, fAxisRadius, fAxisRadius, fAxisHeight, 10, 1);
- glPushMatrix();
- glTranslatef(0.0f, 0.0f, 1.0f);
- gluCylinder(pObj, fArrowRadius, 0.0f, fArrowHeight, 10, 1);
- glRotatef(180.0f, 0.0f, 1.0f, 0.0f);
- gluDisk(pObj, fAxisRadius, fArrowRadius, 10, 1);
- glPopMatrix();
- glPopMatrix();
-
- /* draw the green y axis 3rd with arrowed head */
- glColor3f(0.0f, 1.0f, 0.0f);
- glPushMatrix();
- glRotatef(-90.0f, 1.0f, 0.0f, 0.0f);
- gluCylinder(pObj, fAxisRadius, fAxisRadius, fAxisHeight, 10, 1);
- glPushMatrix();
- glTranslatef(0.0f, 0.0f, 1.0f);
- gluCylinder(pObj, fArrowRadius, 0.0f, fArrowHeight, 10, 1);
- glRotatef(180.0f, 1.0f, 0.0f, 0.0f);
- gluDisk(pObj, fAxisRadius, fArrowRadius, 10, 1);
- glPopMatrix();
- glPopMatrix();
-
- /* white sphere at origin */
- glColor3f(1.0f, 1.0f, 1.0f);
- gluSphere(pObj, 0.05f, 15, 15);
-
- /* delete the quadric */
- gluDeleteQuadric(pObj);
+ /* these just make the code below easier to read */
+ float a = planeEq[0];
+ float b = planeEq[1];
+ float c = planeEq[2];
+ float d = planeEq[3];
+
+ float dx = -vLightPos[0];
+ float dy = -vLightPos[1];
+ float dz = -vLightPos[2];
+
+ /* now build the projection matrix */
+ proj[0] = b * dy + c * dz;
+ proj[1] = -a * dy;
+ proj[2] = -a * dz;
+ proj[3] = 0.0;
+
+ proj[4] = -b * dx;
+ proj[5] = a * dx + c * dz;
+ proj[6] = -b * dz;
+ proj[7] = 0.0;
+
+ proj[8] = -c * dx;
+ proj[9] = -c * dy;
+ proj[10] = a * dx + b * dy;
+ proj[11] = 0.0;
+
+ proj[12] = -d * dx;
+ proj[13] = -d * dy;
+ proj[14] = -d * dz;
+ proj[15] = a * dx + b * dy + c * dz;
+ /* shadow matrix ready */
}
#define A(row,col) a[(col<<2)+row]
#define B(row,col) b[(col<<2)+row]
#define P(row,col) product[(col<<2)+row]
-void m3dMatrixMultiply44(M3DMatrix44f product, const M3DMatrix44f a,
+void m3dMatrixMultiply44f(M3DMatrix44f product, const M3DMatrix44f a,
const M3DMatrix44f b)
{
int i;
@@ -485,165 +201,3 @@ void m3dMatrixMultiply44(M3DMatrix44f product, const M3DMatrix44f a,
#undef B
#undef P
-
-/*************************************************************/
-/* unrelated functions that do not have much to do with math */
-/* */
-/*************************************************************/
-
-GLint gltWriteTGA(const char *szFileName)
-{
- FILE *pFile; /* file pointer */
- TGAHEADER tgaHeader; /* tga file header */
- unsigned long lImageSize; /* size in bytes of image */
- GLbyte *pBits = NULL; /* pointer to bits */
- GLint iViewport[4]; /* viewport in pixels */
- GLenum lastBuffer; /* storage for the current read buffer setting */
-
- /* get the viewport dimensions */
- glGetIntegerv(GL_VIEWPORT, iViewport);
-
- /* how big is the image going to be (targas are tightly packed) */
- lImageSize = iViewport[2] * 3 * iViewport[3];
-
- /* allocate block, if this doesn't work, go home */
- pBits = (GLbyte *) malloc(lImageSize);
- if (pBits == NULL)
- {
- perror("malloc");
- return 0;
- }
-
- /* read bits from color buffer */
- glPixelStorei(GL_PACK_ALIGNMENT, 1);
- glPixelStorei(GL_PACK_ROW_LENGTH, 0);
- glPixelStorei(GL_PACK_SKIP_ROWS, 0);
- glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
-
- /* get the current read buffer setting and save it, switch to
- * the front buffer and do the read operation, finally, restore
- * the read buffer state
- */
- glGetIntegerv(GL_READ_BUFFER, (GLint *) &lastBuffer);
- glReadBuffer(GL_FRONT);
- glReadPixels(0, 0, iViewport[2], iViewport[3], GL_BGR_EXT,
- GL_UNSIGNED_BYTE, pBits);
- glReadBuffer(lastBuffer);
-
- /* initialize the targa header */
- tgaHeader.identsize = 0;
- tgaHeader.colorMapType = 0;
- tgaHeader.imageType = 2;
- tgaHeader.colorMapStart = 0;
- tgaHeader.colorMapLength = 0;
- tgaHeader.colorMapBits = 0;
- tgaHeader.xstart = 0;
- tgaHeader.ystart = 0;
- tgaHeader.width = iViewport[2];
- tgaHeader.height = iViewport[3];
- tgaHeader.bits = 24;
- tgaHeader.descriptor = 0;
-
- /* attempt to open the file */
- pFile = fopen(szFileName, "wb");
- if (pFile == NULL)
- {
- perror("fopen");
- free(pBits); /* free buffer and return error */
- return 0;
- }
-
- /* write the header */
- fwrite(&tgaHeader, sizeof(TGAHEADER), 1, pFile);
-
- /* write the image data */
- fwrite(pBits, lImageSize, 1, pFile);
-
- /* free temporary buffer and close the file */
- free(pBits);
- fclose(pFile);
-
- return 1;
-}
-
-GLbyte *gltLoadTGA(const char *szFileName, GLint *iWidth, GLint *iHeight,
- GLint *iComponents, GLenum *eFormat)
-{
- FILE *pFile; /* file pointer */
- TGAHEADER tgaHeader; /* TGA file header */
- unsigned long lImageSize; /* size in bytes of image */
- short sDepth; /* pixel depth; */
- GLbyte *pBits = NULL; /* pointer to bits */
-
- /* default/failed values */
- *iWidth = 0;
- *iHeight = 0;
- *eFormat = GL_BGR_EXT;
- *iComponents = GL_RGB8;
-
- /* attempt to open the file */
- pFile = fopen(szFileName, "rb");
- if (pFile == NULL)
- {
- perror("fopen");
- return 0;
- }
-
- /* read in header (binary) */
- fread(&tgaHeader, 18 /* sizeof(TGAHEADER) */, 1, pFile);
-
- /* get width, height, and depth of texture */
- *iWidth = tgaHeader.width;
- *iHeight = tgaHeader.height;
- sDepth = tgaHeader.bits / 8;
-
- /* put some validity checks here, very simply, i only understand
- * or care about 8, 24, or 32 bit targas
- */
- if (tgaHeader.bits != 8 && tgaHeader.bits != 24 && tgaHeader.bits != 32)
- return NULL;
-
- /* calculate size of image buffer */
- lImageSize = tgaHeader.width * tgaHeader.height * sDepth;
-
- /* allocate memory and check for success */
- pBits = (GLbyte *) malloc(lImageSize * sizeof(GLbyte));
- if (pBits == NULL)
- {
- perror("malloc");
- return NULL;
- }
-
- /* read in the bits */
- /* check for read error, this should catch rle or other */
- /* weird formats that i don't want to recognize */
- if (fread(pBits, lImageSize, 1, pFile) != 1)
- {
- perror("fread");
- free(pBits);
- return NULL;
- }
-
- /* set opengl format expected */
- switch (sDepth)
- {
- case 3: /* most likely case */
- *eFormat = GL_BGR_EXT;
- *iComponents = GL_RGB8;
- break;
- case 4:
- *eFormat = GL_BGRA_EXT;
- *iComponents = GL_RGBA8;
- break;
- case 1:
- *eFormat = GL_LUMINANCE;
- *iComponents = GL_LUMINANCE8;
- break;
- }
-
- /* done with file */
- fclose(pFile);
-
- /* return pointer to image data */
- return pBits;
-}