I have a little 3D world setup. by that i mean i have set vertex positions and drawn everything and done the matrix calculations and stuff. I know overkill for something that comes pre-packaged in DarkGDK. especially when i'm doing it in darkGDK. but i love seeing how the 3d world works.
Well i have 2 questions 1 why is my plain rotating around it's top left vertex? and 2 how do i get my camera to rotate? here's the code. i have camera rotation code in there but it doesn't work correctly. The camera rotation is using matrix multiplication. i can't understand why it isn't working correctly
// Dark GDK - The Game Creators - www.thegamecreators.com
// the wizard has created a very simple project that uses Dark GDK
// it contains the basic code for a GDK application
// whenever using Dark GDK you must ensure you include the header file
#include "DarkGDK.h"
struct MATRIX{
float m00,m10,m20,
m01,m11,m21,
m02,m12,m22;
};
struct VECTOR{
float x, y, z;
POINT screen;
};
struct POLY{
VECTOR vect[3];
};
struct OBJECT{
POLY*poly;
int polyCount;
float x, y, z;
MATRIX* r;
};
POINT ProjectPoint(VECTOR vect);
int DrawPoly(OBJECT*obj, int i);
void DrawTriangle(POINT p1, POINT p2, POINT p3);
void SetVector(VECTOR*v, float x, float y, float z);
void DrawObject(OBJECT*obj);
OBJECT* CreatePlain(float size);
MATRIX* MatMult(MATRIX*,MATRIX*, MATRIX*);
void MatrixRotationZ(MATRIX*,float);
void MatrixRotationX(MATRIX*,float);
void MatrixScale(MATRIX*,float);
void SetMatrixTransform(OBJECT*obj, MATRIX*mat);
void qscan(int, int, int);
void fill_triangle(POINT, POINT, POINT, int);
VECTOR camVect;
float camAngX = 0.0, camAngY = 0.0, camAngZ = 0.0;
float zdist = 300 / tan(31.0);
// the main entry point for the application is this function
void DarkGDK ( void )
{
// turn on sync rate and set maximum rate to 60 fps
dbSyncOn ( );
dbSyncRate ( 60 );
dbSetDisplayMode(800, 600, 32);
SetVector(&camVect, 0.0, 0.0, -50.0);
OBJECT*obj = CreatePlain(10.0);
MATRIX matRotateZ;
SetMatrixTransform(obj, &matRotateZ);
float angle = 0.0;
// our main loop
while ( LoopGDK ( ) )
{
dbPrint((float)(dbScreenFPS()));
DrawObject(obj);
angle += 0.01;
MatrixRotationZ(&matRotateZ, dbWrapValue(angle));
camAngX = dbWrapValue( (camAngX + dbMouseMoveY() / 4.0) );
camAngY = dbWrapValue( (camAngX + dbMouseMoveX() / 4.0) );
if(dbLeftKey())
++camVect.x;
if(dbRightKey())
--camVect.x;
if(dbUpKey())
++camVect.z;
if(dbDownKey())
--camVect.z;
// update the screen
dbSync ( );
dbCLS(dbRGB(0, 0, 255));
}
// return back to windows
return;
}
void SetMatrixTransform(OBJECT*obj, MATRIX*mat)
{
obj->r = mat;
}
OBJECT* CreatePlain(float size)
{
OBJECT*plain = new OBJECT;
ZeroMemory(plain, sizeof(OBJECT));
plain->poly = new POLY[3];
plain->polyCount = 2;
// front face
SetVector(&plain->poly[0].vect[0], 0.0, 0.0, 0.0);
SetVector(&plain->poly[0].vect[1], 0.0, size, 0.0);
SetVector(&plain->poly[0].vect[2], size, size, 0.0);
SetVector(&plain->poly[1].vect[0], 0.0, 0.0, 0.0);
SetVector(&plain->poly[1].vect[1], size, size, 0.0);
SetVector(&plain->poly[1].vect[2], size, 0.0, 0.0);
return plain;
}
float GetVectorScreenX(VECTOR v)
{
if(v.z < camVect.z) return -1.0;
int hw = dbScreenWidth()/2;
VECTOR d;
float cosX = cos(camAngX), cosY = cos(camAngY), cosZ = cos(camAngZ);
float sinX = sin(camAngX), sinY = sin(camAngY), sinZ = sin(camAngZ);
d.x = cosY*(sinZ*(v.y-camVect.y)+cosZ*(v.x-camVect.x)) - sinY * (v.z - camVect.z);
d.z = cosX*(cosY*(v.z-camVect.z)+sinY*(sinZ*(v.y-camVect.y)+cosZ*(v.x-camVect.x))) - sinX*(cosZ*(v.y-camVect.y)-sinZ*(v.z-camVect.z));
float x = (d.x * (zdist / d.z))+hw;
return x;
}
float GetVectorScreenY(VECTOR v)
{
if(v.z < camVect.z) return -1.0;
int hh = dbScreenHeight()/2;
VECTOR d;
float cosX = cos(camAngX), cosY = cos(camAngY), cosZ = cos(camAngZ);
float sinX = sin(camAngX), sinY = sin(camAngY), sinZ = sin(camAngZ);
d.y = sinX*(cosY*(v.z-camVect.z)+sinY*(sinZ*(v.y-camVect.y)+cosZ*(v.x-camVect.x))) + cosX*(cosZ*(v.y-camVect.y)-sinZ*(v.z-camVect.z));
d.z = cosX*(cosY*(v.z-camVect.z)+sinY*(sinZ*(v.y-camVect.y)+cosZ*(v.x-camVect.x))) - sinX*(cosZ*(v.y-camVect.y)-sinZ*(v.z-camVect.z));
float y = hh-(d.y * (zdist / d.z));
return y;
}
void MatrixRotationZ(MATRIX*r, float angle)
{
r->m00 = cos(angle); r->m10 = sin(angle)*-1; r->m20 = 0;
r->m01 = sin(angle); r->m11 = cos(angle); r->m21 = 0;
r->m02 = 0; r->m12 = 0; r->m22 = 1;
}
void MatrixRotationX(MATRIX*r, float angle)
{
r->m00 = 1; r->m10 = 0; r->m20 = 0;
r->m01 = 0; r->m11 = cos(angle); r->m21 = sin(angle)*-1;
r->m02 = 0; r->m12 = sin(angle); r->m22 = cos(angle);
}
void MatrixScale(MATRIX*s, float percent)
{
s->m00 = percent; s->m10 = 0; s->m20 = 0;
s->m01 = 0; s->m11 = percent; s->m21 = 0;
s->m02 = 0; s->m12 = 0; s->m22 = percent;
}
MATRIX* MatMult(MATRIX*ret, MATRIX* a, MATRIX*b)
{
ret->m00 = a->m00*b->m00+a->m01*b->m10+a->m02*b->m20;
ret->m10 = a->m00*b->m01+a->m01*b->m11+a->m02*b->m21;
ret->m20 = a->m00*b->m02+a->m01*b->m12+a->m02*b->m22;
ret->m01 = a->m10*b->m00+a->m11*b->m10+a->m12*b->m20;
ret->m11 = a->m10*b->m01+a->m11*b->m11+a->m12*b->m21;
ret->m21 = a->m10*b->m02+a->m11*b->m12+a->m12*b->m22;
ret->m02 = a->m20*b->m00+a->m21*b->m10+a->m22*b->m20;
ret->m12 = a->m20*b->m01+a->m21*b->m11+a->m22*b->m21;
ret->m22 = a->m20*b->m02+a->m21*b->m12+a->m22*b->m22;
return ret;
}
void DrawObject(OBJECT*obj)
{
for(int i = 0; i < (obj->polyCount); ++i)
{
DrawPoly(obj, i);
}
}
void SetVector(VECTOR*v, float x, float y, float z)
{
v->x = x;
v->y = y;
v->z = z;
}
int DrawPoly(OBJECT*obj, int i)
{
float x, y, z, x0, y0, z0, x1, y1, z1;
for(int v = 0; v < 3; ++v)
{
x0 = obj->poly[i].vect[v].x;
y0 = obj->poly[i].vect[v].y;
z0 = obj->poly[i].vect[v].z;
x1 = x0; y1 = y0; z1 = z0;
if(obj->r > 0)
{
x = (x1*obj->r->m00)+(y1*obj->r->m10)+(z1*obj->r->m20);
y = (x1*obj->r->m01)+(y1*obj->r->m11)+(z1*obj->r->m21);
z = (x1*obj->r->m02)+(y1*obj->r->m12)+(z1*obj->r->m22);
} else {
x = x1; y = y1; z = z1;
}
x += obj->x; y += obj->y; z += obj->z;
if(z > camVect.z)
{
VECTOR vect; vect.x = x; vect.y = y; vect.z = z;
obj->poly[i].vect[v].screen.x = GetVectorScreenX(vect);
obj->poly[i].vect[v].screen.y = GetVectorScreenY(vect);
}
}
DrawTriangle(obj->poly[i].vect[0].screen,obj->poly[i].vect[1].screen,obj->poly[i].vect[2].screen);
return 0;
}
void DrawTriangle(POINT p1, POINT p2, POINT p3)
{
dbLine(p1.x, p1.y, p2.x, p2.y );
dbLine(p1.x, p1.y, p3.x, p3.y );
dbLine(p2.x, p2.y, p3.x, p3.y);
}
/** fill triangle
*/
void fill_triangle(POINT a, POINT b, POINT c, int color) {
int xi1 = a.x, yi1 = a.y, xi2 = b.x, yi2 = b.y, xi3 = c.x, yi3 = c.y;
double x0 = xi1;
double x1 = xi2;
double x2 = xi3;
double y0 = yi1;
double y1 = yi2;
double y2 = yi3;
double d0 = 0;
double d1 = 0;
double d2 = 0;
double dx0 = 0;
double dx1 = 0;
double dx2 = 0;
double dy0 = 0;
double dy1 = 0;
double dy2 = 0;
//double dx[] = {0,0,0};
double dy[] = {0,0,0};
double d[] = {0,0,0};
double dt;
int i;
if(y1 < y0) { dt = y0; y0 = y1; y1 = dt; dt = x0; x0 = x1; x1 = dt;}
if(y2 < y1) { dt = y1; y1 = y2; y2 = dt; dt = x1; x1 = x2; x2 = dt;}
if(y2 < y0) { dt = y0; y0 = y2; y2 = dt; dt = x0; x0 = x2; x2 = dt;}
dx0 = x1 - x0;
dy0 = y1 - y0;
dx1 = x2 - x1;
dy1 = y2 - y1;
dx2 = x0 - x2;
dy2 = y0 - y2;
if(dy0 != 0) d0 = dx0 / dy0;
else d0 = 0;
if(dy1 != 0) d1 = dx1 / dy1;
else d1 = 0;
if(dy2 != 0) d2 = dx2 / dy2;
else d2 = 0;
int sx,ex;
double id;
for(i = (int) y0; i < y1; i++) {
id = (double) i;
sx = (int) (x0 + ((id - y0) * d2));
ex = (int) (x0 + ((id - y0) * d0));
if(sx < ex) qscan(sx,i,ex - sx);
else qscan(ex,i,sx - ex);
}
for(i = (int) y1; i < y2; i++) {
sx = (int) (x0 + ((i - y0) * d2));
ex = (int) (x1 + ((i - y1) * d1));
if(sx < ex) qscan(sx,i,ex - sx);
else qscan(ex,i,sx - ex);
}
}
/** private quick scan
*
* @param x x
* @param y y
* @param size size of scan
*
*/
void qscan(int x, int y, int size) {
dbLine(x, y, x+size, y);
}
New Site! Check it out \/