home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 2001 Mobile
/
Chip_Mobile_2001.iso
/
palm
/
business
/
cube3d
/
cube3D.exe
/
cube3D
/
src
/
cube3D.c
next >
Wrap
C/C++ Source or Header
|
2000-12-26
|
13KB
|
350 lines
/*
* @(#)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;
}