home *** CD-ROM | disk | FTP | other *** search
- /*
- * @(#)cube3D.c
- *
- * Copyright 1999-2000, Aaron Ardiri (mailto:aaron@ardiri.com)
- * All rights reserved.
- *
- * The source code outlines a number of basic Palm Computing Programming
- * principles and you should be able to take the core structure and write
- * a large complex program. It is distributed WITHOUT ANY WARRANTY; use it
- * "AS IS" and at your own risk.
- *
- * The code presented is Copyright 1999-2000 by Aaron Ardiri. It should be
- * used for educational purposes only. You shall not modify the Cube3D
- * source code in any way and re-distribute it as your own, however you
- * are free to use the code as a guide for developing programs on the
- * Palm Computing Platform.
- */
-
- #include "palm.h"
-
- // global variable structure
- typedef struct
- {
- Coord vertex[8][3];
- Int16 dx, dy, dz;
- } CubeGlobals;
-
- // interface
- static void CubePerspectiveConversion(Coord, Coord, Coord, Coord *, Coord *);
- static void CubeRotationAboutX(Coord, Coord, Coord,
- Coord *, Coord *, Coord *, Int16);
- static void CubeRotationAboutY(Coord, Coord, Coord,
- Coord *, Coord *, Coord *, Int16);
- static void CubeRotationAboutZ(Coord, Coord, Coord,
- Coord *, Coord *, Coord *, Int16);
-
- /**
- * sin(x) table for 0 <= x < 360
- * - values are generated using a 32 bit "fixed" type datatype
- */
- static fixed
- sin_table[] =
- {
- 0x00000000, 0x00000004, 0x00000008, 0x0000000d,
- 0x00000011, 0x00000016, 0x0000001a, 0x0000001f,
- 0x00000023, 0x00000028, 0x0000002c, 0x00000030,
- 0x00000035, 0x00000039, 0x0000003d, 0x00000042,
- 0x00000046, 0x0000004a, 0x0000004f, 0x00000053,
- 0x00000057, 0x0000005b, 0x0000005f, 0x00000064,
- 0x00000068, 0x0000006c, 0x00000070, 0x00000074,
- 0x00000078, 0x0000007c, 0x00000080, 0x00000083,
- 0x00000087, 0x0000008b, 0x0000008f, 0x00000092,
- 0x00000096, 0x0000009a, 0x0000009d, 0x000000a1,
- 0x000000a4, 0x000000a7, 0x000000ab, 0x000000ae,
- 0x000000b1, 0x000000b5, 0x000000b8, 0x000000bb,
- 0x000000be, 0x000000c1, 0x000000c4, 0x000000c6,
- 0x000000c9, 0x000000cc, 0x000000cf, 0x000000d1,
- 0x000000d4, 0x000000d6, 0x000000d9, 0x000000db,
- 0x000000dd, 0x000000df, 0x000000e2, 0x000000e4,
- 0x000000e6, 0x000000e8, 0x000000e9, 0x000000eb,
- 0x000000ed, 0x000000ee, 0x000000f0, 0x000000f2,
- 0x000000f3, 0x000000f4, 0x000000f6, 0x000000f7,
- 0x000000f8, 0x000000f9, 0x000000fa, 0x000000fb,
- 0x000000fc, 0x000000fc, 0x000000fd, 0x000000fe,
- 0x000000fe, 0x000000ff, 0x000000ff, 0x000000ff,
- 0x000000ff, 0x000000ff, 0x00000100, 0x000000ff,
- 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
- 0x000000fe, 0x000000fe, 0x000000fd, 0x000000fc,
- 0x000000fc, 0x000000fb, 0x000000fa, 0x000000f9,
- 0x000000f8, 0x000000f7, 0x000000f6, 0x000000f4,
- 0x000000f3, 0x000000f2, 0x000000f0, 0x000000ee,
- 0x000000ed, 0x000000eb, 0x000000e9, 0x000000e8,
- 0x000000e6, 0x000000e4, 0x000000e2, 0x000000df,
- 0x000000dd, 0x000000db, 0x000000d9, 0x000000d6,
- 0x000000d4, 0x000000d1, 0x000000cf, 0x000000cc,
- 0x000000c9, 0x000000c6, 0x000000c4, 0x000000c1,
- 0x000000be, 0x000000bb, 0x000000b8, 0x000000b5,
- 0x000000b1, 0x000000ae, 0x000000ab, 0x000000a7,
- 0x000000a4, 0x000000a1, 0x0000009d, 0x0000009a,
- 0x00000096, 0x00000092, 0x0000008f, 0x0000008b,
- 0x00000087, 0x00000083, 0x0000007f, 0x0000007c,
- 0x00000078, 0x00000074, 0x00000070, 0x0000006c,
- 0x00000068, 0x00000064, 0x0000005f, 0x0000005b,
- 0x00000057, 0x00000053, 0x0000004f, 0x0000004a,
- 0x00000046, 0x00000042, 0x0000003d, 0x00000039,
- 0x00000035, 0x00000030, 0x0000002c, 0x00000028,
- 0x00000023, 0x0000001f, 0x0000001a, 0x00000016,
- 0x00000011, 0x0000000d, 0x00000008, 0x00000004,
- 0x00000000, 0xfffffffc, 0xfffffff8, 0xfffffff3,
- 0xffffffef, 0xffffffea, 0xffffffe6, 0xffffffe1,
- 0xffffffdd, 0xffffffd8, 0xffffffd4, 0xffffffd0,
- 0xffffffcb, 0xffffffc7, 0xffffffc3, 0xffffffbe,
- 0xffffffba, 0xffffffb6, 0xffffffb1, 0xffffffad,
- 0xffffffa9, 0xffffffa5, 0xffffffa1, 0xffffff9c,
- 0xffffff98, 0xffffff94, 0xffffff90, 0xffffff8c,
- 0xffffff88, 0xffffff84, 0xffffff80, 0xffffff7d,
- 0xffffff79, 0xffffff75, 0xffffff71, 0xffffff6e,
- 0xffffff6a, 0xffffff66, 0xffffff63, 0xffffff5f,
- 0xffffff5c, 0xffffff59, 0xffffff55, 0xffffff52,
- 0xffffff4f, 0xffffff4b, 0xffffff48, 0xffffff45,
- 0xffffff42, 0xffffff3f, 0xffffff3c, 0xffffff3a,
- 0xffffff37, 0xffffff34, 0xffffff31, 0xffffff2f,
- 0xffffff2c, 0xffffff2a, 0xffffff27, 0xffffff25,
- 0xffffff23, 0xffffff21, 0xffffff1e, 0xffffff1c,
- 0xffffff1a, 0xffffff18, 0xffffff17, 0xffffff15,
- 0xffffff13, 0xffffff12, 0xffffff10, 0xffffff0e,
- 0xffffff0d, 0xffffff0c, 0xffffff0a, 0xffffff09,
- 0xffffff08, 0xffffff07, 0xffffff06, 0xffffff05,
- 0xffffff04, 0xffffff04, 0xffffff03, 0xffffff02,
- 0xffffff02, 0xffffff01, 0xffffff01, 0xffffff01,
- 0xffffff01, 0xffffff01, 0xffffff00, 0xffffff01,
- 0xffffff01, 0xffffff01, 0xffffff01, 0xffffff01,
- 0xffffff02, 0xffffff02, 0xffffff03, 0xffffff04,
- 0xffffff04, 0xffffff05, 0xffffff06, 0xffffff07,
- 0xffffff08, 0xffffff09, 0xffffff0a, 0xffffff0c,
- 0xffffff0d, 0xffffff0e, 0xffffff10, 0xffffff12,
- 0xffffff13, 0xffffff15, 0xffffff17, 0xffffff18,
- 0xffffff1a, 0xffffff1c, 0xffffff1e, 0xffffff21,
- 0xffffff23, 0xffffff25, 0xffffff27, 0xffffff2a,
- 0xffffff2c, 0xffffff2f, 0xffffff31, 0xffffff34,
- 0xffffff37, 0xffffff3a, 0xffffff3c, 0xffffff3f,
- 0xffffff42, 0xffffff45, 0xffffff48, 0xffffff4b,
- 0xffffff4f, 0xffffff52, 0xffffff55, 0xffffff59,
- 0xffffff5c, 0xffffff5f, 0xffffff63, 0xffffff66,
- 0xffffff6a, 0xffffff6e, 0xffffff71, 0xffffff75,
- 0xffffff79, 0xffffff7d, 0xffffff81, 0xffffff84,
- 0xffffff88, 0xffffff8c, 0xffffff90, 0xffffff94,
- 0xffffff98, 0xffffff9c, 0xffffffa1, 0xffffffa5,
- 0xffffffa9, 0xffffffad, 0xffffffb1, 0xffffffb6,
- 0xffffffba, 0xffffffbe, 0xffffffc3, 0xffffffc7,
- 0xffffffcb, 0xffffffd0, 0xffffffd4, 0xffffffd8,
- 0xffffffdd, 0xffffffe1, 0xffffffe6, 0xffffffea,
- 0xffffffef, 0xfffffff3, 0xfffffff8, 0xfffffffc,
- };
- #define ABS(a) (((a) > 0) ? (a) : -(a))
- static fixed cos_fx(Int16 deg) { return sin_table[ABS((deg+90)%360)]; }
- static fixed sin_fx(Int16 deg) { return sin_table[ABS(deg%360)]; }
-
- /**
- * Initialize the Cube3D engine.
- *
- * @param size the size of the cube.
- */
- void
- CubeInitialize(Coord size)
- {
- CubeGlobals *globals;
-
- // create the globals object, and register it
- globals = (CubeGlobals *)MemPtrNew(sizeof(CubeGlobals));
- MemSet(globals, sizeof(CubeGlobals), 0);
- FtrSet(appCreator, ftrCubeGlobals, (UInt32)globals);
-
- // setup our cube (hardcoded sizes here :P)
- globals->vertex[0][0] = -size;
- globals->vertex[0][1] = size;
- globals->vertex[0][2] = -size;
- globals->vertex[1][0] = -size;
- globals->vertex[1][1] = size;
- globals->vertex[1][2] = size;
- globals->vertex[2][0] = size;
- globals->vertex[2][1] = size;
- globals->vertex[2][2] = size;
- globals->vertex[3][0] = size;
- globals->vertex[3][1] = size;
- globals->vertex[3][2] = -size;
- globals->vertex[4][0] = -size;
- globals->vertex[4][1] = -size;
- globals->vertex[4][2] = -size;
- globals->vertex[5][0] = -size;
- globals->vertex[5][1] = -size;
- globals->vertex[5][2] = size;
- globals->vertex[6][0] = size;
- globals->vertex[6][1] = -size;
- globals->vertex[6][2] = size;
- globals->vertex[7][0] = size;
- globals->vertex[7][1] = -size;
- globals->vertex[7][2] = -size;
-
- // reset the "angle" parameters
- globals->dx = globals->dy = globals->dz = 0;
- }
-
- /**
- * Animate the Cube3D engine.
- */
- void
- CubeAnimate()
- {
- CubeGlobals *globals;
- Coord vertex[8][3];
- Coord points[8][2];
- UInt16 i;
-
- // get a globals reference
- FtrGet(appCreator, ftrCubeGlobals, (UInt32 *)&globals);
-
- // perform the "rotation" of the cube
- for (i=0; i<8; i++) {
- CubeRotationAboutX(
- globals->vertex[i][0], globals->vertex[i][1], globals->vertex[i][2],
- &vertex[i][0], &vertex[i][1], &vertex[i][2],
- globals->dx
- );
- CubeRotationAboutY(
- vertex[i][0], vertex[i][1], vertex[i][2],
- &vertex[i][0], &vertex[i][1], &vertex[i][2],
- globals->dy
- );
- CubeRotationAboutZ(
- vertex[i][0], vertex[i][1], vertex[i][2],
- &vertex[i][0], &vertex[i][1], &vertex[i][2],
- globals->dz
- );
- }
-
- // adjust the rotation angles
- globals->dx += 2;
- globals->dy += 1;
- globals->dz += 3;
-
- // convert the cube from 3D to 2D using perspective geometry
- for (i=0; i<8; i++) {
-
- CubePerspectiveConversion(vertex[i][0], vertex[i][1], vertex[i][2],
- &points[i][0], &points[i][1]);
-
- points[i][0] = points[i][0] + 80;
- points[i][1] = 64 - points[i][1]; // position (0,0,0) in center
- // - visible area is 160x128
- }
-
- // draw the "cube"
- WinDrawLine(points[0][0], points[0][1], points[1][0], points[1][1]);
- WinDrawLine(points[0][0], points[0][1], points[3][0], points[3][1]);
- WinDrawLine(points[0][0], points[0][1], points[4][0], points[4][1]);
- WinDrawLine(points[2][0], points[2][1], points[1][0], points[1][1]);
- WinDrawLine(points[2][0], points[2][1], points[3][0], points[3][1]);
- WinDrawLine(points[2][0], points[2][1], points[6][0], points[6][1]);
- WinDrawLine(points[5][0], points[5][1], points[1][0], points[1][1]);
- WinDrawLine(points[5][0], points[5][1], points[4][0], points[4][1]);
- WinDrawLine(points[5][0], points[5][1], points[6][0], points[6][1]);
- WinDrawLine(points[7][0], points[7][1], points[3][0], points[3][1]);
- WinDrawLine(points[7][0], points[7][1], points[4][0], points[4][1]);
- WinDrawLine(points[7][0], points[7][1], points[6][0], points[6][1]);
- }
-
- /**
- * Terminate the Cube3D engine.
- */
- void
- CubeTerminate()
- {
- CubeGlobals *globals;
-
- // get a globals reference
- FtrGet(appCreator, ftrCubeGlobals, (UInt32 *)&globals);
-
- // clean up memory
- MemPtrFree(globals);
-
- // unregister global data
- FtrUnregister(appCreator, ftrCubeGlobals);
- }
-
- /**
- * Perform a simple perspective translation of a 3D point to 2D.
- *
- * @param x the x co-ordinate of the source point
- * @param y the y co-ordinate of the source point
- * @param z the z co-ordinate of the source point
- * @param newX the x co-ordinate pointer of the rotated point
- * @param newY the y co-ordinate pointer of the rotated point
- */
- static void
- CubePerspectiveConversion(Coord x, Coord y, Coord z,
- Coord *newX, Coord *newY)
- {
- fixed _x, _y, _z;
-
- // NB: 333 and 250 value combinations give a good depth of field :))
-
- _x = itofx(x);
- _y = itofx(-y);
- _z = Addfx(itofx(-z), itofx(333));
-
- *newX = fxtoi(Divfx(Mulfx(itofx(250), _x), _z));
- *newY = fxtoi(Divfx(Mulfx(itofx(250), _y), _z));
- }
-
- /**
- * Rotate a 3D point around the X plane.
- *
- * @param x the x co-ordinate of the source point
- * @param y the y co-ordinate of the source point
- * @param z the z co-ordinate of the source point
- * @param newX the x co-ordinate pointer of the rotated point
- * @param newY the y co-ordinate pointer of the rotated point
- * @param newZ the z co-ordinate pointer of the rotated point
- * @param d the angle of rotation.
- */
- static void
- CubeRotationAboutX(Coord x, Coord y, Coord z,
- Coord *newX, Coord *newY, Coord *newZ, Int16 d)
- {
- *newX = x;
- *newY = fxtoi(Addfx(Mulfx( cos_fx(d),itofx(y)),Mulfx( sin_fx(d),itofx(z))));
- *newZ = fxtoi(Addfx(Mulfx(-sin_fx(d),itofx(y)),Mulfx( cos_fx(d),itofx(z))));
- }
-
- /**
- * Rotate a 3D point around the Y plane.
- *
- * @param x the x co-ordinate of the source point
- * @param y the y co-ordinate of the source point
- * @param z the z co-ordinate of the source point
- * @param newX the x co-ordinate pointer of the rotated point
- * @param newY the y co-ordinate pointer of the rotated point
- * @param newZ the z co-ordinate pointer of the rotated point
- * @param d the angle of rotation.
- */
- static void
- CubeRotationAboutY(Coord x, Coord y, Coord z,
- Coord *newX, Coord *newY, Coord *newZ, Int16 d)
- {
- *newX = fxtoi(Addfx(Mulfx( cos_fx(d),itofx(x)),Mulfx(-sin_fx(d),itofx(z))));
- *newY = y;
- *newZ = fxtoi(Addfx(Mulfx( sin_fx(d),itofx(x)),Mulfx( cos_fx(d),itofx(z))));
- }
-
- /**
- * Rotate a 3D point around the Z plane.
- *
- * @param x the x co-ordinate of the source point
- * @param y the y co-ordinate of the source point
- * @param z the z co-ordinate of the source point
- * @param newX the x co-ordinate pointer of the rotated point
- * @param newY the y co-ordinate pointer of the rotated point
- * @param newZ the z co-ordinate pointer of the rotated point
- * @param d the angle of rotation.
- */
- static void
- CubeRotationAboutZ(Coord x, Coord y, Coord z,
- Coord *newX, Coord *newY, Coord *newZ, Int16 d)
- {
- *newX = fxtoi(Addfx(Mulfx( cos_fx(d),itofx(x)),Mulfx( sin_fx(d),itofx(y))));
- *newY = fxtoi(Addfx(Mulfx(-sin_fx(d),itofx(x)),Mulfx( cos_fx(d),itofx(y))));
- *newZ = z;
- }
-