From 9d2084b6b54f32a5b668d6550ab342cae6f665be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Lemaire?= Date: Sun, 16 Feb 2014 15:32:28 +0100 Subject: [PATCH] Convert crlf to nl for portability --- src/3dutils.cpp | 720 +++++++-------- src/3dutils.h | 114 +-- src/appearance.cpp | 234 ++--- src/appearance.h | 88 +- src/audio.cpp | 540 +++++------ src/audio.h | 144 +-- src/camera.cpp | 174 ++-- src/camera.h | 64 +- src/collision.cpp | 1514 +++++++++++++++--------------- src/collision.h | 94 +- src/end.cpp | 288 +++--- src/end.h | 32 +- src/fight.cpp | 1194 ++++++++++++------------ src/fight.h | 56 +- src/font.cpp | 146 +-- src/font.h | 26 +- src/glapi.cpp | 128 +-- src/glapi.h | 20 +- src/graphics.cpp | 472 +++++----- src/graphics.h | 108 +-- src/legoblocks.cpp | 900 +++++++++--------- src/legoblocks.h | 182 ++-- src/legoman.cpp | 2042 ++++++++++++++++++++--------------------- src/legoman.h | 394 ++++---- src/light.cpp | 384 ++++---- src/light.h | 60 +- src/main.cpp | 290 +++--- src/main.h | 54 +- src/material.cpp | 120 +-- src/material.h | 58 +- src/menu.cpp | 1694 +++++++++++++++++----------------- src/menu.h | 38 +- src/mesh.cpp | 758 +++++++-------- src/mesh.h | 242 ++--- src/object.cpp | 426 ++++----- src/object.h | 292 +++--- src/objectfactory.cpp | 648 ++++++------- src/objectfactory.h | 32 +- src/particle.cpp | 302 +++--- src/particle.h | 112 +-- src/run.cpp | 426 ++++----- src/run.h | 32 +- src/shape.cpp | 36 +- src/shape.h | 62 +- src/sphere.cpp | 526 +++++------ src/sphere.h | 134 +-- src/texture.cpp | 194 ++-- src/texture.h | 76 +- src/utils.cpp | 78 +- src/utils.h | 32 +- src/vector.cpp | 548 +++++------ src/vector.h | 100 +- src/world.cpp | 422 ++++----- src/world.h | 112 +-- 54 files changed, 8981 insertions(+), 8981 deletions(-) diff --git a/src/3dutils.cpp b/src/3dutils.cpp index 4d18b58..c6cb587 100644 --- a/src/3dutils.cpp +++ b/src/3dutils.cpp @@ -1,360 +1,360 @@ -#include "main.h" - -#include "3dutils.h" - -#include - -#include "utils.h" -#include "mesh.h" -#include "vector.h" -#include "texture.h" - -#include "glapi.h" - -int SKYBOX = -1; - -/* - * Luo pyörähdyskappaleen y-akselin ympäri annetuista pisteistä - * Parametrina taulukollinen pisteitä, - * pisteidein määrä, - * jakojen määrä pyörähdyssuunnassa, - * jakojen määrä "pysty"suunnassa - * Jos viimeinen parametri on sama kuin pisteiden määrä, - * niin pyörähdyskappale vastaa suoraan annettujen pisteiden - * pyörähdyskappaletta. Muulloin pisteet lasketaan kuutiollisella - * interpoloinnilla annettujen pisteiden välillä. - */ -void createLathedSurface(point2d *points, point2d *pointderivates, int count, int slices, int stacks){ - int i, j; - point2d *h1, *h2; - point2d *derivates; - if (pointderivates == NULL) derivates = new point2d[count]; - else derivates = pointderivates; - //Derivaatta pisteessä i on (points[i+1]-points[i-1])/2 alkua ja loppua lukuunottamatta - for (i = 0; i < count; i++){ - if (pointderivates == NULL || (derivates[i].x == 0 && derivates[i].y == 0)){ - if (i == 0) h1 = &points[0]; - else h1 = &points[i-1]; - if (i == count-1) h2 = &points[count-1]; - else h2 = &points[i+1]; - float dx,dy; - dx = (h2->x - h1->x); - dy = (h2->y - h1->y); - if (i > 0 && i < count){ - dx /= 2; - dy /= 2; - } - derivates[i].x = dx; - derivates[i].y = dy; - } - } - - float sif; - int si; - point2d newpoint, oldpoint; - point2d derivate; - point2d newnormal, oldnormal; - point2d A, B, C, D; - oldpoint.x = points[0].x; - oldpoint.y = points[0].y; - oldnormal.x = derivates[0].y; - oldnormal.y = -derivates[0].x; - point2d *p1, *p2, *d1, *d2; - int i1, i2; - float t; - float x1, y1, z1, x2, y2, z2, nx1, ny1, nz1, nx2, ny2, nz2; - for (i = 1; i <= stacks-(stacks/count); i++){ - sif = (float)i*count/stacks; - si = (int)sif; - t = sif-si; - i1 = si; - i2 = si+1; - if (i2 >= count) i2 = count-1; - p1 = &points[i1]; - p2 = &points[i2]; - d1 = &derivates[i1]; - d2 = &derivates[i2]; - //Hermite-käyrä A*t^3 + B*t^2 + C*t + D - //Hermite-käyrän derivaatta 3*A*t^2 + 2*B*t + C - //Vakiot A,B,C ja D ovat laskettu siten, että: - //1. H(0)=p1; - //2. H(1)=p2; - //3. H'(0)=d1; - //4. H'(1)=d2; - // - //A = d2 - 2*p2 + d1 + 2*p1 - //B = -d2 + 3*p2 - 2*d1 - 3*p1 - //C = d1 - //D = p1 - A.x = d2->x - 2*p2->x + d1->x + 2*p1->x; - A.y = d2->y - 2*p2->y + d1->y + 2*p1->y; - B.x = - d2->x + 3*p2->x - 2*d1->x - 3*p1->x; - B.y = - d2->y + 3*p2->y - 2*d1->y - 3*p1->y; - C.x = d1->x; - C.y = d1->y; - D.x = p1->x; - D.y = p1->y; - - newpoint.x = A.x*t*t*t + B.x*t*t + C.x*t + D.x; - newpoint.y = A.y*t*t*t + B.y*t*t + C.y*t + D.y; - - derivate.x = 3*A.x*t*t + 2*B.x*t + C.x; - derivate.y = 3*A.y*t*t + 2*B.y*t + C.y; - - newnormal.x = derivate.y; - newnormal.y = -derivate.x; - - glBegin(GL_QUAD_STRIP); - for (j = 0; j <= slices; j++){ - float angle = j*2*PI/slices; - - nx2 = sin(angle)*newnormal.x; - ny2 = newnormal.y; - nz2 = cos(angle)*newnormal.x; - glNormal3f(nx2, ny2, nz2); - x2 = sin(angle)*newpoint.x; - y2 = newpoint.y; - z2 = cos(angle)*newpoint.x; - glTexCoord2f(j*1.0/slices,1.0-(i*1.0/(stacks-1))); - glVertex3f(x2, y2, z2); - - nx1 = sin(angle)*oldnormal.x; - ny1 = oldnormal.y; - nz1 = cos(angle)*oldnormal.x; - glNormal3f(nx1, ny1, nz1); - x1 = sin(angle)*oldpoint.x; - y1 = oldpoint.y; - z1 = cos(angle)*oldpoint.x; - glTexCoord2f(j*1.0/slices,1.0-((i-1)*1.0/(stacks-1))); - glVertex3f(x1, y1, z1); - } - glEnd(); - - oldpoint.x = newpoint.x; - oldpoint.y = newpoint.y; - oldnormal.x = newnormal.x; - oldnormal.y = newnormal.y; - } -} - -GLUquadricObj *spherequadric = gluNewQuadric(); - -void createSphere(float r, int slices, int stacks){ - /*float phi, theta; - int x, y; - for (y = 0; y < stacks; y++){ - for (x = 0; x < slices; x++){ - } - }*/ - gluSphere(spherequadric, r, slices, stacks); -} - -#define DEFAULTSLICES 20 -#define DEFAULTSTACKS 10 - -void createSphere(float r){ - createSphere(r, DEFAULTSLICES, DEFAULTSTACKS); -} - -bool solvePointInTriangle(float *position, float *normal, - Vertex *v1, Vertex *v2, Vertex *v3, - float *t, float *u, float *v){ - float edge1[3], edge2[3], tvec[3], pvec[3], qvec[3]; - float det,inv_det; - - // find vectors for two edges sharing vert0 - vectorSub(edge1, v2->position, v1->position); - vectorSub(edge2, v3->position, v1->position); - - // begin calculating determinant - also used to calculate U parameter - vectorCross(pvec, normal, edge2); - - //if determinant is near zero, ray lies in plane of triangle - det = vectorDot(edge1, pvec); - - if (det > -EPSILON && det < EPSILON) return false; - inv_det = 1.0 / det; - - // calculate distance from vert0 to ray origin - vectorSub(tvec, position, v1->position); - - // calculate U parameter and test bounds - *u = vectorDot(tvec, pvec) * inv_det; - if (*u < 0.0 || *u > 1.0) return false; - - // prepare to test V parameter - vectorCross(qvec, tvec, edge1); - - // calculate V parameter and test bounds - *v = vectorDot(normal, qvec) * inv_det; - if (*v < 0.0 || *u + *v > 1.0) return false; - - // calculate t, ray intersects triangle - *t = vectorDot(edge2, qvec) * inv_det; - - return true; -} - - -float distanceFromPlane(float point[3], float normal[3], float distance){ - return vectorDot(point, normal) + distance; -} - - -void createSkyBox(float x, float y, float z, float w, float h, float l) -{ - glEnable(GL_TEXTURE_2D); - glClear(GL_DEPTH_BUFFER_BIT); - glDisable(GL_DEPTH_TEST); - glDisable(GL_BLEND); - glDisable(GL_CULL_FACE); - glDisable(GL_ALPHA_TEST); - glDisable(GL_LIGHTING); - glShadeModel(GL_FLAT); - - float modelview[16]; - - glGetFloatv(GL_MODELVIEW_MATRIX, modelview); - modelview[12] = modelview[13] = modelview[14] = 0.0f; - glPushMatrix(); - glLoadMatrixf(modelview); - - if (SKYBOX > 0){ - glCallList(SKYBOX); - } - else{ - - SKYBOX = glGenLists(1); - - float d = 1.0/512; - - //glPushAttrib(GL_COLOR); - - glNewList(SKYBOX, GL_COMPILE_AND_EXECUTE); - - - //glBindTexture(GL_TEXTURE_2D, SKY_BACK_ID); - skybacktexture->enable(); - - - glBegin(GL_QUADS); - glColor4f(1, 1, 1, 1.0); - - glTexCoord2f(1-d, 1-d); glVertex3f(x + w, y, z); - glTexCoord2f(1-d, 0+d); glVertex3f(x + w, y + h, z); - glTexCoord2f(0+d, 0+d); glVertex3f(x, y + h, z); - glTexCoord2f(0+d, 1-d); glVertex3f(x, y, z); - - glEnd(); - - - //glBindTexture(GL_TEXTURE_2D, SKY_FRONT_ID); - skyfronttexture->enable(); - - - glBegin(GL_QUADS); - - glColor4f(1, 1, 1, 1.0); - - glTexCoord2f(1-d, 1-d); glVertex3f(x, y, z + l); - glTexCoord2f(1-d, 0+d); glVertex3f(x, y + h, z + l); - glTexCoord2f(0+d, 0+d); glVertex3f(x + w, y + h, z + l); - glTexCoord2f(0+d, 1-d); glVertex3f(x + w, y, z + l); - glEnd(); - - - - //glBindTexture(GL_TEXTURE_2D, SKY_TOP_ID); - skytoptexture->enable(); - - - glBegin(GL_QUADS); - glColor4f(1, 1, 1, 1.0); - - glTexCoord2f(0+d, 0+d); glVertex3f(x + w, y + h, z + l); - glTexCoord2f(1-d, 0+d); glVertex3f(x + w, y + h, z); - glTexCoord2f(1-d, 1-d); glVertex3f(x, y + h, z); - glTexCoord2f(0+d, 1-d); glVertex3f(x, y + h, z + l); - /*glTexCoord2f(1.0f, 0+d); glVertex3f(x + w, y + h, z); - glTexCoord2f(1.0f, 1.0f); glVertex3f(x + w, y + h, z + l); - glTexCoord2f(0+d, 1.0f); glVertex3f(x, y + h, z + l); - glTexCoord2f(0+d, 0+d); glVertex3f(x, y + h, z);*/ - - - glEnd(); - - - - //glBindTexture(GL_TEXTURE_2D, SKY_BOTTOM_ID); - skybottomtexture->enable(); - - - glBegin(GL_QUADS); - glColor4f(1, 1, 1, 1.0); - - glTexCoord2f(1-d, 0+d); glVertex3f(x, y, z); - glTexCoord2f(1-d, 1-d); glVertex3f(x + w, y, z); - glTexCoord2f(0+d, 1-d); glVertex3f(x + w, y, z + l); - glTexCoord2f(0+d, 0+d); glVertex3f(x, y, z + l); - - - glEnd(); - - //glBindTexture(GL_TEXTURE_2D, SKY_LEFT_ID); - skylefttexture->enable(); - - - glBegin(GL_QUADS); - glColor4f(1, 1, 1, 1.0); - glTexCoord2f(1-d, 0+d); glVertex3f(x, y + h, z); - glTexCoord2f(0+d, 0+d); glVertex3f(x, y + h, z + l); - glTexCoord2f(0+d, 1-d); glVertex3f(x, y, z + l); - glTexCoord2f(1-d, 1-d); glVertex3f(x, y, z); - - glEnd(); - - //glBindTexture(GL_TEXTURE_2D, SKY_RIGHT_ID); - skyrighttexture->enable(); - - glBegin(GL_QUADS); - glColor4f(1, 1, 1, 1.0); - glTexCoord2f(0+d, 1-d); glVertex3f(x + w, y, z); - glTexCoord2f(1-d, 1-d); glVertex3f(x + w, y, z + l); - glTexCoord2f(1-d, 0+d); glVertex3f(x + w, y + h, z + l); - glTexCoord2f(0+d, 0+d); glVertex3f(x + w, y + h, z); - - - glEnd(); - glEndList(); - } - - glPopMatrix(); - glEnable(GL_DEPTH_TEST); - glEnable(GL_CULL_FACE); - glDisable(GL_TEXTURE_2D); - glEnable(GL_LIGHTING); - glShadeModel(GL_SMOOTH); -} - -void enable2D(void){ - glDisable(GL_LIGHTING); - glDisable(GL_CULL_FACE); - glDisable(GL_DEPTH_TEST); - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - gluOrtho2D(0, 1, 1, 0); - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); -} - -void disable2D(void){ - glPopMatrix(); - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); - glEnable(GL_DEPTH_TEST); - glEnable(GL_CULL_FACE); - glEnable(GL_LIGHTING); -} +#include "main.h" + +#include "3dutils.h" + +#include + +#include "utils.h" +#include "mesh.h" +#include "vector.h" +#include "texture.h" + +#include "glapi.h" + +int SKYBOX = -1; + +/* + * Luo pyörähdyskappaleen y-akselin ympäri annetuista pisteistä + * Parametrina taulukollinen pisteitä, + * pisteidein määrä, + * jakojen määrä pyörähdyssuunnassa, + * jakojen määrä "pysty"suunnassa + * Jos viimeinen parametri on sama kuin pisteiden määrä, + * niin pyörähdyskappale vastaa suoraan annettujen pisteiden + * pyörähdyskappaletta. Muulloin pisteet lasketaan kuutiollisella + * interpoloinnilla annettujen pisteiden välillä. + */ +void createLathedSurface(point2d *points, point2d *pointderivates, int count, int slices, int stacks){ + int i, j; + point2d *h1, *h2; + point2d *derivates; + if (pointderivates == NULL) derivates = new point2d[count]; + else derivates = pointderivates; + //Derivaatta pisteessä i on (points[i+1]-points[i-1])/2 alkua ja loppua lukuunottamatta + for (i = 0; i < count; i++){ + if (pointderivates == NULL || (derivates[i].x == 0 && derivates[i].y == 0)){ + if (i == 0) h1 = &points[0]; + else h1 = &points[i-1]; + if (i == count-1) h2 = &points[count-1]; + else h2 = &points[i+1]; + float dx,dy; + dx = (h2->x - h1->x); + dy = (h2->y - h1->y); + if (i > 0 && i < count){ + dx /= 2; + dy /= 2; + } + derivates[i].x = dx; + derivates[i].y = dy; + } + } + + float sif; + int si; + point2d newpoint, oldpoint; + point2d derivate; + point2d newnormal, oldnormal; + point2d A, B, C, D; + oldpoint.x = points[0].x; + oldpoint.y = points[0].y; + oldnormal.x = derivates[0].y; + oldnormal.y = -derivates[0].x; + point2d *p1, *p2, *d1, *d2; + int i1, i2; + float t; + float x1, y1, z1, x2, y2, z2, nx1, ny1, nz1, nx2, ny2, nz2; + for (i = 1; i <= stacks-(stacks/count); i++){ + sif = (float)i*count/stacks; + si = (int)sif; + t = sif-si; + i1 = si; + i2 = si+1; + if (i2 >= count) i2 = count-1; + p1 = &points[i1]; + p2 = &points[i2]; + d1 = &derivates[i1]; + d2 = &derivates[i2]; + //Hermite-käyrä A*t^3 + B*t^2 + C*t + D + //Hermite-käyrän derivaatta 3*A*t^2 + 2*B*t + C + //Vakiot A,B,C ja D ovat laskettu siten, että: + //1. H(0)=p1; + //2. H(1)=p2; + //3. H'(0)=d1; + //4. H'(1)=d2; + // + //A = d2 - 2*p2 + d1 + 2*p1 + //B = -d2 + 3*p2 - 2*d1 - 3*p1 + //C = d1 + //D = p1 + A.x = d2->x - 2*p2->x + d1->x + 2*p1->x; + A.y = d2->y - 2*p2->y + d1->y + 2*p1->y; + B.x = - d2->x + 3*p2->x - 2*d1->x - 3*p1->x; + B.y = - d2->y + 3*p2->y - 2*d1->y - 3*p1->y; + C.x = d1->x; + C.y = d1->y; + D.x = p1->x; + D.y = p1->y; + + newpoint.x = A.x*t*t*t + B.x*t*t + C.x*t + D.x; + newpoint.y = A.y*t*t*t + B.y*t*t + C.y*t + D.y; + + derivate.x = 3*A.x*t*t + 2*B.x*t + C.x; + derivate.y = 3*A.y*t*t + 2*B.y*t + C.y; + + newnormal.x = derivate.y; + newnormal.y = -derivate.x; + + glBegin(GL_QUAD_STRIP); + for (j = 0; j <= slices; j++){ + float angle = j*2*PI/slices; + + nx2 = sin(angle)*newnormal.x; + ny2 = newnormal.y; + nz2 = cos(angle)*newnormal.x; + glNormal3f(nx2, ny2, nz2); + x2 = sin(angle)*newpoint.x; + y2 = newpoint.y; + z2 = cos(angle)*newpoint.x; + glTexCoord2f(j*1.0/slices,1.0-(i*1.0/(stacks-1))); + glVertex3f(x2, y2, z2); + + nx1 = sin(angle)*oldnormal.x; + ny1 = oldnormal.y; + nz1 = cos(angle)*oldnormal.x; + glNormal3f(nx1, ny1, nz1); + x1 = sin(angle)*oldpoint.x; + y1 = oldpoint.y; + z1 = cos(angle)*oldpoint.x; + glTexCoord2f(j*1.0/slices,1.0-((i-1)*1.0/(stacks-1))); + glVertex3f(x1, y1, z1); + } + glEnd(); + + oldpoint.x = newpoint.x; + oldpoint.y = newpoint.y; + oldnormal.x = newnormal.x; + oldnormal.y = newnormal.y; + } +} + +GLUquadricObj *spherequadric = gluNewQuadric(); + +void createSphere(float r, int slices, int stacks){ + /*float phi, theta; + int x, y; + for (y = 0; y < stacks; y++){ + for (x = 0; x < slices; x++){ + } + }*/ + gluSphere(spherequadric, r, slices, stacks); +} + +#define DEFAULTSLICES 20 +#define DEFAULTSTACKS 10 + +void createSphere(float r){ + createSphere(r, DEFAULTSLICES, DEFAULTSTACKS); +} + +bool solvePointInTriangle(float *position, float *normal, + Vertex *v1, Vertex *v2, Vertex *v3, + float *t, float *u, float *v){ + float edge1[3], edge2[3], tvec[3], pvec[3], qvec[3]; + float det,inv_det; + + // find vectors for two edges sharing vert0 + vectorSub(edge1, v2->position, v1->position); + vectorSub(edge2, v3->position, v1->position); + + // begin calculating determinant - also used to calculate U parameter + vectorCross(pvec, normal, edge2); + + //if determinant is near zero, ray lies in plane of triangle + det = vectorDot(edge1, pvec); + + if (det > -EPSILON && det < EPSILON) return false; + inv_det = 1.0 / det; + + // calculate distance from vert0 to ray origin + vectorSub(tvec, position, v1->position); + + // calculate U parameter and test bounds + *u = vectorDot(tvec, pvec) * inv_det; + if (*u < 0.0 || *u > 1.0) return false; + + // prepare to test V parameter + vectorCross(qvec, tvec, edge1); + + // calculate V parameter and test bounds + *v = vectorDot(normal, qvec) * inv_det; + if (*v < 0.0 || *u + *v > 1.0) return false; + + // calculate t, ray intersects triangle + *t = vectorDot(edge2, qvec) * inv_det; + + return true; +} + + +float distanceFromPlane(float point[3], float normal[3], float distance){ + return vectorDot(point, normal) + distance; +} + + +void createSkyBox(float x, float y, float z, float w, float h, float l) +{ + glEnable(GL_TEXTURE_2D); + glClear(GL_DEPTH_BUFFER_BIT); + glDisable(GL_DEPTH_TEST); + glDisable(GL_BLEND); + glDisable(GL_CULL_FACE); + glDisable(GL_ALPHA_TEST); + glDisable(GL_LIGHTING); + glShadeModel(GL_FLAT); + + float modelview[16]; + + glGetFloatv(GL_MODELVIEW_MATRIX, modelview); + modelview[12] = modelview[13] = modelview[14] = 0.0f; + glPushMatrix(); + glLoadMatrixf(modelview); + + if (SKYBOX > 0){ + glCallList(SKYBOX); + } + else{ + + SKYBOX = glGenLists(1); + + float d = 1.0/512; + + //glPushAttrib(GL_COLOR); + + glNewList(SKYBOX, GL_COMPILE_AND_EXECUTE); + + + //glBindTexture(GL_TEXTURE_2D, SKY_BACK_ID); + skybacktexture->enable(); + + + glBegin(GL_QUADS); + glColor4f(1, 1, 1, 1.0); + + glTexCoord2f(1-d, 1-d); glVertex3f(x + w, y, z); + glTexCoord2f(1-d, 0+d); glVertex3f(x + w, y + h, z); + glTexCoord2f(0+d, 0+d); glVertex3f(x, y + h, z); + glTexCoord2f(0+d, 1-d); glVertex3f(x, y, z); + + glEnd(); + + + //glBindTexture(GL_TEXTURE_2D, SKY_FRONT_ID); + skyfronttexture->enable(); + + + glBegin(GL_QUADS); + + glColor4f(1, 1, 1, 1.0); + + glTexCoord2f(1-d, 1-d); glVertex3f(x, y, z + l); + glTexCoord2f(1-d, 0+d); glVertex3f(x, y + h, z + l); + glTexCoord2f(0+d, 0+d); glVertex3f(x + w, y + h, z + l); + glTexCoord2f(0+d, 1-d); glVertex3f(x + w, y, z + l); + glEnd(); + + + + //glBindTexture(GL_TEXTURE_2D, SKY_TOP_ID); + skytoptexture->enable(); + + + glBegin(GL_QUADS); + glColor4f(1, 1, 1, 1.0); + + glTexCoord2f(0+d, 0+d); glVertex3f(x + w, y + h, z + l); + glTexCoord2f(1-d, 0+d); glVertex3f(x + w, y + h, z); + glTexCoord2f(1-d, 1-d); glVertex3f(x, y + h, z); + glTexCoord2f(0+d, 1-d); glVertex3f(x, y + h, z + l); + /*glTexCoord2f(1.0f, 0+d); glVertex3f(x + w, y + h, z); + glTexCoord2f(1.0f, 1.0f); glVertex3f(x + w, y + h, z + l); + glTexCoord2f(0+d, 1.0f); glVertex3f(x, y + h, z + l); + glTexCoord2f(0+d, 0+d); glVertex3f(x, y + h, z);*/ + + + glEnd(); + + + + //glBindTexture(GL_TEXTURE_2D, SKY_BOTTOM_ID); + skybottomtexture->enable(); + + + glBegin(GL_QUADS); + glColor4f(1, 1, 1, 1.0); + + glTexCoord2f(1-d, 0+d); glVertex3f(x, y, z); + glTexCoord2f(1-d, 1-d); glVertex3f(x + w, y, z); + glTexCoord2f(0+d, 1-d); glVertex3f(x + w, y, z + l); + glTexCoord2f(0+d, 0+d); glVertex3f(x, y, z + l); + + + glEnd(); + + //glBindTexture(GL_TEXTURE_2D, SKY_LEFT_ID); + skylefttexture->enable(); + + + glBegin(GL_QUADS); + glColor4f(1, 1, 1, 1.0); + glTexCoord2f(1-d, 0+d); glVertex3f(x, y + h, z); + glTexCoord2f(0+d, 0+d); glVertex3f(x, y + h, z + l); + glTexCoord2f(0+d, 1-d); glVertex3f(x, y, z + l); + glTexCoord2f(1-d, 1-d); glVertex3f(x, y, z); + + glEnd(); + + //glBindTexture(GL_TEXTURE_2D, SKY_RIGHT_ID); + skyrighttexture->enable(); + + glBegin(GL_QUADS); + glColor4f(1, 1, 1, 1.0); + glTexCoord2f(0+d, 1-d); glVertex3f(x + w, y, z); + glTexCoord2f(1-d, 1-d); glVertex3f(x + w, y, z + l); + glTexCoord2f(1-d, 0+d); glVertex3f(x + w, y + h, z + l); + glTexCoord2f(0+d, 0+d); glVertex3f(x + w, y + h, z); + + + glEnd(); + glEndList(); + } + + glPopMatrix(); + glEnable(GL_DEPTH_TEST); + glEnable(GL_CULL_FACE); + glDisable(GL_TEXTURE_2D); + glEnable(GL_LIGHTING); + glShadeModel(GL_SMOOTH); +} + +void enable2D(void){ + glDisable(GL_LIGHTING); + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + gluOrtho2D(0, 1, 1, 0); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); +} + +void disable2D(void){ + glPopMatrix(); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glEnable(GL_DEPTH_TEST); + glEnable(GL_CULL_FACE); + glEnable(GL_LIGHTING); +} diff --git a/src/3dutils.h b/src/3dutils.h index 5476e8f..6b8b93e 100644 --- a/src/3dutils.h +++ b/src/3dutils.h @@ -1,57 +1,57 @@ -#ifndef __3DUTILS_H_INCLUDED__ -#define __3DUTILS_H_INCLUDED__ - -#include "main.h" -#include "texture.h" - - - -#define SKYFRONT DATAPATH"tback.png" -#define SKYBACK DATAPATH"tfront.png" -#define SKYLEFT DATAPATH"tleft.png" -#define SKYRIGHT DATAPATH"tright.png" -#define SKYTOP DATAPATH"ttop.png" -#define SKYBOTTOM DATAPATH"tbottom.png" - - -#define DAMAGEHEAD DATAPATH"damagehead.png" -#define DAMAGETORSO DATAPATH"damagetorso.png" -#define DAMAGEHAND DATAPATH"damagehand.png" -#define DAMAGELEG DATAPATH"damageleg.png" -#define FACE DATAPATH"perusnaama3.png" - -extern int SKYBOX; - -typedef struct{ - float x,y; -} point2d; - -typedef struct{ - float x,y,z; -} point3d; - -extern Texture *flaretexture; -extern Texture *skyfronttexture; -extern Texture *skybacktexture; -extern Texture *skylefttexture; -extern Texture *skyrighttexture; -extern Texture *skytoptexture; -extern Texture *skybottomtexture; -extern Texture *damageHead; -extern Texture *faceTexture; - -void createLathedSurface(point2d *points, point2d *pointderivates, int count, int slices, int stacks); -void createSphere(float r, int slices, int stacks); -void createSphere(float r); - -float distanceFromPlane(float point[3], float normal[3], float distance); - -void createSkyBox(float x, float y, float z, float w, float h, float l); - - -//MUST be called in pairs, enable pushes and disable pops -void enable2D(void); -void disable2D(void); - -#endif - +#ifndef __3DUTILS_H_INCLUDED__ +#define __3DUTILS_H_INCLUDED__ + +#include "main.h" +#include "texture.h" + + + +#define SKYFRONT DATAPATH"tback.png" +#define SKYBACK DATAPATH"tfront.png" +#define SKYLEFT DATAPATH"tleft.png" +#define SKYRIGHT DATAPATH"tright.png" +#define SKYTOP DATAPATH"ttop.png" +#define SKYBOTTOM DATAPATH"tbottom.png" + + +#define DAMAGEHEAD DATAPATH"damagehead.png" +#define DAMAGETORSO DATAPATH"damagetorso.png" +#define DAMAGEHAND DATAPATH"damagehand.png" +#define DAMAGELEG DATAPATH"damageleg.png" +#define FACE DATAPATH"perusnaama3.png" + +extern int SKYBOX; + +typedef struct{ + float x,y; +} point2d; + +typedef struct{ + float x,y,z; +} point3d; + +extern Texture *flaretexture; +extern Texture *skyfronttexture; +extern Texture *skybacktexture; +extern Texture *skylefttexture; +extern Texture *skyrighttexture; +extern Texture *skytoptexture; +extern Texture *skybottomtexture; +extern Texture *damageHead; +extern Texture *faceTexture; + +void createLathedSurface(point2d *points, point2d *pointderivates, int count, int slices, int stacks); +void createSphere(float r, int slices, int stacks); +void createSphere(float r); + +float distanceFromPlane(float point[3], float normal[3], float distance); + +void createSkyBox(float x, float y, float z, float w, float h, float l); + + +//MUST be called in pairs, enable pushes and disable pops +void enable2D(void); +void disable2D(void); + +#endif + diff --git a/src/appearance.cpp b/src/appearance.cpp index 15a77f7..bd22b7f 100644 --- a/src/appearance.cpp +++ b/src/appearance.cpp @@ -1,117 +1,117 @@ -#include "main.h" - - -#include "appearance.h" -#include "utils.h" -#include "3dutils.h" -#include "glapi.h" - -Appearance::Appearance(void){ -} - -void Appearance::prepare(void){ -} - - - -/*BoxAppearance::BoxAppearance(void){ - setDimension(-1, 1, -1, 1, -1, 1); -} - -BoxAppearance::setDimension(float x1, float x2, float y1, float y2, float z1, float z2){ - if (x1 > x2) swapFloat(&x1, &x2); - if (y1 > y2) swapFloat(&y1, &y2); - if (z1 > z2) swapFloat(&z1, &z2); - this->x1 = x1; - this->x2 = x2; - this->y1 = y1; - this->y2 = y2; - this->z1 = z1; - this->z2 = z2; -} - -void BoxAppearance::draw(void){ - - this->material.enable(); - - glBegin(GL_QUADS); - - //Front Face - glNormal3f(0, 0, 1); - glVertex3f(x1, y1, z2); - glVertex3f(x2, y1, z2); - glVertex3f(x2, y2, z2); - glVertex3f(x1, y2, z2); - // Back Face - glNormal3f(0, 0, -1); - glVertex3f(x1, y1, z1); - glVertex3f(x1, y2, z1); - glVertex3f(x2, y2, z1); - glVertex3f(x2, y1, z1); - // Top Face - glNormal3f(0, 1, 0); - glVertex3f(x1, y2, z1); - glVertex3f(x1, y2, z2); - glVertex3f(x2, y2, z2); - glVertex3f(x2, y2, z1); - // Bottom Face - glNormal3f(0, -1, 0); - glVertex3f(x1, y1, z1); - glVertex3f(x2, y1, z1); - glVertex3f(x2, y1, z2); - glVertex3f(x1, y1, z2); - // Right face - glNormal3f(x2, 0, 0); - glVertex3f(x2, y1, z1); - glVertex3f(x2, y2, z1); - glVertex3f(x2, y2, z2); - glVertex3f(x2, y1, z2); - // Left Face - glNormal3f(x1, 0, 0); - glVertex3f(x1, y1, z1); - glVertex3f(x1, y1, z2); - glVertex3f(x1, y2, z2); - glVertex3f(x1, y2, z1); - glEnd(); - - this->material.disable(); -}*/ - - -Material* Appearance::getMaterial(void){ - return &this->material; -} - -void Appearance::setMaterial(Material matsku){ - material = matsku; -} - - - - -MultiAppearance::MultiAppearance(void){ - appearances = NULL; -} - -void MultiAppearance::addAppearance(Appearance *appearance){ - appearancelist *node = new appearancelist; - node->data = appearance; - node->next = appearances; - appearances = node; -} - -void MultiAppearance::prepare(void){ - appearancelist *node = appearances; - while (node != NULL){ - node->data->prepare(); - node = node->next; - } -} - -void MultiAppearance::draw(void){ - appearancelist *node = appearances; - while (node != NULL){ - node->data->draw(); - node = node->next; - } -} +#include "main.h" + + +#include "appearance.h" +#include "utils.h" +#include "3dutils.h" +#include "glapi.h" + +Appearance::Appearance(void){ +} + +void Appearance::prepare(void){ +} + + + +/*BoxAppearance::BoxAppearance(void){ + setDimension(-1, 1, -1, 1, -1, 1); +} + +BoxAppearance::setDimension(float x1, float x2, float y1, float y2, float z1, float z2){ + if (x1 > x2) swapFloat(&x1, &x2); + if (y1 > y2) swapFloat(&y1, &y2); + if (z1 > z2) swapFloat(&z1, &z2); + this->x1 = x1; + this->x2 = x2; + this->y1 = y1; + this->y2 = y2; + this->z1 = z1; + this->z2 = z2; +} + +void BoxAppearance::draw(void){ + + this->material.enable(); + + glBegin(GL_QUADS); + + //Front Face + glNormal3f(0, 0, 1); + glVertex3f(x1, y1, z2); + glVertex3f(x2, y1, z2); + glVertex3f(x2, y2, z2); + glVertex3f(x1, y2, z2); + // Back Face + glNormal3f(0, 0, -1); + glVertex3f(x1, y1, z1); + glVertex3f(x1, y2, z1); + glVertex3f(x2, y2, z1); + glVertex3f(x2, y1, z1); + // Top Face + glNormal3f(0, 1, 0); + glVertex3f(x1, y2, z1); + glVertex3f(x1, y2, z2); + glVertex3f(x2, y2, z2); + glVertex3f(x2, y2, z1); + // Bottom Face + glNormal3f(0, -1, 0); + glVertex3f(x1, y1, z1); + glVertex3f(x2, y1, z1); + glVertex3f(x2, y1, z2); + glVertex3f(x1, y1, z2); + // Right face + glNormal3f(x2, 0, 0); + glVertex3f(x2, y1, z1); + glVertex3f(x2, y2, z1); + glVertex3f(x2, y2, z2); + glVertex3f(x2, y1, z2); + // Left Face + glNormal3f(x1, 0, 0); + glVertex3f(x1, y1, z1); + glVertex3f(x1, y1, z2); + glVertex3f(x1, y2, z2); + glVertex3f(x1, y2, z1); + glEnd(); + + this->material.disable(); +}*/ + + +Material* Appearance::getMaterial(void){ + return &this->material; +} + +void Appearance::setMaterial(Material matsku){ + material = matsku; +} + + + + +MultiAppearance::MultiAppearance(void){ + appearances = NULL; +} + +void MultiAppearance::addAppearance(Appearance *appearance){ + appearancelist *node = new appearancelist; + node->data = appearance; + node->next = appearances; + appearances = node; +} + +void MultiAppearance::prepare(void){ + appearancelist *node = appearances; + while (node != NULL){ + node->data->prepare(); + node = node->next; + } +} + +void MultiAppearance::draw(void){ + appearancelist *node = appearances; + while (node != NULL){ + node->data->draw(); + node = node->next; + } +} diff --git a/src/appearance.h b/src/appearance.h index 19c278e..b7191e3 100644 --- a/src/appearance.h +++ b/src/appearance.h @@ -1,44 +1,44 @@ -#ifndef __APPEARANCE_H_INCLUDED__ -#define __APPEARANCE_H_INCLUDED__ - -#include "main.h" - -#include "material.h" - -/* - * Abstract class for drawing objects - */ -class Appearance{ -private: -public: - Material material; - - Appearance(void); - - Material* getMaterial(void); - void setMaterial(Material mat); - - virtual void prepare(void); - virtual void draw(void) = 0; -}; - - -struct appearancelist{ - Appearance *data; - appearancelist *next; -}; - -class MultiAppearance : public Appearance{ -private: - appearancelist *appearances; - -public: - MultiAppearance(void); - void addAppearance(Appearance *appearance); - - void prepare(void); - void draw(void); -}; - -#endif - +#ifndef __APPEARANCE_H_INCLUDED__ +#define __APPEARANCE_H_INCLUDED__ + +#include "main.h" + +#include "material.h" + +/* + * Abstract class for drawing objects + */ +class Appearance{ +private: +public: + Material material; + + Appearance(void); + + Material* getMaterial(void); + void setMaterial(Material mat); + + virtual void prepare(void); + virtual void draw(void) = 0; +}; + + +struct appearancelist{ + Appearance *data; + appearancelist *next; +}; + +class MultiAppearance : public Appearance{ +private: + appearancelist *appearances; + +public: + MultiAppearance(void); + void addAppearance(Appearance *appearance); + + void prepare(void); + void draw(void); +}; + +#endif + diff --git a/src/audio.cpp b/src/audio.cpp index b357633..9f747ba 100644 --- a/src/audio.cpp +++ b/src/audio.cpp @@ -1,270 +1,270 @@ -#include "main.h" - -#include -#include - -#include "audio.h" - - -#define SOUND_FADENONE 0 -#define SOUND_FADEIN 1 -#define SOUND_FADEOUT 2 - - -struct soundlist{ - Sound *sound; - soundlist *next; -}; - -soundlist *allsounds = NULL; - - -Sound::Sound(Sound *source){ - memcpy(this, source, sizeof(Sound)); - soundlist *node = new soundlist; - node->sound = this; - node->next = allsounds; - allsounds = node; -} - -Sound::Sound(char *filename){ - load(filename, SOUNDTYPE_AUTODETECT, false); - //printf("%s: %p, %p, %p, %p\n", filename, this, stream, sample, module); -} - -Sound::Sound(char *filename, int type){ - load(filename, type, false); -} - -Sound::Sound(char *filename, bool loops){ - load(filename, SOUNDTYPE_AUTODETECT, loops); - //printf("%s: %p, %p, %p, %p\n", filename, this, stream, sample, module); -} - -Sound::Sound(char *filename, int type, bool loops){ - load(filename, type, loops); -} - -bool endsWith(char *str1, char *str2){ - char *str3 = str1 + strlen(str1) - strlen(str2); -#ifdef WIN32 - if (stricmp(str3, str2)) return false; -#else - if (strcasecmp(str3, str2)) return false; -#endif - else return true; -} - -void Sound::load(char *filename, int type, bool loops){ - this->filename = filename; - if (type == SOUNDTYPE_AUTODETECT){ - if (endsWith(filename, "mp3") || - endsWith(filename, "mp2") || - endsWith(filename, "ogg")) type = SOUNDTYPE_STREAM; - - if (endsWith(filename, "wav") || - endsWith(filename, "raw")) type = SOUNDTYPE_SAMPLE; - - if (endsWith(filename, "s3m") || - endsWith(filename, "xm") || - endsWith(filename, "it") || - endsWith(filename, "mid") || - endsWith(filename, "rmi") || - endsWith(filename, "sgr") || - endsWith(filename, "mod")) type = SOUNDTYPE_MODULE; - } -#ifdef AUDIO_FMOD - sample = NULL; - module = NULL; - stream = NULL; - this->type = type; - if (type == SOUNDTYPE_MODULE){ - module = FMUSIC_LoadSong(filename); - this->loops = false; - } else if (type == SOUNDTYPE_SAMPLE){ - if (loops){ - sample = FSOUND_Sample_Load(FSOUND_FREE, filename, FSOUND_LOOP_NORMAL, 0); - FSOUND_Sample_SetLoopMode(sample, FSOUND_LOOP_NORMAL); - } else{ - sample = FSOUND_Sample_Load(FSOUND_FREE, filename, FSOUND_LOOP_OFF, 0); - FSOUND_Sample_SetLoopMode(sample, FSOUND_LOOP_OFF); - } - this->loops = loops; - } else if (type == SOUNDTYPE_STREAM){ - if (loops){ - stream = FSOUND_Stream_OpenFile(filename, FSOUND_LOOP_NORMAL, 0); - } else{ - stream = FSOUND_Stream_OpenFile(filename, FSOUND_LOOP_OFF, 0); - } - this->loops = loops; - } -#endif - stopcallback = NULL; - soundlist *node = new soundlist; - node->sound = this; - node->next = allsounds; - allsounds = node; - minduration = 0; - setVolume(1.0); -} - - -bool Sound::play(){ - //printf("Playing %s: %p, %p, %p, %p\n", filename, this, stream, sample, module); - if (minduration > 0) return false; - running = true; - finished = false; - fademode = SOUND_FADENONE; - minduration = 0; -#ifdef AUDIO_FMOD - if (type == SOUNDTYPE_MODULE){ - FMUSIC_PlaySong(module); - FMUSIC_SetMasterVolume(module, volume*256); - } else if (type == SOUNDTYPE_SAMPLE){ - channel = FSOUND_PlaySound(FSOUND_FREE, sample); - FSOUND_SetVolume(channel, volume*256); - if (!loops){ - running = false; - finished = false; - } - } else if (type == SOUNDTYPE_STREAM){ - channel = FSOUND_Stream_Play(FSOUND_FREE, stream); - FSOUND_SetVolume(channel, volume*256); - } -#endif - //printf("Done: %f\n", volume); - return true; -} - -void Sound::play(int minduration){ - if (play()) this->minduration = minduration; -} - -void Sound::stop(){ -#ifdef AUDIO_FMOD - if (type == SOUNDTYPE_MODULE){ - FMUSIC_StopSong(module); - } else if (type == SOUNDTYPE_SAMPLE){ - FSOUND_StopSound(channel); - } else if (type == SOUNDTYPE_STREAM){ - FSOUND_Stream_Stop(stream); - } -#endif -} - -void Sound::setVolume(float volume){ - //printf("Volume %s: %f\n", filename, volume); -#ifdef AUDIO_FMOD - if (type == SOUNDTYPE_MODULE){ - FMUSIC_SetMasterVolume(module, volume*256); - } else if (type == SOUNDTYPE_SAMPLE){ - FSOUND_SetVolume(channel, volume*256); - } else if (type == SOUNDTYPE_STREAM){ - FSOUND_SetVolume(channel, volume*256); - } -#endif - this->volume = volume; -} - -#ifdef AUDIO_FMOD -signed char streamendcallback(FSOUND_STREAM *stream, void *buff, int len, int param){ - Sound *sound = (Sound *)param; - sound->setFinished(); - return true; -} -#endif - -void Sound::setStopCallback(STOPCALLBACK callback){ - stopcallback = callback; -#ifdef AUDIO_FMOD - if (type == SOUNDTYPE_MODULE){ - } else if (type == SOUNDTYPE_SAMPLE){ - //NOT SUPPORTED - } else if (type == SOUNDTYPE_STREAM){ - FSOUND_Stream_SetEndCallback(stream, streamendcallback, (int)this); - } -#endif -} - - - -void Sound::setFinished(void){ - finished = true; -} - -bool Sound::isFinished(void){ -#ifdef AUDIO_FMOD - if (type == SOUNDTYPE_MODULE){ - if (FMUSIC_IsFinished(module)) return true; - } else if (type == SOUNDTYPE_SAMPLE){ - //NOT SUPPORTED - } else if (type == SOUNDTYPE_STREAM){ - if (finished) return true; - } -#endif - return false; -} - -void Sound::update(void){ - if (running){ - if (isFinished()){ - running = false; - if (stopcallback != NULL) stopcallback(this); - } else{ - if (fademode == SOUND_FADEIN){ - if (fadepos < fadetarget){ - fadepos++; - setVolume((float)fadepos/fadetarget); - } else fademode = SOUND_FADENONE; - } - if (fademode == SOUND_FADEOUT){ - if (fadepos < fadetarget){ - fadepos++; - setVolume(1.0 - (float)fadepos/fadetarget); - } else{ - fademode = SOUND_FADENONE; - stop(); - } - } - } - } - if (minduration > 0) minduration--; -} - -void Sound::fadeIn(int length){ - fademode = SOUND_FADEIN; - fadepos = 0; - fadetarget = length; -} - -void Sound::fadeOut(int length){ - if (fademode == SOUND_FADEIN){ - float percent = 1.0 - (float)fadepos/fadetarget; - fadepos = fadetarget * percent; - } - fadepos = 0; - fadetarget = length; - fademode = SOUND_FADEOUT; -} - - -void initAudio(void){ -#ifdef AUDIO_FMOD - FSOUND_Init(44100, 32, 0); -#endif -} - -void uninitAudio(void){ -#ifdef AUDIO_FMOD - FSOUND_Close(); -#endif -} - -void updateAudio(void){ - soundlist *node = allsounds; - while (node != NULL){ - Sound *sound = node->sound; - sound->update(); - node = node->next; - } -} +#include "main.h" + +#include +#include + +#include "audio.h" + + +#define SOUND_FADENONE 0 +#define SOUND_FADEIN 1 +#define SOUND_FADEOUT 2 + + +struct soundlist{ + Sound *sound; + soundlist *next; +}; + +soundlist *allsounds = NULL; + + +Sound::Sound(Sound *source){ + memcpy(this, source, sizeof(Sound)); + soundlist *node = new soundlist; + node->sound = this; + node->next = allsounds; + allsounds = node; +} + +Sound::Sound(char *filename){ + load(filename, SOUNDTYPE_AUTODETECT, false); + //printf("%s: %p, %p, %p, %p\n", filename, this, stream, sample, module); +} + +Sound::Sound(char *filename, int type){ + load(filename, type, false); +} + +Sound::Sound(char *filename, bool loops){ + load(filename, SOUNDTYPE_AUTODETECT, loops); + //printf("%s: %p, %p, %p, %p\n", filename, this, stream, sample, module); +} + +Sound::Sound(char *filename, int type, bool loops){ + load(filename, type, loops); +} + +bool endsWith(char *str1, char *str2){ + char *str3 = str1 + strlen(str1) - strlen(str2); +#ifdef WIN32 + if (stricmp(str3, str2)) return false; +#else + if (strcasecmp(str3, str2)) return false; +#endif + else return true; +} + +void Sound::load(char *filename, int type, bool loops){ + this->filename = filename; + if (type == SOUNDTYPE_AUTODETECT){ + if (endsWith(filename, "mp3") || + endsWith(filename, "mp2") || + endsWith(filename, "ogg")) type = SOUNDTYPE_STREAM; + + if (endsWith(filename, "wav") || + endsWith(filename, "raw")) type = SOUNDTYPE_SAMPLE; + + if (endsWith(filename, "s3m") || + endsWith(filename, "xm") || + endsWith(filename, "it") || + endsWith(filename, "mid") || + endsWith(filename, "rmi") || + endsWith(filename, "sgr") || + endsWith(filename, "mod")) type = SOUNDTYPE_MODULE; + } +#ifdef AUDIO_FMOD + sample = NULL; + module = NULL; + stream = NULL; + this->type = type; + if (type == SOUNDTYPE_MODULE){ + module = FMUSIC_LoadSong(filename); + this->loops = false; + } else if (type == SOUNDTYPE_SAMPLE){ + if (loops){ + sample = FSOUND_Sample_Load(FSOUND_FREE, filename, FSOUND_LOOP_NORMAL, 0); + FSOUND_Sample_SetLoopMode(sample, FSOUND_LOOP_NORMAL); + } else{ + sample = FSOUND_Sample_Load(FSOUND_FREE, filename, FSOUND_LOOP_OFF, 0); + FSOUND_Sample_SetLoopMode(sample, FSOUND_LOOP_OFF); + } + this->loops = loops; + } else if (type == SOUNDTYPE_STREAM){ + if (loops){ + stream = FSOUND_Stream_OpenFile(filename, FSOUND_LOOP_NORMAL, 0); + } else{ + stream = FSOUND_Stream_OpenFile(filename, FSOUND_LOOP_OFF, 0); + } + this->loops = loops; + } +#endif + stopcallback = NULL; + soundlist *node = new soundlist; + node->sound = this; + node->next = allsounds; + allsounds = node; + minduration = 0; + setVolume(1.0); +} + + +bool Sound::play(){ + //printf("Playing %s: %p, %p, %p, %p\n", filename, this, stream, sample, module); + if (minduration > 0) return false; + running = true; + finished = false; + fademode = SOUND_FADENONE; + minduration = 0; +#ifdef AUDIO_FMOD + if (type == SOUNDTYPE_MODULE){ + FMUSIC_PlaySong(module); + FMUSIC_SetMasterVolume(module, volume*256); + } else if (type == SOUNDTYPE_SAMPLE){ + channel = FSOUND_PlaySound(FSOUND_FREE, sample); + FSOUND_SetVolume(channel, volume*256); + if (!loops){ + running = false; + finished = false; + } + } else if (type == SOUNDTYPE_STREAM){ + channel = FSOUND_Stream_Play(FSOUND_FREE, stream); + FSOUND_SetVolume(channel, volume*256); + } +#endif + //printf("Done: %f\n", volume); + return true; +} + +void Sound::play(int minduration){ + if (play()) this->minduration = minduration; +} + +void Sound::stop(){ +#ifdef AUDIO_FMOD + if (type == SOUNDTYPE_MODULE){ + FMUSIC_StopSong(module); + } else if (type == SOUNDTYPE_SAMPLE){ + FSOUND_StopSound(channel); + } else if (type == SOUNDTYPE_STREAM){ + FSOUND_Stream_Stop(stream); + } +#endif +} + +void Sound::setVolume(float volume){ + //printf("Volume %s: %f\n", filename, volume); +#ifdef AUDIO_FMOD + if (type == SOUNDTYPE_MODULE){ + FMUSIC_SetMasterVolume(module, volume*256); + } else if (type == SOUNDTYPE_SAMPLE){ + FSOUND_SetVolume(channel, volume*256); + } else if (type == SOUNDTYPE_STREAM){ + FSOUND_SetVolume(channel, volume*256); + } +#endif + this->volume = volume; +} + +#ifdef AUDIO_FMOD +signed char streamendcallback(FSOUND_STREAM *stream, void *buff, int len, int param){ + Sound *sound = (Sound *)param; + sound->setFinished(); + return true; +} +#endif + +void Sound::setStopCallback(STOPCALLBACK callback){ + stopcallback = callback; +#ifdef AUDIO_FMOD + if (type == SOUNDTYPE_MODULE){ + } else if (type == SOUNDTYPE_SAMPLE){ + //NOT SUPPORTED + } else if (type == SOUNDTYPE_STREAM){ + FSOUND_Stream_SetEndCallback(stream, streamendcallback, (int)this); + } +#endif +} + + + +void Sound::setFinished(void){ + finished = true; +} + +bool Sound::isFinished(void){ +#ifdef AUDIO_FMOD + if (type == SOUNDTYPE_MODULE){ + if (FMUSIC_IsFinished(module)) return true; + } else if (type == SOUNDTYPE_SAMPLE){ + //NOT SUPPORTED + } else if (type == SOUNDTYPE_STREAM){ + if (finished) return true; + } +#endif + return false; +} + +void Sound::update(void){ + if (running){ + if (isFinished()){ + running = false; + if (stopcallback != NULL) stopcallback(this); + } else{ + if (fademode == SOUND_FADEIN){ + if (fadepos < fadetarget){ + fadepos++; + setVolume((float)fadepos/fadetarget); + } else fademode = SOUND_FADENONE; + } + if (fademode == SOUND_FADEOUT){ + if (fadepos < fadetarget){ + fadepos++; + setVolume(1.0 - (float)fadepos/fadetarget); + } else{ + fademode = SOUND_FADENONE; + stop(); + } + } + } + } + if (minduration > 0) minduration--; +} + +void Sound::fadeIn(int length){ + fademode = SOUND_FADEIN; + fadepos = 0; + fadetarget = length; +} + +void Sound::fadeOut(int length){ + if (fademode == SOUND_FADEIN){ + float percent = 1.0 - (float)fadepos/fadetarget; + fadepos = fadetarget * percent; + } + fadepos = 0; + fadetarget = length; + fademode = SOUND_FADEOUT; +} + + +void initAudio(void){ +#ifdef AUDIO_FMOD + FSOUND_Init(44100, 32, 0); +#endif +} + +void uninitAudio(void){ +#ifdef AUDIO_FMOD + FSOUND_Close(); +#endif +} + +void updateAudio(void){ + soundlist *node = allsounds; + while (node != NULL){ + Sound *sound = node->sound; + sound->update(); + node = node->next; + } +} diff --git a/src/audio.h b/src/audio.h index 5317257..3029ac5 100644 --- a/src/audio.h +++ b/src/audio.h @@ -1,72 +1,72 @@ -#ifndef __AUDIO_H_INCLUDED__ -#define __AUDIO_H_INCLUDED__ - - -#ifdef AUDIO_FMOD -#include -#endif - - -class Sound; - -typedef void(* STOPCALLBACK)(Sound *sound); - -#define SOUNDTYPE_AUTODETECT 0 -#define SOUNDTYPE_MODULE 1 -#define SOUNDTYPE_STREAM 2 -#define SOUNDTYPE_SAMPLE 3 - -#define BGSONG DATAPATH"boom.mp3" - -class Sound{ -private: -#ifdef AUDIO_FMOD - int type; - FMUSIC_MODULE *module; - FSOUND_STREAM *stream; - FSOUND_SAMPLE *sample; - int channel; -#endif - bool loops; - bool finished; - bool running; - float volume; - STOPCALLBACK stopcallback; - bool isFinished(void); - - int fadepos, fadetarget; - int fademode; - - int minduration; - - char *filename; - -public: - Sound(Sound *source); - Sound(char *filename); - Sound(char *filename, int type); - Sound(char *filename, bool loops); - Sound(char *filename, int type, bool loops); - void load(char *filename, int type, bool loops); - bool play(void); - - //Plays sound for at least minduration frames until sound - //can be played again. Doesn't prevent stopping of the sound - void play(int minduration); - void stop(); - void setStopCallback(STOPCALLBACK callback); - void setVolume(float volume); - void fadeIn(int length); - void fadeOut(int length); - - //Do not use methods below - void setFinished(void); - void update(void); -}; - -void initAudio(void); -void uninitAudio(void); -void updateAudio(void); - -#endif - +#ifndef __AUDIO_H_INCLUDED__ +#define __AUDIO_H_INCLUDED__ + + +#ifdef AUDIO_FMOD +#include +#endif + + +class Sound; + +typedef void(* STOPCALLBACK)(Sound *sound); + +#define SOUNDTYPE_AUTODETECT 0 +#define SOUNDTYPE_MODULE 1 +#define SOUNDTYPE_STREAM 2 +#define SOUNDTYPE_SAMPLE 3 + +#define BGSONG DATAPATH"boom.mp3" + +class Sound{ +private: +#ifdef AUDIO_FMOD + int type; + FMUSIC_MODULE *module; + FSOUND_STREAM *stream; + FSOUND_SAMPLE *sample; + int channel; +#endif + bool loops; + bool finished; + bool running; + float volume; + STOPCALLBACK stopcallback; + bool isFinished(void); + + int fadepos, fadetarget; + int fademode; + + int minduration; + + char *filename; + +public: + Sound(Sound *source); + Sound(char *filename); + Sound(char *filename, int type); + Sound(char *filename, bool loops); + Sound(char *filename, int type, bool loops); + void load(char *filename, int type, bool loops); + bool play(void); + + //Plays sound for at least minduration frames until sound + //can be played again. Doesn't prevent stopping of the sound + void play(int minduration); + void stop(); + void setStopCallback(STOPCALLBACK callback); + void setVolume(float volume); + void fadeIn(int length); + void fadeOut(int length); + + //Do not use methods below + void setFinished(void); + void update(void); +}; + +void initAudio(void); +void uninitAudio(void); +void updateAudio(void); + +#endif + diff --git a/src/camera.cpp b/src/camera.cpp index e873a68..2a440bd 100644 --- a/src/camera.cpp +++ b/src/camera.cpp @@ -1,87 +1,87 @@ -#include "main.h" - -#include "camera.h" -#include "vector.h" -#include "glapi.h" - -Camera::Camera(void){ - right = &matrix[0]; - up = &matrix[3]; - forward = &matrix[6]; - - vectorSet(position, 0, 2, 2); - vectorSet(target, 0, 0, 0); - vectorSet(up, 0, 1, 0); - - calculateMatrix(); -} - -void Camera::setPosition(float position[3]){ - vectorCopy(this->position, position); -} - -void Camera::setPosition(float x, float y, float z){ - this->position[0] = x; - this->position[1] = y; - this->position[2] = z; -} - -void Camera::getPosition(float *position){ - vectorCopy(position, this->position); -} - -void Camera::setTarget(float target[3]){ - vectorCopy(this->target, target); -} - -void Camera::getTarget(float *target){ - vectorCopy(target, this->target); -} - -void Camera::setUp(float up[3]){ - vectorCopy(this->up, up); -} - -void Camera::getMatrix(float *matrix){ - vectorCopy(&matrix[0], &this->matrix[0]); - vectorCopy(&matrix[3], &this->matrix[3]); - vectorCopy(&matrix[6], &this->matrix[6]); -} - -void Camera::moveRight(float amount){ - float movevector[3]; - vectorScale(movevector, right, amount); - vectorAdd(position, movevector); - //vectorAdd(target, movevector); - calculateMatrix(); -} - -void Camera::moveUp(float amount){ - float movevector[3]; - vectorScale(movevector, up, amount); - vectorAdd(position, movevector); - //vectorAdd(target, movevector); - calculateMatrix(); -} - -void Camera::moveForward(float amount){ - float movevector[3]; - vectorScale(movevector, forward, amount); - vectorAdd(position, movevector); - //vectorAdd(target, movevector); - calculateMatrix(); -} - -void Camera::glUpdate(void){ - //glLoadIdentity(); - - gluLookAt(position[0], position[1], position[2], - target[0], target[1], target[2], - up[0], up[1], up[2]); -} - -void Camera::calculateMatrix(void){ - vectorSub(forward, target, position); - vectorNormalize(forward); - vectorCross(right, forward, up); -} +#include "main.h" + +#include "camera.h" +#include "vector.h" +#include "glapi.h" + +Camera::Camera(void){ + right = &matrix[0]; + up = &matrix[3]; + forward = &matrix[6]; + + vectorSet(position, 0, 2, 2); + vectorSet(target, 0, 0, 0); + vectorSet(up, 0, 1, 0); + + calculateMatrix(); +} + +void Camera::setPosition(float position[3]){ + vectorCopy(this->position, position); +} + +void Camera::setPosition(float x, float y, float z){ + this->position[0] = x; + this->position[1] = y; + this->position[2] = z; +} + +void Camera::getPosition(float *position){ + vectorCopy(position, this->position); +} + +void Camera::setTarget(float target[3]){ + vectorCopy(this->target, target); +} + +void Camera::getTarget(float *target){ + vectorCopy(target, this->target); +} + +void Camera::setUp(float up[3]){ + vectorCopy(this->up, up); +} + +void Camera::getMatrix(float *matrix){ + vectorCopy(&matrix[0], &this->matrix[0]); + vectorCopy(&matrix[3], &this->matrix[3]); + vectorCopy(&matrix[6], &this->matrix[6]); +} + +void Camera::moveRight(float amount){ + float movevector[3]; + vectorScale(movevector, right, amount); + vectorAdd(position, movevector); + //vectorAdd(target, movevector); + calculateMatrix(); +} + +void Camera::moveUp(float amount){ + float movevector[3]; + vectorScale(movevector, up, amount); + vectorAdd(position, movevector); + //vectorAdd(target, movevector); + calculateMatrix(); +} + +void Camera::moveForward(float amount){ + float movevector[3]; + vectorScale(movevector, forward, amount); + vectorAdd(position, movevector); + //vectorAdd(target, movevector); + calculateMatrix(); +} + +void Camera::glUpdate(void){ + //glLoadIdentity(); + + gluLookAt(position[0], position[1], position[2], + target[0], target[1], target[2], + up[0], up[1], up[2]); +} + +void Camera::calculateMatrix(void){ + vectorSub(forward, target, position); + vectorNormalize(forward); + vectorCross(right, forward, up); +} diff --git a/src/camera.h b/src/camera.h index e3e9591..339747f 100644 --- a/src/camera.h +++ b/src/camera.h @@ -1,32 +1,32 @@ -#ifndef __CAMERA_H_INCLUDED__ -#define __CAMERA_H_INCLUDED__ - -class Camera{ -private: - float position[3]; - float target[3]; - float matrix[9]; - float *right, *up, *forward; - - void calculateMatrix(void); - -public: - Camera(void); - - void setPosition(float position[3]); - void setPosition(float x, float y, float z); - void getPosition(float *position); - void setTarget(float target[3]); - void getTarget(float *target); - void setUp(float up[3]); - void getMatrix(float *matrix); - - void moveRight(float amount); - void moveUp(float amount); - void moveForward(float amount); - - void glUpdate(void); -}; - -#endif - +#ifndef __CAMERA_H_INCLUDED__ +#define __CAMERA_H_INCLUDED__ + +class Camera{ +private: + float position[3]; + float target[3]; + float matrix[9]; + float *right, *up, *forward; + + void calculateMatrix(void); + +public: + Camera(void); + + void setPosition(float position[3]); + void setPosition(float x, float y, float z); + void getPosition(float *position); + void setTarget(float target[3]); + void getTarget(float *target); + void setUp(float up[3]); + void getMatrix(float *matrix); + + void moveRight(float amount); + void moveUp(float amount); + void moveForward(float amount); + + void glUpdate(void); +}; + +#endif + diff --git a/src/collision.cpp b/src/collision.cpp index e43255a..c0e9de7 100644 --- a/src/collision.cpp +++ b/src/collision.cpp @@ -1,757 +1,757 @@ -#include -#include - -#include "object.h" -#include "vector.h" -#include "collision.h" -#include "mesh.h" -#include "3dutils.h" -#include "world.h" -#include "audio.h" - - -//objectlist *collisionlists[32]; -unsigned int collisionlinks[32]; - -Contact *contacts; -int contactcount; - -void initCollisions(void){ - int i; - for (i = 0; i < 32; i++){ - //collisionlists[i] = NULL; - collisionlinks[i] = 0; - } -} - -/*void addCollisionObject(Object *object, int group){ - objectlist *node = new objectlist; - node->object = object; - node->next = collisionlists[group]; - collisionlists[group] = node; -}*/ - -void addCollisionLink(int source, int target){ - collisionlinks[source] |= (1<object1 = source; - contact->object2 = target; - vectorCopy(contact->normal, normal); - vectorCopy(contact->position, contactpoint); -} - -#define KINETICFRICTION 0.4 - -bool handleCollision(Contact *contact){ - Object *source = contact->object1; - Object *target = contact->object2; - float *normal = contact->normal; - float *contactpoint = contact->position; - - float sourcevelocity[3], targetvelocity[3]; - float sourcecontactpoint[3], targetcontactpoint[3]; - - vectorSub(sourcecontactpoint, contactpoint, source->position); - source->getVelocity(sourcevelocity, sourcecontactpoint); - - if (target == NULL){ - vectorSet(targetcontactpoint, 0, 0, 0); - vectorSet(targetvelocity, 0, 0, 0); - } else{ - vectorSub(targetcontactpoint, contactpoint, target->position); - target->getVelocity(targetvelocity, targetcontactpoint); - } - - float deltavelocity[3]; - vectorSub(deltavelocity, sourcevelocity, targetvelocity); - float dot = vectorDot(deltavelocity, normal); - - //if (fabs(dot) < EPSILON) return false; - //if (dot > -1.0e-5 && dot < 1.0e-5) return false; - //if (dot >= 0) return false; - if (dot > -1.0e-5) return false; - - - float invmass1; - invmass1 = source->invmass; - - float invmass2; - if (target == NULL) invmass2 = 0; - else invmass2 = target->invmass; - - float t1; - if (source->invmomentofinertia == 0){ - t1 = 0; - } else{ - float v1[3]; - vectorCross(v1, sourcecontactpoint, normal); - vectorScale(v1, source->invmomentofinertia); - float w1[3]; - vectorCross(w1, v1, sourcecontactpoint); - t1 = vectorDot(normal, w1); - } - - float t2; - if (target == NULL || target->invmomentofinertia == 0){ - t2 = 0; - } else{ - float v1[3]; - vectorCross(v1, targetcontactpoint, normal); - vectorScale(v1, target->invmomentofinertia); - float w1[3]; - vectorCross(w1, v1, targetcontactpoint); - t2 = vectorDot(normal, w1); - } - - float denominator = invmass1 + invmass2 + t1 + t2; - - float e = 1.0 - COLLISIONFRICTION; - - float impulsesize = (1 + e) * dot / denominator; - - //printf("%f\n", impulsesize); - - float impulse[3]; - vectorScale(impulse, normal, impulsesize); - - - float friction[3]; - vectorScale(friction, normal, vectorDot(deltavelocity, normal)); - vectorAdd(friction, deltavelocity); - vectorNormalize(friction); - float frictionsize = 10*KINETICFRICTION*dot/denominator; - float maxfrictionsize = 0.1*vectorLength(deltavelocity); - if (frictionsize < -maxfrictionsize) frictionsize = -maxfrictionsize; - vectorScale(friction, -frictionsize); - vectorAdd(impulse, friction); - - - if (target != NULL){ - target->addImpulse(impulse, targetcontactpoint); - target->calculateStateVariables(); - } - - float speed; - float speed2[3]; - - if (target != NULL && source != NULL){ - //float kvel[3]; - //source->getVelocity(kvel); - float k = vectorLength(sourcevelocity)*0.1; - //if (k > 1) k = 1; - speed = -impulsesize*target->invmass*k; - vectorScale(speed2, impulse, target->invmass*k); - /*float kvel[3]; - source->getVelocity(kvel); - float k = 0;//vectorDot(speed2, kvel); - if (k < EPSILON) k = 0; - speed *= k; - vectorScale(speed2, k); - if (k > 0) */target->hitForce(speed, speed2, source); - } - - - vectorScale(impulse, -1); - source->addImpulse(impulse, sourcecontactpoint); - source->calculateStateVariables(); - - //vectorScale(speed, source->invmass); - if (target != NULL && source != NULL){ - //float kvel[3]; - //target->getVelocity(kvel); - float k = vectorLength(targetvelocity)*0.1; - //if (k > 1) k = 1; - speed = -impulsesize*source->invmass*k; - vectorScale(speed2, impulse, source->invmass*k); - /*float kvel[3]; - target->getVelocity(kvel); - float k = 0;//vectorDot(speed2, kvel); - if (k < EPSILON) k = 0; - speed *= k; - vectorScale(speed2, k); - if (k > 0) */source->hitForce(speed, speed2, target); - } - - - return true; -} - - -bool handleLink(ObjectLink *link){ - if (!link->enabled) return false; - - Object *source = link->object1; - Object *target = link->object2; - - float normal[3]; - float contactpoint1[3], contactpoint2[3]; - source->transformPoint(contactpoint1, link->point1); - target->transformPoint(contactpoint2, link->point2); - - float diff[3]; - vectorSub(diff, contactpoint1, contactpoint2); - vectorNormalize(normal, diff); - - float strength = vectorDot(diff, diff); - - if (strength < 1.0e-5) return false; - - float sourcevelocity[3], targetvelocity[3]; - float sourcecontactpoint[3], targetcontactpoint[3]; - - vectorSub(sourcecontactpoint, contactpoint1, source->position); - source->getVelocity(sourcevelocity, sourcecontactpoint); - - vectorSub(targetcontactpoint, contactpoint2, target->position); - target->getVelocity(targetvelocity, targetcontactpoint); - - float deltavelocity[3]; - vectorSub(deltavelocity, sourcevelocity, targetvelocity); - float dot = vectorDot(deltavelocity, normal); - - //if (fabs(dot) < EPSILON) return false; - //if (dot > -1.0e-5 && dot < 1.0e-5) return false; - //if (dot >= 0) return false; - //if (dot > -1.0e-5) return false; - - - float invmass1 = source->invmass; - float invmass2 = target->invmass; - - float t1; - if (source->invmomentofinertia == 0){ - t1 = 0; - } else{ - float v1[3]; - vectorCross(v1, sourcecontactpoint, normal); - vectorScale(v1, source->invmomentofinertia); - float w1[3]; - vectorCross(w1, v1, sourcecontactpoint); - t1 = vectorDot(normal, w1); - } - - float t2; - if (target->invmomentofinertia == 0){ - t2 = 0; - } else{ - float v1[3]; - vectorCross(v1, targetcontactpoint, normal); - vectorScale(v1, target->invmomentofinertia); - float w1[3]; - vectorCross(w1, v1, targetcontactpoint); - t2 = vectorDot(normal, w1); - } - - float denominator = invmass1 + invmass2 + t1 + t2; - - float impulsesize = (dot + strength*100) / denominator; - - //printf("%f\n", impulsesize); - - float impulse[3]; - vectorScale(impulse, normal, impulsesize); - - - target->addImpulse(impulse, targetcontactpoint); - target->calculateStateVariables(); - - vectorScale(impulse, -1); - source->addImpulse(impulse, sourcecontactpoint); - source->calculateStateVariables(); - - - return true; -} - -bool checkCollisions(Object *object, float *contactnormal){ - //bool collision = false; - int group = object->getCollisionGroup(); - int groups = collisionlinks[group]; - group = 0; - int collisions = 0; - /*float oldmomentum[3]; - vectorCopy(oldmomentum, object->momentum); - - while (groups){ - if (groups & 1){ - objectlist *node = collisionlists[group]; - while (node != NULL){ - Object *object2 = node->object; - node = node->next; - if (object != object2){ - if (object2->geometry->checkCollision(object, contactnormal)){ - collisions++; - } - } - } - } - group++; - groups >>= 1; - } - /*float temp[3]; - vectorSub(temp, object->momentum, oldmomentum); - vectorScale(temp, 1.0/DT); - object->addForce(temp);*/ - //vectorSub(object-> - //vectorCopy(object->momentum, oldmomentum); - //printf("%i\n", collisions); - //vectorScale(object->force, 1.0/collisions); - /*if (collisions > 0){ - vectorScale(object->force, 2.0/vectorLength(object->momentum)); - }*/ - return collisions > 0; -} - -/* - * mass = 0 means infinite mass - */ -/*void collide(float *velocity1, float *velocity2, - float mass1, float mass2, - float *normal, float *newimpulse){ - float deltavelocity[3]; - vectorSub(deltavelocity, velocity1, velocity2); - float dot = vectorDot(deltavelocity, normal); - float massinverse1 = 0; - float massinverse2 = 0; - if (mass1 != 0) massinverse1 = 1.0 / mass1; - if (mass2 != 0) massinverse2 = 1.0 / mass2; - float impulsesize = -1 * dot / (massinverse1 + massinverse2); - vectorScale(newimpulse, normal, impulsesize); - if (dot > 0){ - vectorSet(newimpulse, 0, 0, 0); - } -}*/ - -void collide(Object *source, Object *target, float *normal, float *contactpoint){ -/* float momentum[3]; - source->getMomentum(momentum); - - float sourcevelocity[3], targetvelocity[3]; - float sourcecontactpoint[3], targetcontactpoint[3]; - - //source->unTransformPoint(sourcecontactpoint, contactpoint); - //target->unTransformPoint(targetcontactpoint, contactpoint); - vectorSub(sourcecontactpoint, contactpoint, source->position); - vectorSub(targetcontactpoint, contactpoint, target->position); - - source->getVelocity(sourcevelocity);//, sourcecontactpoint); - float sourcemass = source->getMass(); - - target->getVelocity(targetvelocity);//, targetcontactpoint); - float targetmass = target->getMass(); - - float deltavelocity[3]; - vectorSub(deltavelocity, sourcevelocity, targetvelocity); - float dot = vectorDot(deltavelocity, normal); - float massinverse1 = 0; - float massinverse2 = 0; - if (sourcemass != 0) massinverse1 = 1.0 / sourcemass; - if (targetmass != 0) massinverse2 = 1.0 / targetmass; - - float t1; - if (source->invmomentofinertia == 0){ - t1 = 0; - } else{ - float v1[3]; - vectorCross(v1, sourcecontactpoint, normal); - vectorScale(v1, 1.0/source->momentofinertia); - float w1[3]; - vectorCross(w1, v1, sourcecontactpoint); - t1 = vectorDot(normal, w1); - } - //printf("S: %f, %f, %f\n", sourcecontactpoint[0], source->momentofinertia, v1); - - float t2; - if (target->momentofinertia == 0){ - t2 = 0; - } else{ - float v2[3]; - vectorCross(v2, targetcontactpoint, normal); - vectorScale(v2, 1.0/target->momentofinertia); - float w2[3]; - vectorCross(w2, v2, targetcontactpoint); - t2 = vectorDot(normal, w2); - } - //printf("T: %f, %f, %f\n", targetcontactpoint[0], target->momentofinertia, v2); - - - float divisor; - divisor = massinverse1 + massinverse2;// + t1 + t2; - - printf("%f, %f, %f, %f : %f\n", massinverse1, massinverse2, t1, t2, divisor); - - float impulsesize = -dot / divisor; - - float impulse[3]; - vectorScale(impulse, normal, impulsesize); - //collide(sourcevelocity, targetvelocity, sourcemass, targetmass, normal, impulse); - - //vectorAdd(source->momentum, impulse); - - float *force = impulse; - - //vectorScale(force, 2.0/DT); - printf("F: %f, %f, %f\n", impulse[0], impulse[1], impulse[2]); - - //float cp[3]; - //vectorSub(cp, contactpoint, source->position); - //source->addForce(force, sourcecontactpoint);*/ -} - - - -bool checkSphereMeshCollision(float *sphereposition, float r, Mesh *mesh, float *normal, float *contactpoint){ - float linenormal[3]; - float pointnormal[3]; - float maxdist = 0; - bool planecollision = false; - bool linecollision = false; - bool pointcollision = false; - - int i, j; - - for (i = 0; i < mesh->polygoncount; i++){ - class Polygon *polygon = &mesh->polygons[i]; - - float dist = distanceFromPlane(sphereposition, polygon->planenormal, polygon->planedistance); - if (dist < r && dist > -r){ - bool directcollision = true; - for (j = 0; j < polygon->vertexcount; j++){ - float *p1 = polygon->vertices[j]->position; - float *p2 = polygon->vertices[(j+1)%polygon->vertexcount]->position; - float *p3 = polygon->vertices[(j+2)%polygon->vertexcount]->position; - float v1[3], v2[3]; - vectorSub(v1, p2, p1); - - //Collision for polygon surface - vectorSub(v2, p3, p2); - float t1[3]; - vectorProject(t1, v2, v1); - float norm[3]; - vectorSub(norm, v2, t1); - vectorNormalize(norm); - - //Collision for polygon edges - float newpoint[3]; - vectorSub(newpoint, sphereposition, p1); - float dist2 = vectorDot(newpoint, norm); - if (dist2 < 0){ - directcollision = false; - float projloc = vectorDot(newpoint, v1) / vectorDot(v1, v1); - if (projloc >= 0 && projloc <= 1){ - float proj[3]; - vectorScale(proj, v1, projloc); - float projorth[3]; - vectorSub(projorth, newpoint, proj); - float l2 = vectorDot(projorth, projorth); - if (l2 < r*r){ - vectorNormalize(linenormal, projorth); - if (dist < 0) vectorScale(linenormal, -1); - linecollision = true; - } - } - } - - //Collision for polygon vertices - float pointdiff[3]; - vectorSub(pointdiff, sphereposition, p1); - float l3 = vectorDot(pointdiff, pointdiff); - if (l3 < r*r){ - vectorScale(pointnormal, pointdiff, 1.0 / sqrt(l3)); - if (dist < 0) vectorScale(pointnormal, -1); - pointcollision = true; - } - } - if (directcollision){ - if (dist > maxdist || !planecollision){ - vectorCopy(normal, polygon->planenormal); - maxdist = dist; - planecollision = true; - } - } - } - } - - if (planecollision){ - vectorScale(contactpoint, normal, -r); - vectorAdd(contactpoint, sphereposition); - } else if (linecollision){ - vectorScale(contactpoint, linenormal, -r); - vectorAdd(contactpoint, sphereposition); - vectorCopy(normal, linenormal); - } else if (pointcollision){ - vectorScale(contactpoint, pointnormal, -r); - vectorAdd(contactpoint, sphereposition); - vectorCopy(normal, pointnormal); - } else{ - return false; - } - - return true; -} - - - - - -bool checkPointMeshCollision(float *position, Mesh *mesh, float *normal, float *contactpoint){ - float maxdist = 0; - bool planecollision = false; - - int i; - - for (i = 0; i < mesh->polygoncount; i++){ - class Polygon *polygon = &mesh->polygons[i]; - - float dist = distanceFromPlane(position, polygon->planenormal, polygon->planedistance); - if (dist < 0){ - bool directcollision = true; - /*for (j = 0; j < polygon->vertexcount; j++){ - float *p1 = polygon->vertices[j]->position; - float *p2 = polygon->vertices[(j+1)%polygon->vertexcount]->position; - float *p3 = polygon->vertices[(j+2)%polygon->vertexcount]->position; - float v1[3], v2[3]; - vectorSub(v1, p2, p1); - - //Collision for polygon surface - vectorSub(v2, p3, p2); - float t1[3]; - vectorProject(t1, v2, v1); - float norm[3]; - vectorSub(norm, v2, t1); - vectorNormalize(norm); - - //Collision for polygon edges - float newpoint[3]; - vectorSub(newpoint, position, p1); - float dist2 = vectorDot(newpoint, norm); - if (dist2 < 0) directcollision = false; - }*/ - if (directcollision){ - if (dist > maxdist || !planecollision){ - vectorCopy(normal, polygon->planenormal); - maxdist = dist; - planecollision = true; - } - } - } else{ - return false; - } - } - - if (planecollision){ - vectorCopy(contactpoint, position); - } else{ - return false; - } - - return true; -} - -#define MAXPOLYGONS 1000 - -struct tracehit{ - float t; - Polygon *polygon; -}; - -bool tracePlane(tracehit *result, float *origin, float *ray, class Polygon *polygon){ - float *normal = polygon->planenormal; - float D = polygon->planedistance; - float denominator = vectorDot(normal, ray); - if (denominator == 0){ - if (vectorDot(normal, origin) > 0) result->t = 1000000; - else result->t = -1000000; - result->polygon = polygon; - return true; - } - - float t = - (vectorDot(normal, origin) + D) / denominator; - - result->t = t; - result->polygon = polygon; - - //if (t < 0 || t > 1) return false; - - return true; -} - -Edge *findSharingEdge(class Polygon *p1, class Polygon *p2){ - //printf("Edges:\n"); - int i, j; - for (i = 0; i < p1->vertexcount; i++){ - //printf("%p\n", p1->edges[i]); - for (j = 0; j < p2->vertexcount; j++){ - if (p1->edges[i] == p2->edges[j]) return p1->edges[i]; - } - } - return NULL; -} - -/*Polygon *findSharingPolygon(Mesh *mesh, class Polygon *p1, class Polygon *p2){ - //printf("Edges:\n"); - int i, j; - for (i = 0; i < p1->vertexcount; i++){ - //printf("%p\n", p1->edges[i]); - for (j = 0; j < p2->vertexcount; j++){ - if (p1->edges[i] == p2->edges[j]) return p1->edges[i]; - } - } - return NULL; -}*/ -Polygon *findNearestPolygon(class Polygon *polygon, float *point){ - int i; - float mindist = 0; - Polygon *nearestpolygon = NULL; - for (i = 0; i < polygon->edgecount; i++){ - Edge *edge = polygon->edges[i]; - Polygon *polygon2 = edge->p1; - if (polygon2 == polygon) polygon2 = edge->p2; - float newdist = distanceFromPlane(point, polygon2->planenormal, polygon2->planedistance); - if (newdist > 0) return NULL; - if (mindist == 0 || newdist > mindist){ - mindist = newdist; - nearestpolygon = polygon2; - } - } - return nearestpolygon; -} - -bool checkEdgeMeshCollision(float *p1, float *p2, Mesh *mesh, float *normal, float *contactpoint){ - float ray[3]; - vectorSub(ray, p2, p1); - - float maxdist = 0; - bool collision = false; - - int i, j; - - tracehit hits[MAXPOLYGONS]; - int hitcount = 0; - - for (i = 0; i < mesh->polygoncount; i++){ - class Polygon *polygon = &mesh->polygons[i]; - - if (tracePlane(&hits[hitcount], p1, ray, polygon)){ - hitcount++; - } - } - - if (hitcount < 2) return false; - - for (i = 1; i < hitcount; i++){ - for (j = i; j > 0; j--){ - if (hits[j].t < hits[j-1].t){ - float tempt = hits[j].t; - hits[j].t = hits[j-1].t; - hits[j-1].t = tempt; - class Polygon *tempp = hits[j].polygon; - hits[j].polygon = hits[j-1].polygon; - hits[j-1].polygon = tempp; - } else break; - } - } - - int negative = -1, positive = -1; - - - for (i = 0; i < hitcount; i++){ - float t = hits[i].t; - class Polygon *polygon = hits[i].polygon; - - float dot = vectorDot(ray, polygon->planenormal); - - if (dot > 0 && positive == -1) positive = i; - if (dot < 0) negative = i; - - if (dot < 0 && positive != -1) return false; - } - - if (negative == -1 || positive == -1) return false; - - /*for (i = 0; i < hitcount; i++){ - float t = hits[i].t; - class Polygon *polygon = hits[i].polygon; - - float dot = vectorDot(ray, polygon->planenormal); - - printf("%f ", dot); - } - printf("\n");*/ - - if (hits[negative].t < 0 || hits[positive].t > 1) return false; - - Edge *edge2 = findSharingEdge(hits[negative].polygon, hits[positive].polygon); - - //fflush(stdout); - float cp1[3], cp2[3]; - vectorScale(cp1, ray, hits[negative].t); - vectorAdd(cp1, p1); - vectorScale(cp2, ray, hits[positive].t); - vectorAdd(cp2, p1); - - if (edge2 != NULL){ - - /*float ev1[3]; - vectorSub(ev1, edge2->v2->position, edge2->v1->position); - vectorCross(normal, ev1, ray); - vectorScale(normal, vectorDot(normal, hits[positive].polygon->planenormal)); - vectorNormalize(normal); - - float at = (hits[negative].t + hits[positive].t) / 2; - vectorScale(contactpoint, ray, at); - vectorAdd(contactpoint, p1);*/ - - float dot1 = fabs(vectorDot(ray, hits[negative].polygon->planenormal)); - float dot2 = fabs(vectorDot(ray, hits[positive].polygon->planenormal)); - - if (dot1 > dot2){ - //vectorScale(contactpoint, ray, hits[negative].t); - //vectorAdd(contactpoint, p1); - vectorCopy(contactpoint, cp1); - vectorCopy(normal, hits[positive].polygon->planenormal); - } else{ - //vectorScale(contactpoint, ray, hits[positive].t); - //vectorAdd(contactpoint, p1); - vectorCopy(contactpoint, cp2); - vectorCopy(normal, hits[negative].polygon->planenormal); - } - } else{ - Polygon *polygon = findNearestPolygon(hits[negative].polygon, cp1); - if (polygon != NULL){ - /*vectorCopy(contactpoint, cp1); - vectorAdd(contactpoint, cp2); - vectorScale(contactpoint, 0.5);*/ - float at = (hits[negative].t + hits[positive].t) / 2; - vectorScale(contactpoint, ray, at); - vectorAdd(contactpoint, p1); - - vectorCopy(normal, polygon->planenormal); - } else{ - return false; - } - } - - - //shotsound->play(); - return true; -} +#include +#include + +#include "object.h" +#include "vector.h" +#include "collision.h" +#include "mesh.h" +#include "3dutils.h" +#include "world.h" +#include "audio.h" + + +//objectlist *collisionlists[32]; +unsigned int collisionlinks[32]; + +Contact *contacts; +int contactcount; + +void initCollisions(void){ + int i; + for (i = 0; i < 32; i++){ + //collisionlists[i] = NULL; + collisionlinks[i] = 0; + } +} + +/*void addCollisionObject(Object *object, int group){ + objectlist *node = new objectlist; + node->object = object; + node->next = collisionlists[group]; + collisionlists[group] = node; +}*/ + +void addCollisionLink(int source, int target){ + collisionlinks[source] |= (1<object1 = source; + contact->object2 = target; + vectorCopy(contact->normal, normal); + vectorCopy(contact->position, contactpoint); +} + +#define KINETICFRICTION 0.4 + +bool handleCollision(Contact *contact){ + Object *source = contact->object1; + Object *target = contact->object2; + float *normal = contact->normal; + float *contactpoint = contact->position; + + float sourcevelocity[3], targetvelocity[3]; + float sourcecontactpoint[3], targetcontactpoint[3]; + + vectorSub(sourcecontactpoint, contactpoint, source->position); + source->getVelocity(sourcevelocity, sourcecontactpoint); + + if (target == NULL){ + vectorSet(targetcontactpoint, 0, 0, 0); + vectorSet(targetvelocity, 0, 0, 0); + } else{ + vectorSub(targetcontactpoint, contactpoint, target->position); + target->getVelocity(targetvelocity, targetcontactpoint); + } + + float deltavelocity[3]; + vectorSub(deltavelocity, sourcevelocity, targetvelocity); + float dot = vectorDot(deltavelocity, normal); + + //if (fabs(dot) < EPSILON) return false; + //if (dot > -1.0e-5 && dot < 1.0e-5) return false; + //if (dot >= 0) return false; + if (dot > -1.0e-5) return false; + + + float invmass1; + invmass1 = source->invmass; + + float invmass2; + if (target == NULL) invmass2 = 0; + else invmass2 = target->invmass; + + float t1; + if (source->invmomentofinertia == 0){ + t1 = 0; + } else{ + float v1[3]; + vectorCross(v1, sourcecontactpoint, normal); + vectorScale(v1, source->invmomentofinertia); + float w1[3]; + vectorCross(w1, v1, sourcecontactpoint); + t1 = vectorDot(normal, w1); + } + + float t2; + if (target == NULL || target->invmomentofinertia == 0){ + t2 = 0; + } else{ + float v1[3]; + vectorCross(v1, targetcontactpoint, normal); + vectorScale(v1, target->invmomentofinertia); + float w1[3]; + vectorCross(w1, v1, targetcontactpoint); + t2 = vectorDot(normal, w1); + } + + float denominator = invmass1 + invmass2 + t1 + t2; + + float e = 1.0 - COLLISIONFRICTION; + + float impulsesize = (1 + e) * dot / denominator; + + //printf("%f\n", impulsesize); + + float impulse[3]; + vectorScale(impulse, normal, impulsesize); + + + float friction[3]; + vectorScale(friction, normal, vectorDot(deltavelocity, normal)); + vectorAdd(friction, deltavelocity); + vectorNormalize(friction); + float frictionsize = 10*KINETICFRICTION*dot/denominator; + float maxfrictionsize = 0.1*vectorLength(deltavelocity); + if (frictionsize < -maxfrictionsize) frictionsize = -maxfrictionsize; + vectorScale(friction, -frictionsize); + vectorAdd(impulse, friction); + + + if (target != NULL){ + target->addImpulse(impulse, targetcontactpoint); + target->calculateStateVariables(); + } + + float speed; + float speed2[3]; + + if (target != NULL && source != NULL){ + //float kvel[3]; + //source->getVelocity(kvel); + float k = vectorLength(sourcevelocity)*0.1; + //if (k > 1) k = 1; + speed = -impulsesize*target->invmass*k; + vectorScale(speed2, impulse, target->invmass*k); + /*float kvel[3]; + source->getVelocity(kvel); + float k = 0;//vectorDot(speed2, kvel); + if (k < EPSILON) k = 0; + speed *= k; + vectorScale(speed2, k); + if (k > 0) */target->hitForce(speed, speed2, source); + } + + + vectorScale(impulse, -1); + source->addImpulse(impulse, sourcecontactpoint); + source->calculateStateVariables(); + + //vectorScale(speed, source->invmass); + if (target != NULL && source != NULL){ + //float kvel[3]; + //target->getVelocity(kvel); + float k = vectorLength(targetvelocity)*0.1; + //if (k > 1) k = 1; + speed = -impulsesize*source->invmass*k; + vectorScale(speed2, impulse, source->invmass*k); + /*float kvel[3]; + target->getVelocity(kvel); + float k = 0;//vectorDot(speed2, kvel); + if (k < EPSILON) k = 0; + speed *= k; + vectorScale(speed2, k); + if (k > 0) */source->hitForce(speed, speed2, target); + } + + + return true; +} + + +bool handleLink(ObjectLink *link){ + if (!link->enabled) return false; + + Object *source = link->object1; + Object *target = link->object2; + + float normal[3]; + float contactpoint1[3], contactpoint2[3]; + source->transformPoint(contactpoint1, link->point1); + target->transformPoint(contactpoint2, link->point2); + + float diff[3]; + vectorSub(diff, contactpoint1, contactpoint2); + vectorNormalize(normal, diff); + + float strength = vectorDot(diff, diff); + + if (strength < 1.0e-5) return false; + + float sourcevelocity[3], targetvelocity[3]; + float sourcecontactpoint[3], targetcontactpoint[3]; + + vectorSub(sourcecontactpoint, contactpoint1, source->position); + source->getVelocity(sourcevelocity, sourcecontactpoint); + + vectorSub(targetcontactpoint, contactpoint2, target->position); + target->getVelocity(targetvelocity, targetcontactpoint); + + float deltavelocity[3]; + vectorSub(deltavelocity, sourcevelocity, targetvelocity); + float dot = vectorDot(deltavelocity, normal); + + //if (fabs(dot) < EPSILON) return false; + //if (dot > -1.0e-5 && dot < 1.0e-5) return false; + //if (dot >= 0) return false; + //if (dot > -1.0e-5) return false; + + + float invmass1 = source->invmass; + float invmass2 = target->invmass; + + float t1; + if (source->invmomentofinertia == 0){ + t1 = 0; + } else{ + float v1[3]; + vectorCross(v1, sourcecontactpoint, normal); + vectorScale(v1, source->invmomentofinertia); + float w1[3]; + vectorCross(w1, v1, sourcecontactpoint); + t1 = vectorDot(normal, w1); + } + + float t2; + if (target->invmomentofinertia == 0){ + t2 = 0; + } else{ + float v1[3]; + vectorCross(v1, targetcontactpoint, normal); + vectorScale(v1, target->invmomentofinertia); + float w1[3]; + vectorCross(w1, v1, targetcontactpoint); + t2 = vectorDot(normal, w1); + } + + float denominator = invmass1 + invmass2 + t1 + t2; + + float impulsesize = (dot + strength*100) / denominator; + + //printf("%f\n", impulsesize); + + float impulse[3]; + vectorScale(impulse, normal, impulsesize); + + + target->addImpulse(impulse, targetcontactpoint); + target->calculateStateVariables(); + + vectorScale(impulse, -1); + source->addImpulse(impulse, sourcecontactpoint); + source->calculateStateVariables(); + + + return true; +} + +bool checkCollisions(Object *object, float *contactnormal){ + //bool collision = false; + int group = object->getCollisionGroup(); + int groups = collisionlinks[group]; + group = 0; + int collisions = 0; + /*float oldmomentum[3]; + vectorCopy(oldmomentum, object->momentum); + + while (groups){ + if (groups & 1){ + objectlist *node = collisionlists[group]; + while (node != NULL){ + Object *object2 = node->object; + node = node->next; + if (object != object2){ + if (object2->geometry->checkCollision(object, contactnormal)){ + collisions++; + } + } + } + } + group++; + groups >>= 1; + } + /*float temp[3]; + vectorSub(temp, object->momentum, oldmomentum); + vectorScale(temp, 1.0/DT); + object->addForce(temp);*/ + //vectorSub(object-> + //vectorCopy(object->momentum, oldmomentum); + //printf("%i\n", collisions); + //vectorScale(object->force, 1.0/collisions); + /*if (collisions > 0){ + vectorScale(object->force, 2.0/vectorLength(object->momentum)); + }*/ + return collisions > 0; +} + +/* + * mass = 0 means infinite mass + */ +/*void collide(float *velocity1, float *velocity2, + float mass1, float mass2, + float *normal, float *newimpulse){ + float deltavelocity[3]; + vectorSub(deltavelocity, velocity1, velocity2); + float dot = vectorDot(deltavelocity, normal); + float massinverse1 = 0; + float massinverse2 = 0; + if (mass1 != 0) massinverse1 = 1.0 / mass1; + if (mass2 != 0) massinverse2 = 1.0 / mass2; + float impulsesize = -1 * dot / (massinverse1 + massinverse2); + vectorScale(newimpulse, normal, impulsesize); + if (dot > 0){ + vectorSet(newimpulse, 0, 0, 0); + } +}*/ + +void collide(Object *source, Object *target, float *normal, float *contactpoint){ +/* float momentum[3]; + source->getMomentum(momentum); + + float sourcevelocity[3], targetvelocity[3]; + float sourcecontactpoint[3], targetcontactpoint[3]; + + //source->unTransformPoint(sourcecontactpoint, contactpoint); + //target->unTransformPoint(targetcontactpoint, contactpoint); + vectorSub(sourcecontactpoint, contactpoint, source->position); + vectorSub(targetcontactpoint, contactpoint, target->position); + + source->getVelocity(sourcevelocity);//, sourcecontactpoint); + float sourcemass = source->getMass(); + + target->getVelocity(targetvelocity);//, targetcontactpoint); + float targetmass = target->getMass(); + + float deltavelocity[3]; + vectorSub(deltavelocity, sourcevelocity, targetvelocity); + float dot = vectorDot(deltavelocity, normal); + float massinverse1 = 0; + float massinverse2 = 0; + if (sourcemass != 0) massinverse1 = 1.0 / sourcemass; + if (targetmass != 0) massinverse2 = 1.0 / targetmass; + + float t1; + if (source->invmomentofinertia == 0){ + t1 = 0; + } else{ + float v1[3]; + vectorCross(v1, sourcecontactpoint, normal); + vectorScale(v1, 1.0/source->momentofinertia); + float w1[3]; + vectorCross(w1, v1, sourcecontactpoint); + t1 = vectorDot(normal, w1); + } + //printf("S: %f, %f, %f\n", sourcecontactpoint[0], source->momentofinertia, v1); + + float t2; + if (target->momentofinertia == 0){ + t2 = 0; + } else{ + float v2[3]; + vectorCross(v2, targetcontactpoint, normal); + vectorScale(v2, 1.0/target->momentofinertia); + float w2[3]; + vectorCross(w2, v2, targetcontactpoint); + t2 = vectorDot(normal, w2); + } + //printf("T: %f, %f, %f\n", targetcontactpoint[0], target->momentofinertia, v2); + + + float divisor; + divisor = massinverse1 + massinverse2;// + t1 + t2; + + printf("%f, %f, %f, %f : %f\n", massinverse1, massinverse2, t1, t2, divisor); + + float impulsesize = -dot / divisor; + + float impulse[3]; + vectorScale(impulse, normal, impulsesize); + //collide(sourcevelocity, targetvelocity, sourcemass, targetmass, normal, impulse); + + //vectorAdd(source->momentum, impulse); + + float *force = impulse; + + //vectorScale(force, 2.0/DT); + printf("F: %f, %f, %f\n", impulse[0], impulse[1], impulse[2]); + + //float cp[3]; + //vectorSub(cp, contactpoint, source->position); + //source->addForce(force, sourcecontactpoint);*/ +} + + + +bool checkSphereMeshCollision(float *sphereposition, float r, Mesh *mesh, float *normal, float *contactpoint){ + float linenormal[3]; + float pointnormal[3]; + float maxdist = 0; + bool planecollision = false; + bool linecollision = false; + bool pointcollision = false; + + int i, j; + + for (i = 0; i < mesh->polygoncount; i++){ + class Polygon *polygon = &mesh->polygons[i]; + + float dist = distanceFromPlane(sphereposition, polygon->planenormal, polygon->planedistance); + if (dist < r && dist > -r){ + bool directcollision = true; + for (j = 0; j < polygon->vertexcount; j++){ + float *p1 = polygon->vertices[j]->position; + float *p2 = polygon->vertices[(j+1)%polygon->vertexcount]->position; + float *p3 = polygon->vertices[(j+2)%polygon->vertexcount]->position; + float v1[3], v2[3]; + vectorSub(v1, p2, p1); + + //Collision for polygon surface + vectorSub(v2, p3, p2); + float t1[3]; + vectorProject(t1, v2, v1); + float norm[3]; + vectorSub(norm, v2, t1); + vectorNormalize(norm); + + //Collision for polygon edges + float newpoint[3]; + vectorSub(newpoint, sphereposition, p1); + float dist2 = vectorDot(newpoint, norm); + if (dist2 < 0){ + directcollision = false; + float projloc = vectorDot(newpoint, v1) / vectorDot(v1, v1); + if (projloc >= 0 && projloc <= 1){ + float proj[3]; + vectorScale(proj, v1, projloc); + float projorth[3]; + vectorSub(projorth, newpoint, proj); + float l2 = vectorDot(projorth, projorth); + if (l2 < r*r){ + vectorNormalize(linenormal, projorth); + if (dist < 0) vectorScale(linenormal, -1); + linecollision = true; + } + } + } + + //Collision for polygon vertices + float pointdiff[3]; + vectorSub(pointdiff, sphereposition, p1); + float l3 = vectorDot(pointdiff, pointdiff); + if (l3 < r*r){ + vectorScale(pointnormal, pointdiff, 1.0 / sqrt(l3)); + if (dist < 0) vectorScale(pointnormal, -1); + pointcollision = true; + } + } + if (directcollision){ + if (dist > maxdist || !planecollision){ + vectorCopy(normal, polygon->planenormal); + maxdist = dist; + planecollision = true; + } + } + } + } + + if (planecollision){ + vectorScale(contactpoint, normal, -r); + vectorAdd(contactpoint, sphereposition); + } else if (linecollision){ + vectorScale(contactpoint, linenormal, -r); + vectorAdd(contactpoint, sphereposition); + vectorCopy(normal, linenormal); + } else if (pointcollision){ + vectorScale(contactpoint, pointnormal, -r); + vectorAdd(contactpoint, sphereposition); + vectorCopy(normal, pointnormal); + } else{ + return false; + } + + return true; +} + + + + + +bool checkPointMeshCollision(float *position, Mesh *mesh, float *normal, float *contactpoint){ + float maxdist = 0; + bool planecollision = false; + + int i; + + for (i = 0; i < mesh->polygoncount; i++){ + class Polygon *polygon = &mesh->polygons[i]; + + float dist = distanceFromPlane(position, polygon->planenormal, polygon->planedistance); + if (dist < 0){ + bool directcollision = true; + /*for (j = 0; j < polygon->vertexcount; j++){ + float *p1 = polygon->vertices[j]->position; + float *p2 = polygon->vertices[(j+1)%polygon->vertexcount]->position; + float *p3 = polygon->vertices[(j+2)%polygon->vertexcount]->position; + float v1[3], v2[3]; + vectorSub(v1, p2, p1); + + //Collision for polygon surface + vectorSub(v2, p3, p2); + float t1[3]; + vectorProject(t1, v2, v1); + float norm[3]; + vectorSub(norm, v2, t1); + vectorNormalize(norm); + + //Collision for polygon edges + float newpoint[3]; + vectorSub(newpoint, position, p1); + float dist2 = vectorDot(newpoint, norm); + if (dist2 < 0) directcollision = false; + }*/ + if (directcollision){ + if (dist > maxdist || !planecollision){ + vectorCopy(normal, polygon->planenormal); + maxdist = dist; + planecollision = true; + } + } + } else{ + return false; + } + } + + if (planecollision){ + vectorCopy(contactpoint, position); + } else{ + return false; + } + + return true; +} + +#define MAXPOLYGONS 1000 + +struct tracehit{ + float t; + Polygon *polygon; +}; + +bool tracePlane(tracehit *result, float *origin, float *ray, class Polygon *polygon){ + float *normal = polygon->planenormal; + float D = polygon->planedistance; + float denominator = vectorDot(normal, ray); + if (denominator == 0){ + if (vectorDot(normal, origin) > 0) result->t = 1000000; + else result->t = -1000000; + result->polygon = polygon; + return true; + } + + float t = - (vectorDot(normal, origin) + D) / denominator; + + result->t = t; + result->polygon = polygon; + + //if (t < 0 || t > 1) return false; + + return true; +} + +Edge *findSharingEdge(class Polygon *p1, class Polygon *p2){ + //printf("Edges:\n"); + int i, j; + for (i = 0; i < p1->vertexcount; i++){ + //printf("%p\n", p1->edges[i]); + for (j = 0; j < p2->vertexcount; j++){ + if (p1->edges[i] == p2->edges[j]) return p1->edges[i]; + } + } + return NULL; +} + +/*Polygon *findSharingPolygon(Mesh *mesh, class Polygon *p1, class Polygon *p2){ + //printf("Edges:\n"); + int i, j; + for (i = 0; i < p1->vertexcount; i++){ + //printf("%p\n", p1->edges[i]); + for (j = 0; j < p2->vertexcount; j++){ + if (p1->edges[i] == p2->edges[j]) return p1->edges[i]; + } + } + return NULL; +}*/ +Polygon *findNearestPolygon(class Polygon *polygon, float *point){ + int i; + float mindist = 0; + Polygon *nearestpolygon = NULL; + for (i = 0; i < polygon->edgecount; i++){ + Edge *edge = polygon->edges[i]; + Polygon *polygon2 = edge->p1; + if (polygon2 == polygon) polygon2 = edge->p2; + float newdist = distanceFromPlane(point, polygon2->planenormal, polygon2->planedistance); + if (newdist > 0) return NULL; + if (mindist == 0 || newdist > mindist){ + mindist = newdist; + nearestpolygon = polygon2; + } + } + return nearestpolygon; +} + +bool checkEdgeMeshCollision(float *p1, float *p2, Mesh *mesh, float *normal, float *contactpoint){ + float ray[3]; + vectorSub(ray, p2, p1); + + float maxdist = 0; + bool collision = false; + + int i, j; + + tracehit hits[MAXPOLYGONS]; + int hitcount = 0; + + for (i = 0; i < mesh->polygoncount; i++){ + class Polygon *polygon = &mesh->polygons[i]; + + if (tracePlane(&hits[hitcount], p1, ray, polygon)){ + hitcount++; + } + } + + if (hitcount < 2) return false; + + for (i = 1; i < hitcount; i++){ + for (j = i; j > 0; j--){ + if (hits[j].t < hits[j-1].t){ + float tempt = hits[j].t; + hits[j].t = hits[j-1].t; + hits[j-1].t = tempt; + class Polygon *tempp = hits[j].polygon; + hits[j].polygon = hits[j-1].polygon; + hits[j-1].polygon = tempp; + } else break; + } + } + + int negative = -1, positive = -1; + + + for (i = 0; i < hitcount; i++){ + float t = hits[i].t; + class Polygon *polygon = hits[i].polygon; + + float dot = vectorDot(ray, polygon->planenormal); + + if (dot > 0 && positive == -1) positive = i; + if (dot < 0) negative = i; + + if (dot < 0 && positive != -1) return false; + } + + if (negative == -1 || positive == -1) return false; + + /*for (i = 0; i < hitcount; i++){ + float t = hits[i].t; + class Polygon *polygon = hits[i].polygon; + + float dot = vectorDot(ray, polygon->planenormal); + + printf("%f ", dot); + } + printf("\n");*/ + + if (hits[negative].t < 0 || hits[positive].t > 1) return false; + + Edge *edge2 = findSharingEdge(hits[negative].polygon, hits[positive].polygon); + + //fflush(stdout); + float cp1[3], cp2[3]; + vectorScale(cp1, ray, hits[negative].t); + vectorAdd(cp1, p1); + vectorScale(cp2, ray, hits[positive].t); + vectorAdd(cp2, p1); + + if (edge2 != NULL){ + + /*float ev1[3]; + vectorSub(ev1, edge2->v2->position, edge2->v1->position); + vectorCross(normal, ev1, ray); + vectorScale(normal, vectorDot(normal, hits[positive].polygon->planenormal)); + vectorNormalize(normal); + + float at = (hits[negative].t + hits[positive].t) / 2; + vectorScale(contactpoint, ray, at); + vectorAdd(contactpoint, p1);*/ + + float dot1 = fabs(vectorDot(ray, hits[negative].polygon->planenormal)); + float dot2 = fabs(vectorDot(ray, hits[positive].polygon->planenormal)); + + if (dot1 > dot2){ + //vectorScale(contactpoint, ray, hits[negative].t); + //vectorAdd(contactpoint, p1); + vectorCopy(contactpoint, cp1); + vectorCopy(normal, hits[positive].polygon->planenormal); + } else{ + //vectorScale(contactpoint, ray, hits[positive].t); + //vectorAdd(contactpoint, p1); + vectorCopy(contactpoint, cp2); + vectorCopy(normal, hits[negative].polygon->planenormal); + } + } else{ + Polygon *polygon = findNearestPolygon(hits[negative].polygon, cp1); + if (polygon != NULL){ + /*vectorCopy(contactpoint, cp1); + vectorAdd(contactpoint, cp2); + vectorScale(contactpoint, 0.5);*/ + float at = (hits[negative].t + hits[positive].t) / 2; + vectorScale(contactpoint, ray, at); + vectorAdd(contactpoint, p1); + + vectorCopy(normal, polygon->planenormal); + } else{ + return false; + } + } + + + //shotsound->play(); + return true; +} diff --git a/src/collision.h b/src/collision.h index 4a82fa5..44a66e4 100644 --- a/src/collision.h +++ b/src/collision.h @@ -1,47 +1,47 @@ -#ifndef __COLLISION_H_INCLUDED__ -#define __COLLISION_H_INCLUDED__ - -#include "mesh.h" - -class ObjectLink; - -#define COLLISIONGROUP_NONE 0 -#define COLLISIONGROUP_ARENA 1 -#define COLLISIONGROUP_MAN1 2 -#define COLLISIONGROUP_MAN1HAND 3 -#define COLLISIONGROUP_MAN2 4 -#define COLLISIONGROUP_MAN2HAND 5 -#define COLLISIONGROUP_PARTICLE 6 - -#define COLLISIONFRICTION 0.9 - -void initCollisions(void); -//void addCollisionObject(Object *object, int group); -void addCollisionLink(int source, int target); -void removeCollisionLink(int source, int target); -bool isCollisionLink(int source, int target); - -class Contact{ -public: - Object *object1, *object2; - float normal[3]; - float position[3]; -}; - -extern Contact *contacts; -extern int contactcount; - - -//Contact point is world-relative and must be transformed -//into coordinate system of both objects -void addCollision(Object *source, Object *target, - float *normal, float *contactpoint); -bool handleCollision(Contact *contact); -bool handleLink(ObjectLink *link); - -bool checkSphereMeshCollision(float *sphereposition, float r, Mesh *mesh, float *normal, float *contactpoint); -bool checkPointMeshCollision(float *position, Mesh *mesh, float *normal, float *contactpoint); -bool checkEdgeMeshCollision(float *p1, float *p2, Mesh *mesh, float *normal, float *contactpoint); - -#endif - +#ifndef __COLLISION_H_INCLUDED__ +#define __COLLISION_H_INCLUDED__ + +#include "mesh.h" + +class ObjectLink; + +#define COLLISIONGROUP_NONE 0 +#define COLLISIONGROUP_ARENA 1 +#define COLLISIONGROUP_MAN1 2 +#define COLLISIONGROUP_MAN1HAND 3 +#define COLLISIONGROUP_MAN2 4 +#define COLLISIONGROUP_MAN2HAND 5 +#define COLLISIONGROUP_PARTICLE 6 + +#define COLLISIONFRICTION 0.9 + +void initCollisions(void); +//void addCollisionObject(Object *object, int group); +void addCollisionLink(int source, int target); +void removeCollisionLink(int source, int target); +bool isCollisionLink(int source, int target); + +class Contact{ +public: + Object *object1, *object2; + float normal[3]; + float position[3]; +}; + +extern Contact *contacts; +extern int contactcount; + + +//Contact point is world-relative and must be transformed +//into coordinate system of both objects +void addCollision(Object *source, Object *target, + float *normal, float *contactpoint); +bool handleCollision(Contact *contact); +bool handleLink(ObjectLink *link); + +bool checkSphereMeshCollision(float *sphereposition, float r, Mesh *mesh, float *normal, float *contactpoint); +bool checkPointMeshCollision(float *position, Mesh *mesh, float *normal, float *contactpoint); +bool checkEdgeMeshCollision(float *p1, float *p2, Mesh *mesh, float *normal, float *contactpoint); + +#endif + diff --git a/src/end.cpp b/src/end.cpp index e1ef863..1f4d612 100644 --- a/src/end.cpp +++ b/src/end.cpp @@ -1,144 +1,144 @@ -#include "main.h" - -#include - -#include "legoblocks.h" -#include "camera.h" -#include "light.h" -#include "audio.h" -#include "object.h" -#include "appearance.h" -#include "sphere.h" -#include "vector.h" -#include "collision.h" -#include "utils.h" -#include "graphics.h" -#include "objectfactory.h" -#include "world.h" -#include "3dutils.h" -#include "legoman.h" -#include "font.h" -#include "run.h" -#include "menu.h" -#include "fight.h" - -#include "glapi.h" - -Camera endcamera; -Light endlight, endlight2; - -//BasicBlockAppearance *endfloor = new BasicBlockAppearance(100, 1, 100); -BasicBlock *endfloor;// = new BasicBlock(20, 1, 15); - -void initEnd(void){ - endlight.setColor(1, 1, 1); - endlight.setSpecular(1, 1, 1); - endlight.setPosition(-0.5, BLOCKHEIGHT*16, 0.5); - endlight.setAttenuation(0, 0.0, 0.005); - - endlight2.setColor(1, 1, 1); - endlight2.setSpecular(1, 1, 1); - endlight2.setAttenuation(1.0, 0.0, 0.0); - - endfloor = new BasicBlock(30, 1, 20); - //endfloor->material.setColor(0, 1, 0, 1); - endfloor->setColor(0, 1, 0); - endfloor->setPosition(-10, -BLOCKHEIGHT*0.5, 0); - endfloor->prepare(); -} - -int endingcounter; - -void endRestart(void){ - endingcounter = 0; - //initEnd(); - //endfloor->prepare(); -} - -void stopEnding(void){ - endlight.setEnabled(false); - changeGameMode(MENUMODE); - fightmusic->fadeOut(300); - menuRestart(); -} - -float endfade; - -void calculateEnd(int framecount){ - endfade = -1; - - if (endingcounter < 200){ - endfade = 1-(float)endingcounter/200; - } - endingcounter++; - - endlight.setEnabled(true); - //endlight2.setEnabled(true); - - float target[3] = {0, 13, 0}; - endcamera.setTarget(target); - endcamera.setPosition(10+sin(framecount*0.002)*2, 20+sin(framecount*0.0017)*2, 25+cos(framecount*0.002)*2); - //endcamera.setPosition(sin(framecount*0.01)*25, sin(framecount*0.007)*6+20, cos(framecount*0.01)*25); - - //endlight.setPosition(40, 20, 0); - endlight.setPosition(-sin(framecount*0.007)*10, 15, cos(framecount*0.007)*2+22); - - if (keys[SDLK_ESCAPE]){ - stopEnding(); - } -} - -void drawEnd(int framecount){ - glLoadIdentity(); - glTranslatef(10, 0, 0); - - endcamera.glUpdate(); - - updateLights(); - - glEnable(GL_LIGHTING); - glDisable(GL_BLEND); - glEnable(GL_CULL_FACE); - glDisable(GL_TEXTURE_2D); - - endfloor->draw(); - - glColor3f(1, 1, 0); - - drawTrophy(); - - glRotatef(270, 0, 1, 0); - glTranslatef(2-BLOCKHEIGHT*0.5, 0, 15-BLOCKHEIGHT*0.5); - glScalef(3, 3, 3); - - winner->head->draw(); - winner->torso->draw(); - winner->lefthand->draw(); - winner->righthand->draw(); - winner->waist->draw(); - winner->leftleg->draw(); - winner->rightleg->draw(); - - - enable2D(); - - glColor3f(1, 1, 1); - - if (winner->side == PLAYER1) print(0.05, 0.05, "Player 1 is\nthe winner", 0.09); - if (winner->side == PLAYER2) print(0.05, 0.05, "Player 2 is\nthe winner", 0.09); - - - if (endfade != -1){ - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glColor4f(0, 0, 0, endfade); - glBegin(GL_QUADS); - glVertex2f(0, 0); - glVertex2f(1, 0); - glVertex2f(1, 1); - glVertex2f(0, 1); - glEnd(); - } - - disable2D(); -} +#include "main.h" + +#include + +#include "legoblocks.h" +#include "camera.h" +#include "light.h" +#include "audio.h" +#include "object.h" +#include "appearance.h" +#include "sphere.h" +#include "vector.h" +#include "collision.h" +#include "utils.h" +#include "graphics.h" +#include "objectfactory.h" +#include "world.h" +#include "3dutils.h" +#include "legoman.h" +#include "font.h" +#include "run.h" +#include "menu.h" +#include "fight.h" + +#include "glapi.h" + +Camera endcamera; +Light endlight, endlight2; + +//BasicBlockAppearance *endfloor = new BasicBlockAppearance(100, 1, 100); +BasicBlock *endfloor;// = new BasicBlock(20, 1, 15); + +void initEnd(void){ + endlight.setColor(1, 1, 1); + endlight.setSpecular(1, 1, 1); + endlight.setPosition(-0.5, BLOCKHEIGHT*16, 0.5); + endlight.setAttenuation(0, 0.0, 0.005); + + endlight2.setColor(1, 1, 1); + endlight2.setSpecular(1, 1, 1); + endlight2.setAttenuation(1.0, 0.0, 0.0); + + endfloor = new BasicBlock(30, 1, 20); + //endfloor->material.setColor(0, 1, 0, 1); + endfloor->setColor(0, 1, 0); + endfloor->setPosition(-10, -BLOCKHEIGHT*0.5, 0); + endfloor->prepare(); +} + +int endingcounter; + +void endRestart(void){ + endingcounter = 0; + //initEnd(); + //endfloor->prepare(); +} + +void stopEnding(void){ + endlight.setEnabled(false); + changeGameMode(MENUMODE); + fightmusic->fadeOut(300); + menuRestart(); +} + +float endfade; + +void calculateEnd(int framecount){ + endfade = -1; + + if (endingcounter < 200){ + endfade = 1-(float)endingcounter/200; + } + endingcounter++; + + endlight.setEnabled(true); + //endlight2.setEnabled(true); + + float target[3] = {0, 13, 0}; + endcamera.setTarget(target); + endcamera.setPosition(10+sin(framecount*0.002)*2, 20+sin(framecount*0.0017)*2, 25+cos(framecount*0.002)*2); + //endcamera.setPosition(sin(framecount*0.01)*25, sin(framecount*0.007)*6+20, cos(framecount*0.01)*25); + + //endlight.setPosition(40, 20, 0); + endlight.setPosition(-sin(framecount*0.007)*10, 15, cos(framecount*0.007)*2+22); + + if (keys[SDLK_ESCAPE]){ + stopEnding(); + } +} + +void drawEnd(int framecount){ + glLoadIdentity(); + glTranslatef(10, 0, 0); + + endcamera.glUpdate(); + + updateLights(); + + glEnable(GL_LIGHTING); + glDisable(GL_BLEND); + glEnable(GL_CULL_FACE); + glDisable(GL_TEXTURE_2D); + + endfloor->draw(); + + glColor3f(1, 1, 0); + + drawTrophy(); + + glRotatef(270, 0, 1, 0); + glTranslatef(2-BLOCKHEIGHT*0.5, 0, 15-BLOCKHEIGHT*0.5); + glScalef(3, 3, 3); + + winner->head->draw(); + winner->torso->draw(); + winner->lefthand->draw(); + winner->righthand->draw(); + winner->waist->draw(); + winner->leftleg->draw(); + winner->rightleg->draw(); + + + enable2D(); + + glColor3f(1, 1, 1); + + if (winner->side == PLAYER1) print(0.05, 0.05, "Player 1 is\nthe winner", 0.09); + if (winner->side == PLAYER2) print(0.05, 0.05, "Player 2 is\nthe winner", 0.09); + + + if (endfade != -1){ + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glColor4f(0, 0, 0, endfade); + glBegin(GL_QUADS); + glVertex2f(0, 0); + glVertex2f(1, 0); + glVertex2f(1, 1); + glVertex2f(0, 1); + glEnd(); + } + + disable2D(); +} diff --git a/src/end.h b/src/end.h index d629e5b..0d07fc6 100644 --- a/src/end.h +++ b/src/end.h @@ -1,16 +1,16 @@ -#ifndef __END_H_INCLUDED__ -#define __END_H_INCLUDED__ - -#include - -#include "texture.h" -#include "audio.h" - - -void initEnd(void); -void endRestart(void); -void calculateEnd(int framecount); -void drawEnd(int framecount); - -#endif - +#ifndef __END_H_INCLUDED__ +#define __END_H_INCLUDED__ + +#include + +#include "texture.h" +#include "audio.h" + + +void initEnd(void); +void endRestart(void); +void calculateEnd(int framecount); +void drawEnd(int framecount); + +#endif + diff --git a/src/fight.cpp b/src/fight.cpp index 6ef13f0..5b39bc9 100644 --- a/src/fight.cpp +++ b/src/fight.cpp @@ -1,597 +1,597 @@ -#include "main.h" - -#include - -#include "legoblocks.h" -#include "camera.h" -#include "light.h" -#include "audio.h" -#include "object.h" -#include "appearance.h" -#include "sphere.h" -#include "vector.h" -#include "collision.h" -#include "utils.h" -#include "graphics.h" -#include "objectfactory.h" -#include "world.h" -#include "3dutils.h" -#include "legoman.h" -#include "particle.h" -#include "font.h" -#include "fight.h" -#include "menu.h" -#include "end.h" -#include "run.h" - -#include "glapi.h" - -Camera camera; -Light light1, light2, light3, light4; -World *arenaworld; - -Sound *fightmusic; -Sound *hitsound1, *hitsound2, *hitsound3, *hitsound4; -Sound *softhitsound1, *softhitsound2; -Sound *jumpsound; -Sound *fallsound1, *fallsound2; -Sound *fightsound; -Sound *victorysound; - -Legoman *man1, *man2; -int points1, points2; - -#define ARENASIZE 10 -#define ARENAHEIGHT 10 - -bool fightinitialized = false; - -void initFight(void){ - if (!fightinitialized){ - initCollisions(); - addCollisionLink(COLLISIONGROUP_ARENA, COLLISIONGROUP_PARTICLE); - //addCollisionLink(COLLISIONGROUP_PARTICLE, COLLISIONGROUP_PARTICLE); - - addCollisionLink(COLLISIONGROUP_MAN1, COLLISIONGROUP_ARENA); - //addCollisionLink(COLLISIONGROUP_MAN1, COLLISIONGROUP_PARTICLE); - addCollisionLink(COLLISIONGROUP_MAN1, COLLISIONGROUP_MAN1); - addCollisionLink(COLLISIONGROUP_MAN1HAND, COLLISIONGROUP_ARENA); - //addCollisionLink(COLLISIONGROUP_MAN1HAND, COLLISIONGROUP_PARTICLE); - - addCollisionLink(COLLISIONGROUP_MAN2, COLLISIONGROUP_ARENA); - //addCollisionLink(COLLISIONGROUP_MAN2, COLLISIONGROUP_PARTICLE); - addCollisionLink(COLLISIONGROUP_MAN2, COLLISIONGROUP_MAN2); - addCollisionLink(COLLISIONGROUP_MAN2HAND, COLLISIONGROUP_ARENA); - //addCollisionLink(COLLISIONGROUP_MAN2HAND, COLLISIONGROUP_PARTICLE); - - addCollisionLink(COLLISIONGROUP_MAN1, COLLISIONGROUP_MAN2); - addCollisionLink(COLLISIONGROUP_MAN1, COLLISIONGROUP_MAN2HAND); - addCollisionLink(COLLISIONGROUP_MAN1HAND, COLLISIONGROUP_MAN2); - addCollisionLink(COLLISIONGROUP_MAN1HAND, COLLISIONGROUP_MAN2HAND); - - //Sound* backgroundsong = new Sound("mixdown.mp3"); - Sound* backgroundsong = new Sound(BGSONG, true); - camera.setPosition(-5, 8, 18); - - arenaworld = new World(); - - - //arenalight.setEnabled(true); - /*arenalight.setPosition(0, 10, 0); - Object *lamp = new Object(); - lamp->appearance = new LampAppearance(); - lamp->setPosition(0, 10, 0); - arenaworld->addChild(lamp);*/ - - } - - light1.setColor(1, 1, 1); - light1.setSpecular(1, 1, 1); - light1.setPosition(-ARENASIZE+0.5, 5, -ARENASIZE+0.5); - light1.setAttenuation(0.2, 0.0, 0.02); - - light2.setColor(1, 1, 1); - light2.setSpecular(1, 1, 1); - light2.setPosition(ARENASIZE-0.5, 5, -ARENASIZE+0.5); - light2.setAttenuation(0.2, 0.0, 0.02); - - light3.setColor(1, 1, 1); - light3.setSpecular(1, 1, 1); - light3.setPosition(-ARENASIZE+0.5, 5, ARENASIZE-0.5); - light3.setAttenuation(0.2, 0.0, 0.02); - - light4.setColor(1, 1, 1); - light4.setSpecular(1, 1, 1); - light4.setPosition(ARENASIZE-0.5, 5, ARENASIZE-0.5); - light4.setAttenuation(0.2, 0.0, 0.02); - - - if (!fightinitialized){ - Object *lamp; - - lamp = new Object(); - lamp->appearance = new LampAppearance(); - lamp->setPosition(-ARENASIZE+0.5, (ARENAHEIGHT+0.5)*BLOCKHEIGHT, -ARENASIZE+0.5); - arenaworld->addChild(lamp); - - lamp = new Object(); - lamp->appearance = new LampAppearance(); - lamp->setPosition(ARENASIZE-0.5, (ARENAHEIGHT+0.5)*BLOCKHEIGHT, -ARENASIZE+0.5); - arenaworld->addChild(lamp); - - lamp = new Object(); - lamp->appearance = new LampAppearance(); - lamp->setPosition(-ARENASIZE+0.5, (ARENAHEIGHT+0.5)*BLOCKHEIGHT, ARENASIZE-0.5); - arenaworld->addChild(lamp); - - lamp = new Object(); - lamp->appearance = new LampAppearance(); - lamp->setPosition(ARENASIZE-0.5, (ARENAHEIGHT+0.5)*BLOCKHEIGHT, ARENASIZE-0.5); - arenaworld->addChild(lamp); - - - //Floor - BasicBlock *floorblock; - floorblock = new BasicBlock(ARENASIZE*2, 3, ARENASIZE*2); - floorblock->setPosition(0, -BLOCKHEIGHT*3/2.0, 0); - floorblock->setColor(0, 1, 0); - floorblock->setCollisionGroup(COLLISIONGROUP_ARENA); - arenaworld->addChild(floorblock); - - - //Corners - BasicBlock *arenacorner; - - arenacorner = new BasicBlock(1, ARENAHEIGHT, 1); - arenacorner->setColor(1, 0, 0); - //arenacorner->setCollisionGroup(COLLISIONGROUP_ARENA); - arenacorner->setPosition(ARENASIZE-0.5, BLOCKHEIGHT*ARENAHEIGHT/2.0, ARENASIZE-0.5); - arenaworld->addChild(arenacorner); - - arenacorner = new BasicBlock(1, ARENAHEIGHT, 1); - arenacorner->setColor(1, 0, 0); - //arenacorner->setCollisionGroup(COLLISIONGROUP_ARENA); - arenacorner->setPosition(-ARENASIZE+0.5, BLOCKHEIGHT*ARENAHEIGHT/2.0, ARENASIZE-0.5); - arenaworld->addChild(arenacorner); - - arenacorner = new BasicBlock(1, ARENAHEIGHT, 1); - arenacorner->setColor(1, 0, 0); - //arenacorner->setCollisionGroup(COLLISIONGROUP_ARENA); - arenacorner->setPosition(ARENASIZE-0.5, BLOCKHEIGHT*ARENAHEIGHT/2.0, -ARENASIZE+0.5); - arenaworld->addChild(arenacorner); - - arenacorner = new BasicBlock(1, ARENAHEIGHT, 1); - arenacorner->setColor(1, 0, 0); - //arenacorner->setCollisionGroup(COLLISIONGROUP_ARENA); - arenacorner->setPosition(-ARENASIZE+0.5, BLOCKHEIGHT*ARENAHEIGHT/2.0, -ARENASIZE+0.5); - arenaworld->addChild(arenacorner); - - - //"Ropes" - MeshObject *arenaline; - Mesh *linegeometry; - MultiAppearance *lineappearance; - BasicBlockAppearance *line; - int geometryheight = BLOCKHEIGHT*ARENAHEIGHT; - - linegeometry = createBox(-0.5, 0.5, -geometryheight/2, geometryheight/2-BLOCKHEIGHT, -ARENASIZE, ARENASIZE); - arenaline = new MeshObject(linegeometry); - lineappearance = new MultiAppearance(); - line = new BasicBlockAppearance(1, 1, ARENASIZE*2); - vectorSet(line->displacement, 0, -BLOCKHEIGHT*2.5, 0); - line->material.setColor(1, 0, 0, 1); - lineappearance->addAppearance(line), - line = new BasicBlockAppearance(1, 1, ARENASIZE*2); - vectorSet(line->displacement, 0, BLOCKHEIGHT*0.5, 0); - line->material.setColor(1, 0, 0, 1); - lineappearance->addAppearance(line), - line = new BasicBlockAppearance(1, 1, ARENASIZE*2); - vectorSet(line->displacement, 0, BLOCKHEIGHT*3.5, 0); - line->material.setColor(1, 0, 0, 1); - lineappearance->addAppearance(line), - arenaline->appearance = lineappearance; - arenaline->setCollisionGroup(COLLISIONGROUP_ARENA); - arenaline->setPosition(-ARENASIZE+0.5, geometryheight/2, 0); - arenaworld->addChild(arenaline); - - linegeometry = createBox(-0.5, 0.5, -geometryheight/2, geometryheight/2-BLOCKHEIGHT, -ARENASIZE, ARENASIZE); - arenaline = new MeshObject(linegeometry); - lineappearance = new MultiAppearance(); - line = new BasicBlockAppearance(1, 1, ARENASIZE*2); - vectorSet(line->displacement, 0, -BLOCKHEIGHT*2.5, 0); - line->material.setColor(1, 0, 0, 1); - lineappearance->addAppearance(line), - line = new BasicBlockAppearance(1, 1, ARENASIZE*2); - vectorSet(line->displacement, 0, BLOCKHEIGHT*0.5, 0); - line->material.setColor(1, 0, 0, 1); - lineappearance->addAppearance(line), - line = new BasicBlockAppearance(1, 1, ARENASIZE*2); - vectorSet(line->displacement, 0, BLOCKHEIGHT*3.5, 0); - line->material.setColor(1, 0, 0, 1); - lineappearance->addAppearance(line), - arenaline->appearance = lineappearance; - arenaline->setCollisionGroup(COLLISIONGROUP_ARENA); - arenaline->setPosition(ARENASIZE-0.5, geometryheight/2, 0); - arenaworld->addChild(arenaline); - - linegeometry = createBox(-ARENASIZE, ARENASIZE, -geometryheight/2, geometryheight/2-BLOCKHEIGHT, -0.5, 0.5); - arenaline = new MeshObject(linegeometry); - lineappearance = new MultiAppearance(); - line = new BasicBlockAppearance(ARENASIZE*2, 1, 1); - vectorSet(line->displacement, 0, -BLOCKHEIGHT*2.5, 0); - line->material.setColor(1, 0, 0, 1); - lineappearance->addAppearance(line), - line = new BasicBlockAppearance(ARENASIZE*2, 1, 1); - vectorSet(line->displacement, 0, BLOCKHEIGHT*0.5, 0); - line->material.setColor(1, 0, 0, 1); - lineappearance->addAppearance(line), - line = new BasicBlockAppearance(ARENASIZE*2, 1, 1); - vectorSet(line->displacement, 0, BLOCKHEIGHT*3.5, 0); - line->material.setColor(1, 0, 0, 1); - lineappearance->addAppearance(line), - arenaline->appearance = lineappearance; - arenaline->setCollisionGroup(COLLISIONGROUP_ARENA); - arenaline->setPosition(0, geometryheight/2, -ARENASIZE+0.5); - arenaworld->addChild(arenaline); - - linegeometry = createBox(-ARENASIZE, ARENASIZE, -geometryheight/2, geometryheight/2-BLOCKHEIGHT, -0.5, 0.5); - arenaline = new MeshObject(linegeometry); - lineappearance = new MultiAppearance(); - line = new BasicBlockAppearance(ARENASIZE*2, 1, 1); - vectorSet(line->displacement, 0, -BLOCKHEIGHT*2.5, 0); - line->material.setColor(1, 0, 0, 1); - lineappearance->addAppearance(line), - line = new BasicBlockAppearance(ARENASIZE*2, 1, 1); - vectorSet(line->displacement, 0, BLOCKHEIGHT*0.5, 0); - line->material.setColor(1, 0, 0, 1); - lineappearance->addAppearance(line), - line = new BasicBlockAppearance(ARENASIZE*2, 1, 1); - vectorSet(line->displacement, 0, BLOCKHEIGHT*3.5, 0); - line->material.setColor(1, 0, 0, 1); - lineappearance->addAppearance(line), - arenaline->appearance = lineappearance; - arenaline->setCollisionGroup(COLLISIONGROUP_ARENA); - arenaline->setPosition(0, geometryheight/2, ARENASIZE-0.5); - arenaworld->addChild(arenaline); - - float movement[3]; - - man1 = new Legoman(PLAYER1); - man1->insertToWorld(arenaworld); - vectorSet(movement, -4, 0, 0); - man1->move(movement); - man1->lockPart(LEFTLEG | RIGHTLEG); - - man2 = new Legoman(PLAYER2); - man2->insertToWorld(arenaworld); - vectorSet(movement, 4, 0, 0); - man2->move(movement); - man2->lockPart(LEFTLEG | RIGHTLEG); - - man1->addOpponent(man2); - man2->addOpponent(man1); - - - initBloods(arenaworld); - - - hitsound1 = new Sound(DATAPATH"hit1.wav"); - softhitsound1 = new Sound(DATAPATH"hitsoft1.wav"); - softhitsound2 = new Sound(DATAPATH"hitsoft2.wav"); - jumpsound = new Sound(DATAPATH"jump.wav"); - fallsound1 = new Sound(DATAPATH"fall1.wav"); - fallsound2 = new Sound(DATAPATH"fall2.wav"); - fightsound = new Sound(DATAPATH"fight.wav"); - victorysound = new Sound(DATAPATH"victory.wav"); - - fightmusic = new Sound(DATAPATH"fight.mp3", true); - } - - float cameraTarget[3] = {0, 6, 0}; - camera.setTarget(cameraTarget); - arenaworld->prepare(); - - points1 = 0; - points2 = 0; - - winner = man1; -} - -#define MAXSCORE 3 - -int trophycounter = -1; - -void resetFight(void){ - float movement[3]; - man1->heal(); - man2->heal(); - - vectorSet(movement, -4, 0, 0); - man1->move(movement); - vectorSet(movement, 4, 0, 0); - man2->move(movement); - - man1->lockPart(LEFTLEG | RIGHTLEG); - man2->lockPart(LEFTLEG | RIGHTLEG); -} - -int startcounter, endcounter; - -float fightfade; - -bool dead; - -Legoman *winner; - -void gameOver(Legoman *loser){ - endcounter = 0; - dead = true; - winner = loser->getOpponent(); -} - -void startFight(void){ - resetFight(); - fightmusic->setVolume(0); - fightmusic->play(); - fightmusic->fadeIn(300); - startcounter = 0; - trophycounter = -1; - fightfade = 1; - dead = false; - points1 = 0; - points2 = 0; -} - -SDLKey player1left = SDLK_LEFT; -SDLKey player1right = SDLK_RIGHT; -SDLKey player1forward = SDLK_UP; -SDLKey player1backward = SDLK_DOWN; -SDLKey player1jump = SDLK_RSHIFT; -SDLKey player1hit = SDLK_RCTRL; - -SDLKey player2left = SDLK_a; -SDLKey player2right = SDLK_d; -SDLKey player2forward = SDLK_w; -SDLKey player2backward = SDLK_s; -SDLKey player2jump = SDLK_LSHIFT; -SDLKey player2hit = SDLK_LCTRL; - - -void stopGame(void){ - light1.setEnabled(false); - light2.setEnabled(false); - light3.setEnabled(false); - light4.setEnabled(false); - changeGameMode(MENUMODE); - fightmusic->fadeOut(300); - menuRestart(); -} - -void endGame(void){ - trophycounter = 0; -} - -void endGame2(void){ - light1.setEnabled(false); - light2.setEnabled(false); - light3.setEnabled(false); - light4.setEnabled(false); - changeGameMode(ENDMODE); - winner->heal(); - endRestart(); -} - -#define READY 250 -#define FIGHT 500 -#define VICTORY 300 -#define VICTORYEND 700 -#define ENDFADE 780 -#define STARTOVER 800 - -#define TROPHYFADE 400 - -void calculateFight(int framecount){ - fightfade = -1; - if (startcounter < 200){ - fightfade = (200-startcounter)/200.0; - } - if (startcounter == FIGHT - 30){ - fightsound->play(); - } - startcounter++; - - if (endcounter == VICTORY){ - victorysound->play(); - if (winner == man1) points1++; - if (winner == man2) points2++; - } - if (endcounter >= ENDFADE && endcounter <= STARTOVER){ - fightfade = (endcounter - ENDFADE)/(STARTOVER-ENDFADE); - } - if (endcounter == STARTOVER){ - if (points1 == MAXSCORE || points2 == MAXSCORE){ - endGame(); - } else{ - startcounter = 0; - resetFight(); - dead = false; - endcounter = 0; - } - } - if (dead) endcounter++; - if (trophycounter != -1){ - fightfade = (float)trophycounter/TROPHYFADE; - trophycounter++; - if (trophycounter == TROPHYFADE) endGame2(); - } - - /*if (framecount % 10 == 0){ - float pos[3] = {0, 5, 0}; - float vel[3] = {randomf(2)-1, randomf(2)-1, randomf(2)-1}; - createBlood(pos, vel); - }*/ - //arenalight.setPosition(sin(framecount*0.01)*6, 3, cos(framecount*0.01)*4); - //light2.setPosition(sin(framecount*0.017)*6, 2, cos(framecount*0.027)*5); - //light3.setPosition(sin(framecount*0.023)*3, 4, cos(framecount*0.013)*3); - - camera.setPosition(sin(framecount*0.0005)*20, sin(framecount*0.0013)*5+15, cos(framecount*0.0005)*20); - - //camera.setPosition(8, 5, 5); - - float upmovement[3] = {0, 0.001, 0}; - man1->move(upmovement); - man2->move(upmovement); - man1->update(); - man2->update(); - - if (startcounter >= FIGHT){ - - if (man1->isAlive()){ - if (keys[player1left]) man1->turn(5); - if (keys[player1right]) man1->turn(-5); - if (keys[player1forward]) man1->walk(0.03); - if (keys[player1backward]) man1->walk(-0.03); - if (keys[player1jump]) man1->jump(); - if (keys[player1hit]) man1->hit(); - } - - if (man2->isAlive()){ - if (keys[player2left]) man2->turn(5); - if (keys[player2right]) man2->turn(-5); - if (keys[player2forward]) man2->walk(0.03); - if (keys[player2backward]) man2->walk(-0.03); - if (keys[player2jump]) man2->jump(); - if (keys[player2hit]) man2->hit(); - } - } - - - if (keys[SDLK_ESCAPE]){ - stopGame(); - } - - - arenaworld->move(); -} - -void drawDamageMeters(void){ - enable2D(); - - glEnable(GL_BLEND); - - glPushMatrix(); - glTranslatef(0.925, 0.22-0.025, 0); - glScalef(0.08*3/4, 0.08, 0.1); - man1->drawVisuals(); - glPopMatrix(); - - glPushMatrix(); - glTranslatef(0.075, 0.22-0.025, 0); - glScalef(0.08*3/4, 0.08, 0.1); - man2->drawVisuals(); - glPopMatrix(); - - glDisable(GL_TEXTURE_2D); - - - glColor3f(1, 1, 0); - - char pointstring[5]; - sprintf(pointstring, "%i", points1); - print(0.75, 0.05, pointstring, 0.15); - - sprintf(pointstring, "%i", points2); - print(0.15, 0.05, pointstring, 0.15); - - disable2D(); -} - -void drawFight(int framecount){ - glLoadIdentity(); - camera.glUpdate(); - //float position[3]; - //camera.getPosition((float*)position); - //createSkyBox(position[0], position[1], position[2], 50, 20, 50); - - createSkyBox(0, 10, 0, 50, 20, 50); - - - light1.setEnabled(true); - light2.setEnabled(true); - light3.setEnabled(true); - light4.setEnabled(true); - - updateLights(); - - arenaworld->draw(); - - drawDamageMeters(); - - - flaretexture->enable(); - light1.createFlare(); - light2.createFlare(); - light3.createFlare(); - light4.createFlare(); - flaretexture->disable(); - - - enable2D(); - - if (fightfade != -1){ - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glColor4f(0, 0, 0, fightfade); - glBegin(GL_QUADS); - glVertex2f(0, 0); - glVertex2f(1, 0); - glVertex2f(1, 1); - glVertex2f(0, 1); - glEnd(); - } - - if (startcounter >= READY && startcounter < FIGHT){ - float size = 0.2 - (startcounter - READY)*0.0001; - float alpha = 1 - (float)(startcounter - READY)/(FIGHT - READY); - float x = 0.5 - size*1.5; - float y = 0.5 - size*0.5; - - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glColor4f(alpha, 0, 0, alpha); - print(x, y, "Ready", size); - } - if (startcounter >= FIGHT && startcounter < FIGHT+200){ - float size = 0.2 + (startcounter - FIGHT)*0.0005; - float alpha = 1 - (float)(startcounter - FIGHT)/200; - float x = 0.5 - size*1.4; - float y = 0.5 - size*0.5; - - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glColor4f(0, alpha, 0, alpha); - print(x, y, "Fight!", size); - } - - if (dead){ - if (endcounter >= VICTORY && endcounter < VICTORYEND){ - float size = 0.18 + (endcounter - VICTORY)*0.0001; - float alpha = (float)(endcounter - VICTORY)/(VICTORYEND-VICTORY); - alpha = 1-4*(alpha-0.5)*(alpha-0.5); - alpha = pow(alpha, 0.5); - float x = 0.5 - size*1.9; - float y = 0.3 - size*0.5; - - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glColor4f(0, 0, alpha, alpha); - print(x, y, "Victory!", size); - } - } - - disable2D(); - - - glDisable(GL_BLEND); - glEnable(GL_DEPTH_TEST); -} +#include "main.h" + +#include + +#include "legoblocks.h" +#include "camera.h" +#include "light.h" +#include "audio.h" +#include "object.h" +#include "appearance.h" +#include "sphere.h" +#include "vector.h" +#include "collision.h" +#include "utils.h" +#include "graphics.h" +#include "objectfactory.h" +#include "world.h" +#include "3dutils.h" +#include "legoman.h" +#include "particle.h" +#include "font.h" +#include "fight.h" +#include "menu.h" +#include "end.h" +#include "run.h" + +#include "glapi.h" + +Camera camera; +Light light1, light2, light3, light4; +World *arenaworld; + +Sound *fightmusic; +Sound *hitsound1, *hitsound2, *hitsound3, *hitsound4; +Sound *softhitsound1, *softhitsound2; +Sound *jumpsound; +Sound *fallsound1, *fallsound2; +Sound *fightsound; +Sound *victorysound; + +Legoman *man1, *man2; +int points1, points2; + +#define ARENASIZE 10 +#define ARENAHEIGHT 10 + +bool fightinitialized = false; + +void initFight(void){ + if (!fightinitialized){ + initCollisions(); + addCollisionLink(COLLISIONGROUP_ARENA, COLLISIONGROUP_PARTICLE); + //addCollisionLink(COLLISIONGROUP_PARTICLE, COLLISIONGROUP_PARTICLE); + + addCollisionLink(COLLISIONGROUP_MAN1, COLLISIONGROUP_ARENA); + //addCollisionLink(COLLISIONGROUP_MAN1, COLLISIONGROUP_PARTICLE); + addCollisionLink(COLLISIONGROUP_MAN1, COLLISIONGROUP_MAN1); + addCollisionLink(COLLISIONGROUP_MAN1HAND, COLLISIONGROUP_ARENA); + //addCollisionLink(COLLISIONGROUP_MAN1HAND, COLLISIONGROUP_PARTICLE); + + addCollisionLink(COLLISIONGROUP_MAN2, COLLISIONGROUP_ARENA); + //addCollisionLink(COLLISIONGROUP_MAN2, COLLISIONGROUP_PARTICLE); + addCollisionLink(COLLISIONGROUP_MAN2, COLLISIONGROUP_MAN2); + addCollisionLink(COLLISIONGROUP_MAN2HAND, COLLISIONGROUP_ARENA); + //addCollisionLink(COLLISIONGROUP_MAN2HAND, COLLISIONGROUP_PARTICLE); + + addCollisionLink(COLLISIONGROUP_MAN1, COLLISIONGROUP_MAN2); + addCollisionLink(COLLISIONGROUP_MAN1, COLLISIONGROUP_MAN2HAND); + addCollisionLink(COLLISIONGROUP_MAN1HAND, COLLISIONGROUP_MAN2); + addCollisionLink(COLLISIONGROUP_MAN1HAND, COLLISIONGROUP_MAN2HAND); + + //Sound* backgroundsong = new Sound("mixdown.mp3"); + Sound* backgroundsong = new Sound(BGSONG, true); + camera.setPosition(-5, 8, 18); + + arenaworld = new World(); + + + //arenalight.setEnabled(true); + /*arenalight.setPosition(0, 10, 0); + Object *lamp = new Object(); + lamp->appearance = new LampAppearance(); + lamp->setPosition(0, 10, 0); + arenaworld->addChild(lamp);*/ + + } + + light1.setColor(1, 1, 1); + light1.setSpecular(1, 1, 1); + light1.setPosition(-ARENASIZE+0.5, 5, -ARENASIZE+0.5); + light1.setAttenuation(0.2, 0.0, 0.02); + + light2.setColor(1, 1, 1); + light2.setSpecular(1, 1, 1); + light2.setPosition(ARENASIZE-0.5, 5, -ARENASIZE+0.5); + light2.setAttenuation(0.2, 0.0, 0.02); + + light3.setColor(1, 1, 1); + light3.setSpecular(1, 1, 1); + light3.setPosition(-ARENASIZE+0.5, 5, ARENASIZE-0.5); + light3.setAttenuation(0.2, 0.0, 0.02); + + light4.setColor(1, 1, 1); + light4.setSpecular(1, 1, 1); + light4.setPosition(ARENASIZE-0.5, 5, ARENASIZE-0.5); + light4.setAttenuation(0.2, 0.0, 0.02); + + + if (!fightinitialized){ + Object *lamp; + + lamp = new Object(); + lamp->appearance = new LampAppearance(); + lamp->setPosition(-ARENASIZE+0.5, (ARENAHEIGHT+0.5)*BLOCKHEIGHT, -ARENASIZE+0.5); + arenaworld->addChild(lamp); + + lamp = new Object(); + lamp->appearance = new LampAppearance(); + lamp->setPosition(ARENASIZE-0.5, (ARENAHEIGHT+0.5)*BLOCKHEIGHT, -ARENASIZE+0.5); + arenaworld->addChild(lamp); + + lamp = new Object(); + lamp->appearance = new LampAppearance(); + lamp->setPosition(-ARENASIZE+0.5, (ARENAHEIGHT+0.5)*BLOCKHEIGHT, ARENASIZE-0.5); + arenaworld->addChild(lamp); + + lamp = new Object(); + lamp->appearance = new LampAppearance(); + lamp->setPosition(ARENASIZE-0.5, (ARENAHEIGHT+0.5)*BLOCKHEIGHT, ARENASIZE-0.5); + arenaworld->addChild(lamp); + + + //Floor + BasicBlock *floorblock; + floorblock = new BasicBlock(ARENASIZE*2, 3, ARENASIZE*2); + floorblock->setPosition(0, -BLOCKHEIGHT*3/2.0, 0); + floorblock->setColor(0, 1, 0); + floorblock->setCollisionGroup(COLLISIONGROUP_ARENA); + arenaworld->addChild(floorblock); + + + //Corners + BasicBlock *arenacorner; + + arenacorner = new BasicBlock(1, ARENAHEIGHT, 1); + arenacorner->setColor(1, 0, 0); + //arenacorner->setCollisionGroup(COLLISIONGROUP_ARENA); + arenacorner->setPosition(ARENASIZE-0.5, BLOCKHEIGHT*ARENAHEIGHT/2.0, ARENASIZE-0.5); + arenaworld->addChild(arenacorner); + + arenacorner = new BasicBlock(1, ARENAHEIGHT, 1); + arenacorner->setColor(1, 0, 0); + //arenacorner->setCollisionGroup(COLLISIONGROUP_ARENA); + arenacorner->setPosition(-ARENASIZE+0.5, BLOCKHEIGHT*ARENAHEIGHT/2.0, ARENASIZE-0.5); + arenaworld->addChild(arenacorner); + + arenacorner = new BasicBlock(1, ARENAHEIGHT, 1); + arenacorner->setColor(1, 0, 0); + //arenacorner->setCollisionGroup(COLLISIONGROUP_ARENA); + arenacorner->setPosition(ARENASIZE-0.5, BLOCKHEIGHT*ARENAHEIGHT/2.0, -ARENASIZE+0.5); + arenaworld->addChild(arenacorner); + + arenacorner = new BasicBlock(1, ARENAHEIGHT, 1); + arenacorner->setColor(1, 0, 0); + //arenacorner->setCollisionGroup(COLLISIONGROUP_ARENA); + arenacorner->setPosition(-ARENASIZE+0.5, BLOCKHEIGHT*ARENAHEIGHT/2.0, -ARENASIZE+0.5); + arenaworld->addChild(arenacorner); + + + //"Ropes" + MeshObject *arenaline; + Mesh *linegeometry; + MultiAppearance *lineappearance; + BasicBlockAppearance *line; + int geometryheight = BLOCKHEIGHT*ARENAHEIGHT; + + linegeometry = createBox(-0.5, 0.5, -geometryheight/2, geometryheight/2-BLOCKHEIGHT, -ARENASIZE, ARENASIZE); + arenaline = new MeshObject(linegeometry); + lineappearance = new MultiAppearance(); + line = new BasicBlockAppearance(1, 1, ARENASIZE*2); + vectorSet(line->displacement, 0, -BLOCKHEIGHT*2.5, 0); + line->material.setColor(1, 0, 0, 1); + lineappearance->addAppearance(line), + line = new BasicBlockAppearance(1, 1, ARENASIZE*2); + vectorSet(line->displacement, 0, BLOCKHEIGHT*0.5, 0); + line->material.setColor(1, 0, 0, 1); + lineappearance->addAppearance(line), + line = new BasicBlockAppearance(1, 1, ARENASIZE*2); + vectorSet(line->displacement, 0, BLOCKHEIGHT*3.5, 0); + line->material.setColor(1, 0, 0, 1); + lineappearance->addAppearance(line), + arenaline->appearance = lineappearance; + arenaline->setCollisionGroup(COLLISIONGROUP_ARENA); + arenaline->setPosition(-ARENASIZE+0.5, geometryheight/2, 0); + arenaworld->addChild(arenaline); + + linegeometry = createBox(-0.5, 0.5, -geometryheight/2, geometryheight/2-BLOCKHEIGHT, -ARENASIZE, ARENASIZE); + arenaline = new MeshObject(linegeometry); + lineappearance = new MultiAppearance(); + line = new BasicBlockAppearance(1, 1, ARENASIZE*2); + vectorSet(line->displacement, 0, -BLOCKHEIGHT*2.5, 0); + line->material.setColor(1, 0, 0, 1); + lineappearance->addAppearance(line), + line = new BasicBlockAppearance(1, 1, ARENASIZE*2); + vectorSet(line->displacement, 0, BLOCKHEIGHT*0.5, 0); + line->material.setColor(1, 0, 0, 1); + lineappearance->addAppearance(line), + line = new BasicBlockAppearance(1, 1, ARENASIZE*2); + vectorSet(line->displacement, 0, BLOCKHEIGHT*3.5, 0); + line->material.setColor(1, 0, 0, 1); + lineappearance->addAppearance(line), + arenaline->appearance = lineappearance; + arenaline->setCollisionGroup(COLLISIONGROUP_ARENA); + arenaline->setPosition(ARENASIZE-0.5, geometryheight/2, 0); + arenaworld->addChild(arenaline); + + linegeometry = createBox(-ARENASIZE, ARENASIZE, -geometryheight/2, geometryheight/2-BLOCKHEIGHT, -0.5, 0.5); + arenaline = new MeshObject(linegeometry); + lineappearance = new MultiAppearance(); + line = new BasicBlockAppearance(ARENASIZE*2, 1, 1); + vectorSet(line->displacement, 0, -BLOCKHEIGHT*2.5, 0); + line->material.setColor(1, 0, 0, 1); + lineappearance->addAppearance(line), + line = new BasicBlockAppearance(ARENASIZE*2, 1, 1); + vectorSet(line->displacement, 0, BLOCKHEIGHT*0.5, 0); + line->material.setColor(1, 0, 0, 1); + lineappearance->addAppearance(line), + line = new BasicBlockAppearance(ARENASIZE*2, 1, 1); + vectorSet(line->displacement, 0, BLOCKHEIGHT*3.5, 0); + line->material.setColor(1, 0, 0, 1); + lineappearance->addAppearance(line), + arenaline->appearance = lineappearance; + arenaline->setCollisionGroup(COLLISIONGROUP_ARENA); + arenaline->setPosition(0, geometryheight/2, -ARENASIZE+0.5); + arenaworld->addChild(arenaline); + + linegeometry = createBox(-ARENASIZE, ARENASIZE, -geometryheight/2, geometryheight/2-BLOCKHEIGHT, -0.5, 0.5); + arenaline = new MeshObject(linegeometry); + lineappearance = new MultiAppearance(); + line = new BasicBlockAppearance(ARENASIZE*2, 1, 1); + vectorSet(line->displacement, 0, -BLOCKHEIGHT*2.5, 0); + line->material.setColor(1, 0, 0, 1); + lineappearance->addAppearance(line), + line = new BasicBlockAppearance(ARENASIZE*2, 1, 1); + vectorSet(line->displacement, 0, BLOCKHEIGHT*0.5, 0); + line->material.setColor(1, 0, 0, 1); + lineappearance->addAppearance(line), + line = new BasicBlockAppearance(ARENASIZE*2, 1, 1); + vectorSet(line->displacement, 0, BLOCKHEIGHT*3.5, 0); + line->material.setColor(1, 0, 0, 1); + lineappearance->addAppearance(line), + arenaline->appearance = lineappearance; + arenaline->setCollisionGroup(COLLISIONGROUP_ARENA); + arenaline->setPosition(0, geometryheight/2, ARENASIZE-0.5); + arenaworld->addChild(arenaline); + + float movement[3]; + + man1 = new Legoman(PLAYER1); + man1->insertToWorld(arenaworld); + vectorSet(movement, -4, 0, 0); + man1->move(movement); + man1->lockPart(LEFTLEG | RIGHTLEG); + + man2 = new Legoman(PLAYER2); + man2->insertToWorld(arenaworld); + vectorSet(movement, 4, 0, 0); + man2->move(movement); + man2->lockPart(LEFTLEG | RIGHTLEG); + + man1->addOpponent(man2); + man2->addOpponent(man1); + + + initBloods(arenaworld); + + + hitsound1 = new Sound(DATAPATH"hit1.wav"); + softhitsound1 = new Sound(DATAPATH"hitsoft1.wav"); + softhitsound2 = new Sound(DATAPATH"hitsoft2.wav"); + jumpsound = new Sound(DATAPATH"jump.wav"); + fallsound1 = new Sound(DATAPATH"fall1.wav"); + fallsound2 = new Sound(DATAPATH"fall2.wav"); + fightsound = new Sound(DATAPATH"fight.wav"); + victorysound = new Sound(DATAPATH"victory.wav"); + + fightmusic = new Sound(DATAPATH"fight.mp3", true); + } + + float cameraTarget[3] = {0, 6, 0}; + camera.setTarget(cameraTarget); + arenaworld->prepare(); + + points1 = 0; + points2 = 0; + + winner = man1; +} + +#define MAXSCORE 3 + +int trophycounter = -1; + +void resetFight(void){ + float movement[3]; + man1->heal(); + man2->heal(); + + vectorSet(movement, -4, 0, 0); + man1->move(movement); + vectorSet(movement, 4, 0, 0); + man2->move(movement); + + man1->lockPart(LEFTLEG | RIGHTLEG); + man2->lockPart(LEFTLEG | RIGHTLEG); +} + +int startcounter, endcounter; + +float fightfade; + +bool dead; + +Legoman *winner; + +void gameOver(Legoman *loser){ + endcounter = 0; + dead = true; + winner = loser->getOpponent(); +} + +void startFight(void){ + resetFight(); + fightmusic->setVolume(0); + fightmusic->play(); + fightmusic->fadeIn(300); + startcounter = 0; + trophycounter = -1; + fightfade = 1; + dead = false; + points1 = 0; + points2 = 0; +} + +SDLKey player1left = SDLK_LEFT; +SDLKey player1right = SDLK_RIGHT; +SDLKey player1forward = SDLK_UP; +SDLKey player1backward = SDLK_DOWN; +SDLKey player1jump = SDLK_RSHIFT; +SDLKey player1hit = SDLK_RCTRL; + +SDLKey player2left = SDLK_a; +SDLKey player2right = SDLK_d; +SDLKey player2forward = SDLK_w; +SDLKey player2backward = SDLK_s; +SDLKey player2jump = SDLK_LSHIFT; +SDLKey player2hit = SDLK_LCTRL; + + +void stopGame(void){ + light1.setEnabled(false); + light2.setEnabled(false); + light3.setEnabled(false); + light4.setEnabled(false); + changeGameMode(MENUMODE); + fightmusic->fadeOut(300); + menuRestart(); +} + +void endGame(void){ + trophycounter = 0; +} + +void endGame2(void){ + light1.setEnabled(false); + light2.setEnabled(false); + light3.setEnabled(false); + light4.setEnabled(false); + changeGameMode(ENDMODE); + winner->heal(); + endRestart(); +} + +#define READY 250 +#define FIGHT 500 +#define VICTORY 300 +#define VICTORYEND 700 +#define ENDFADE 780 +#define STARTOVER 800 + +#define TROPHYFADE 400 + +void calculateFight(int framecount){ + fightfade = -1; + if (startcounter < 200){ + fightfade = (200-startcounter)/200.0; + } + if (startcounter == FIGHT - 30){ + fightsound->play(); + } + startcounter++; + + if (endcounter == VICTORY){ + victorysound->play(); + if (winner == man1) points1++; + if (winner == man2) points2++; + } + if (endcounter >= ENDFADE && endcounter <= STARTOVER){ + fightfade = (endcounter - ENDFADE)/(STARTOVER-ENDFADE); + } + if (endcounter == STARTOVER){ + if (points1 == MAXSCORE || points2 == MAXSCORE){ + endGame(); + } else{ + startcounter = 0; + resetFight(); + dead = false; + endcounter = 0; + } + } + if (dead) endcounter++; + if (trophycounter != -1){ + fightfade = (float)trophycounter/TROPHYFADE; + trophycounter++; + if (trophycounter == TROPHYFADE) endGame2(); + } + + /*if (framecount % 10 == 0){ + float pos[3] = {0, 5, 0}; + float vel[3] = {randomf(2)-1, randomf(2)-1, randomf(2)-1}; + createBlood(pos, vel); + }*/ + //arenalight.setPosition(sin(framecount*0.01)*6, 3, cos(framecount*0.01)*4); + //light2.setPosition(sin(framecount*0.017)*6, 2, cos(framecount*0.027)*5); + //light3.setPosition(sin(framecount*0.023)*3, 4, cos(framecount*0.013)*3); + + camera.setPosition(sin(framecount*0.0005)*20, sin(framecount*0.0013)*5+15, cos(framecount*0.0005)*20); + + //camera.setPosition(8, 5, 5); + + float upmovement[3] = {0, 0.001, 0}; + man1->move(upmovement); + man2->move(upmovement); + man1->update(); + man2->update(); + + if (startcounter >= FIGHT){ + + if (man1->isAlive()){ + if (keys[player1left]) man1->turn(5); + if (keys[player1right]) man1->turn(-5); + if (keys[player1forward]) man1->walk(0.03); + if (keys[player1backward]) man1->walk(-0.03); + if (keys[player1jump]) man1->jump(); + if (keys[player1hit]) man1->hit(); + } + + if (man2->isAlive()){ + if (keys[player2left]) man2->turn(5); + if (keys[player2right]) man2->turn(-5); + if (keys[player2forward]) man2->walk(0.03); + if (keys[player2backward]) man2->walk(-0.03); + if (keys[player2jump]) man2->jump(); + if (keys[player2hit]) man2->hit(); + } + } + + + if (keys[SDLK_ESCAPE]){ + stopGame(); + } + + + arenaworld->move(); +} + +void drawDamageMeters(void){ + enable2D(); + + glEnable(GL_BLEND); + + glPushMatrix(); + glTranslatef(0.925, 0.22-0.025, 0); + glScalef(0.08*3/4, 0.08, 0.1); + man1->drawVisuals(); + glPopMatrix(); + + glPushMatrix(); + glTranslatef(0.075, 0.22-0.025, 0); + glScalef(0.08*3/4, 0.08, 0.1); + man2->drawVisuals(); + glPopMatrix(); + + glDisable(GL_TEXTURE_2D); + + + glColor3f(1, 1, 0); + + char pointstring[5]; + sprintf(pointstring, "%i", points1); + print(0.75, 0.05, pointstring, 0.15); + + sprintf(pointstring, "%i", points2); + print(0.15, 0.05, pointstring, 0.15); + + disable2D(); +} + +void drawFight(int framecount){ + glLoadIdentity(); + camera.glUpdate(); + //float position[3]; + //camera.getPosition((float*)position); + //createSkyBox(position[0], position[1], position[2], 50, 20, 50); + + createSkyBox(0, 10, 0, 50, 20, 50); + + + light1.setEnabled(true); + light2.setEnabled(true); + light3.setEnabled(true); + light4.setEnabled(true); + + updateLights(); + + arenaworld->draw(); + + drawDamageMeters(); + + + flaretexture->enable(); + light1.createFlare(); + light2.createFlare(); + light3.createFlare(); + light4.createFlare(); + flaretexture->disable(); + + + enable2D(); + + if (fightfade != -1){ + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glColor4f(0, 0, 0, fightfade); + glBegin(GL_QUADS); + glVertex2f(0, 0); + glVertex2f(1, 0); + glVertex2f(1, 1); + glVertex2f(0, 1); + glEnd(); + } + + if (startcounter >= READY && startcounter < FIGHT){ + float size = 0.2 - (startcounter - READY)*0.0001; + float alpha = 1 - (float)(startcounter - READY)/(FIGHT - READY); + float x = 0.5 - size*1.5; + float y = 0.5 - size*0.5; + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glColor4f(alpha, 0, 0, alpha); + print(x, y, "Ready", size); + } + if (startcounter >= FIGHT && startcounter < FIGHT+200){ + float size = 0.2 + (startcounter - FIGHT)*0.0005; + float alpha = 1 - (float)(startcounter - FIGHT)/200; + float x = 0.5 - size*1.4; + float y = 0.5 - size*0.5; + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glColor4f(0, alpha, 0, alpha); + print(x, y, "Fight!", size); + } + + if (dead){ + if (endcounter >= VICTORY && endcounter < VICTORYEND){ + float size = 0.18 + (endcounter - VICTORY)*0.0001; + float alpha = (float)(endcounter - VICTORY)/(VICTORYEND-VICTORY); + alpha = 1-4*(alpha-0.5)*(alpha-0.5); + alpha = pow(alpha, 0.5); + float x = 0.5 - size*1.9; + float y = 0.3 - size*0.5; + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glColor4f(0, 0, alpha, alpha); + print(x, y, "Victory!", size); + } + } + + disable2D(); + + + glDisable(GL_BLEND); + glEnable(GL_DEPTH_TEST); +} diff --git a/src/fight.h b/src/fight.h index 4d79d2c..90bbfaa 100644 --- a/src/fight.h +++ b/src/fight.h @@ -1,28 +1,28 @@ -#ifndef __FIGHT_H_INCLUDED__ -#define __FIGHT_H_INCLUDED__ - -#include -#include "audio.h" -#include "legoman.h" - -extern Sound *fightmusic; -extern Sound *hitsound1; -extern Sound *softhitsound1, *softhitsound2; -extern Sound *jumpsound; -extern Sound *fallsound1, *fallsound2; - -extern bool dead; - -extern Legoman *winner; - -void initFight(void); -void gameOver(Legoman *loser); -void startFight(void); -void calculateFight(int framecount); -void drawFight(int framecount); - -void handleKeydownFight(SDLKey key); -void addGraphicsVector(float *p1, float *p2, float size); - -#endif - +#ifndef __FIGHT_H_INCLUDED__ +#define __FIGHT_H_INCLUDED__ + +#include +#include "audio.h" +#include "legoman.h" + +extern Sound *fightmusic; +extern Sound *hitsound1; +extern Sound *softhitsound1, *softhitsound2; +extern Sound *jumpsound; +extern Sound *fallsound1, *fallsound2; + +extern bool dead; + +extern Legoman *winner; + +void initFight(void); +void gameOver(Legoman *loser); +void startFight(void); +void calculateFight(int framecount); +void drawFight(int framecount); + +void handleKeydownFight(SDLKey key); +void addGraphicsVector(float *p1, float *p2, float size); + +#endif + diff --git a/src/font.cpp b/src/font.cpp index b33bcfa..2952b8d 100644 --- a/src/font.cpp +++ b/src/font.cpp @@ -1,73 +1,73 @@ -#include "main.h" - -#include "font.h" -#include "glapi.h" - -Texture *fonttexture; - -void drawChar(float x, float y, char ch, float size){ - fonttexture->enable(); - - int tx = (ch&15)*64; - int ty = (ch>>4)*64; - - float w = size, h = size*4/3; - - glEnable(GL_BLEND); - glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR); - - glBegin(GL_QUADS); - glTexCoord2f((tx)/1024.0, (ty)/1024.0); - glVertex2f(x, y); - - glTexCoord2f((tx)/1024.0, (ty+64)/1024.0); - glVertex2f(x, y+h); - - glTexCoord2f((tx+64)/1024.0, (ty+64)/1024.0); - glVertex2f(x+w, y+h); - - glTexCoord2f((tx+64)/1024.0, (ty)/1024.0); - glVertex2f(x+w, y); - - glEnd(); - - fonttexture->disable(); -} - -float letterwidth[256] = { - 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, - 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, - 0.5, 0.2, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.45, 0.2, 0.5, - 0.6, 0.5, 0.6, 0.6, 0.65, 0.65, 0.6, 0.65, 0.6, 0.6, 0.2, 1.0, 1.0, 1.0, 1.0, 0.5, - 1.0, 0.7, 0.6, 0.7, 0.7, 0.65, 0.6, 0.7, 0.8, 0.6, 0.7, 0.7, 0.6, 0.9, 0.85, 0.8, - 0.6, 0.9, 0.7, 0.7, 0.7, 0.7, 0.7, 1.0, 0.8, 0.7, 0.8, 1.0, 1.0, 1.0, 1.0, 1.0, - 1.0, 0.6, 0.6, 0.6, 0.6, 0.6, 0.5, 0.6, 0.6, 0.2, 0.4, 0.6, 0.2, 0.8, 0.5, 0.55, - 0.55, 0.55, 0.5, 0.55, 0.55, 0.55, 0.6, 0.8, 0.6, 0.6, 0.6, 1.0, 1.0, 1.0, 1.0, 1.0, - 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, - 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, - 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, - 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, - 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, - 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, - 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, - 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0 -}; - -void print(float x, float y, char *text, float size){ - int i; - int textlength = strlen(text); - float px = x; - float py = y; - for (i = 0; i < textlength; i++){ - char ch = text[i]; - if (ch == '\n'){ - px = x; - py += size*1.2; - } else{ - drawChar(px, py, ch, size); - px += size*letterwidth[ch]; - } - } -} - - +#include "main.h" + +#include "font.h" +#include "glapi.h" + +Texture *fonttexture; + +void drawChar(float x, float y, char ch, float size){ + fonttexture->enable(); + + int tx = (ch&15)*64; + int ty = (ch>>4)*64; + + float w = size, h = size*4/3; + + glEnable(GL_BLEND); + glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR); + + glBegin(GL_QUADS); + glTexCoord2f((tx)/1024.0, (ty)/1024.0); + glVertex2f(x, y); + + glTexCoord2f((tx)/1024.0, (ty+64)/1024.0); + glVertex2f(x, y+h); + + glTexCoord2f((tx+64)/1024.0, (ty+64)/1024.0); + glVertex2f(x+w, y+h); + + glTexCoord2f((tx+64)/1024.0, (ty)/1024.0); + glVertex2f(x+w, y); + + glEnd(); + + fonttexture->disable(); +} + +float letterwidth[256] = { + 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, + 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, + 0.5, 0.2, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.45, 0.2, 0.5, + 0.6, 0.5, 0.6, 0.6, 0.65, 0.65, 0.6, 0.65, 0.6, 0.6, 0.2, 1.0, 1.0, 1.0, 1.0, 0.5, + 1.0, 0.7, 0.6, 0.7, 0.7, 0.65, 0.6, 0.7, 0.8, 0.6, 0.7, 0.7, 0.6, 0.9, 0.85, 0.8, + 0.6, 0.9, 0.7, 0.7, 0.7, 0.7, 0.7, 1.0, 0.8, 0.7, 0.8, 1.0, 1.0, 1.0, 1.0, 1.0, + 1.0, 0.6, 0.6, 0.6, 0.6, 0.6, 0.5, 0.6, 0.6, 0.2, 0.4, 0.6, 0.2, 0.8, 0.5, 0.55, + 0.55, 0.55, 0.5, 0.55, 0.55, 0.55, 0.6, 0.8, 0.6, 0.6, 0.6, 1.0, 1.0, 1.0, 1.0, 1.0, + 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, + 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, + 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, + 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, + 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, + 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, + 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, + 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0 +}; + +void print(float x, float y, char *text, float size){ + int i; + int textlength = strlen(text); + float px = x; + float py = y; + for (i = 0; i < textlength; i++){ + char ch = text[i]; + if (ch == '\n'){ + px = x; + py += size*1.2; + } else{ + drawChar(px, py, ch, size); + px += size*letterwidth[ch]; + } + } +} + + diff --git a/src/font.h b/src/font.h index 2ec09a2..0518440 100644 --- a/src/font.h +++ b/src/font.h @@ -1,13 +1,13 @@ -#ifndef __FONT_H_INCLUDED__ -#define __FONT_H_INCLUDED__ - -#include "texture.h" - -extern Texture *fonttexture; - -//Top left = 0.0 , 0.0 Bottom right = 1.0 , 1.0 -void drawChar(float x, float y, char ch, float size = 0.05); -void print(float x, float y, char *text, float size = 0.05); - -#endif - +#ifndef __FONT_H_INCLUDED__ +#define __FONT_H_INCLUDED__ + +#include "texture.h" + +extern Texture *fonttexture; + +//Top left = 0.0 , 0.0 Bottom right = 1.0 , 1.0 +void drawChar(float x, float y, char ch, float size = 0.05); +void print(float x, float y, char *text, float size = 0.05); + +#endif + diff --git a/src/glapi.cpp b/src/glapi.cpp index 13bbfb4..2a6e3be 100644 --- a/src/glapi.cpp +++ b/src/glapi.cpp @@ -1,64 +1,64 @@ -#include "main.h" - -#include "glapi.h" - -void setupOpengl(int width, int height){ - //float ratio = (float)width/height; - float ratio = 4.0/3.0; - - glShadeModel(GL_SMOOTH); - - glCullFace(GL_BACK); - glFrontFace(GL_CCW); - glEnable(GL_CULL_FACE); - - glEnable(GL_DEPTH_TEST); - glDepthFunc(GL_LEQUAL); - glClearDepth(1.0); - - glClearColor(0, 0, 0, 0); - - glEnable(GL_COLOR_MATERIAL); - - //Enables lighting with zero initial lights. Lights are created with Light-class - glEnable(GL_LIGHTING); - glDisable(GL_LIGHT0); - - float ambient[4]= {0.1, 0.1, 0.1, 1}; - glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient); - - glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE); - glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE); - - GLfloat zero[4] = {0, 0, 0, 1}; - GLfloat one[4] = {1, 1, 1, 1}; - - //Default frontface lighting - glMaterialfv(GL_FRONT, GL_AMBIENT, one); - glMaterialfv(GL_FRONT, GL_DIFFUSE, one); - GLfloat specular[4] = {2, 2, 2, 1}; - glMaterialfv(GL_FRONT, GL_SPECULAR, specular); - glMaterialf(GL_FRONT, GL_SHININESS, 120); - - //Never any backface lighting, except ambient - glMaterialfv(GL_BACK, GL_AMBIENT, one); - glMaterialfv(GL_BACK, GL_DIFFUSE, zero); - glMaterialfv(GL_BACK, GL_SPECULAR, zero); - - - - glViewport(0, 0, width, height); - - glDepthFunc(GL_LEQUAL); - glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); - - glEnable(GL_NORMALIZE); - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - - gluPerspective(60.0, ratio, 1.0, 1024.0); - - - //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); -} +#include "main.h" + +#include "glapi.h" + +void setupOpengl(int width, int height){ + //float ratio = (float)width/height; + float ratio = 4.0/3.0; + + glShadeModel(GL_SMOOTH); + + glCullFace(GL_BACK); + glFrontFace(GL_CCW); + glEnable(GL_CULL_FACE); + + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_LEQUAL); + glClearDepth(1.0); + + glClearColor(0, 0, 0, 0); + + glEnable(GL_COLOR_MATERIAL); + + //Enables lighting with zero initial lights. Lights are created with Light-class + glEnable(GL_LIGHTING); + glDisable(GL_LIGHT0); + + float ambient[4]= {0.1, 0.1, 0.1, 1}; + glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient); + + glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE); + glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE); + + GLfloat zero[4] = {0, 0, 0, 1}; + GLfloat one[4] = {1, 1, 1, 1}; + + //Default frontface lighting + glMaterialfv(GL_FRONT, GL_AMBIENT, one); + glMaterialfv(GL_FRONT, GL_DIFFUSE, one); + GLfloat specular[4] = {2, 2, 2, 1}; + glMaterialfv(GL_FRONT, GL_SPECULAR, specular); + glMaterialf(GL_FRONT, GL_SHININESS, 120); + + //Never any backface lighting, except ambient + glMaterialfv(GL_BACK, GL_AMBIENT, one); + glMaterialfv(GL_BACK, GL_DIFFUSE, zero); + glMaterialfv(GL_BACK, GL_SPECULAR, zero); + + + + glViewport(0, 0, width, height); + + glDepthFunc(GL_LEQUAL); + glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); + + glEnable(GL_NORMALIZE); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + + gluPerspective(60.0, ratio, 1.0, 1024.0); + + + //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); +} diff --git a/src/glapi.h b/src/glapi.h index e6fba06..8f07e27 100644 --- a/src/glapi.h +++ b/src/glapi.h @@ -1,10 +1,10 @@ -#ifndef __GLAPI_H_INCLUDED__ -#define __GLAPI_H_INCLUDED__ - -#include - -void setupOpengl(int width, int height); - -#endif - - +#ifndef __GLAPI_H_INCLUDED__ +#define __GLAPI_H_INCLUDED__ + +#include + +void setupOpengl(int width, int height); + +#endif + + diff --git a/src/graphics.cpp b/src/graphics.cpp index 3874dad..19a5cb4 100644 --- a/src/graphics.cpp +++ b/src/graphics.cpp @@ -1,236 +1,236 @@ -#include "graphics.h" -#include - -GraphicsDruid *GraphicsDruid::instance = 0; - -GraphicsDruid::GraphicsDruid(void){ - this->reserved = 0; -} - -GraphicsDruid::~GraphicsDruid(void){ -} - -void GraphicsDruid::init(void){ - instance->textureCount = 0; - instance->reserved = ID_ARRAY_INIT_SIZE; - instance->idArray = (int*) calloc(ID_ARRAY_INIT_SIZE, sizeof(int)); - - for (int i=0; i < instance->reserved; i++){ - instance->idArray[i] = -1; - } -} - -void GraphicsDruid::destroy(void){ - if (instance->textureCount > 0){ - glDeleteTextures(GL_TEXTURE_2D, (const unsigned int*)instance->idArray); - } - free(instance->idArray); - instance->idArray = 0; - delete instance; - instance = 0; -} - -GraphicsDruid &GraphicsDruid::getInstance(void){ - - if (!instance){ - instance = new GraphicsDruid; - init(); - } - return *instance; -} - -int GraphicsDruid::loadTexture(SDL_Surface *texture, int id, int format){ - - int textureID = id == -1 ? getNewTextureID(id) : id; - - // register texture in OpenGL - glBindTexture (GL_TEXTURE_2D, textureID); - - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);//_MIPMAP_NEAREST); - //glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); - //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); - - //printf("w: %i, h: %i, format: %i, RGBA: %i, pixels: %p\n", - // texture->w, texture->h, format, GL_RGBA, texture->pixels); - //printf("Pitch: %i, Bpp: %i\n", texture->pitch, texture->format->BytesPerPixel); - - /*gluBuild2DMipmaps(GL_TEXTURE_2D, - 4, - texture->w, - texture->h, - format, - GL_UNSIGNED_BYTE, - texture->pixels);*/ - int w = texture->w; - int h = texture->h; - /*int i; - while (w > 0){ - w >>= 1; - i++; - } - w = 1; - for (;i > 1; i--) w <<= 1; - while (h > 0){ - h >>= 1; - i++; - } - h = 1; - for (;i > 1; i--) h <<= 1;*/ - //glTexImage2D(GL_TEXTURE_2D, 0, texture->format->BytesPerPixel, w, h, 0, format, GL_UNSIGNED_BYTE, texture->pixels); - if (texture->format->BytesPerPixel == 3){ - glTexImage2D(GL_TEXTURE_2D, 0, 3, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, texture->pixels); - } else if (texture->format->BytesPerPixel == 4){ - glTexImage2D(GL_TEXTURE_2D, 0, 4, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture->pixels); - } - //SDL_FreeSurface(texture); - //SDL_FreeSurface(alphaSurface); - return textureID; -} - -int GraphicsDruid::loadTexture(char* path, int id){ - - SDL_Surface* texture; - texture = IMG_Load(path); - - if (!texture){ -#ifdef _DEBUG - printf ("Error while loading image: %s\n", SDL_GetError()); -#endif - return -1; - } - int textureID = getNewTextureID(id); - - - // register texture in OpenGL - glBindTexture (GL_TEXTURE_2D, textureID); - - //glPixelStorei (GL_UNPACK_ALIGNMENT, 1); - - // NOTE : Making some assumptions about texture parameters - //glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - //glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); - glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - - glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - - //printf("w: %i, h: %i, RGBA: %i, pixels: %p\n", - // texture->w, texture->h, GL_RGBA, texture->pixels); - //printf("Pitch: %i, Bpp: %i\n", texture->pitch, texture->format->BytesPerPixel); - - if (texture->format->BytesPerPixel == 3){ - /*gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, - texture->w, - texture->h, - GL_RGB, GL_UNSIGNED_BYTE, - texture->pixels);*/ - glTexImage2D(GL_TEXTURE_2D, 0, 3, texture->w, texture->h, 0, GL_RGB, GL_UNSIGNED_BYTE, texture->pixels); - } - else if (texture->format->BytesPerPixel == 4){ - /*gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, - texture->w, - texture->h, - GL_RGBA, GL_UNSIGNED_BYTE, - texture->pixels);*/ - glTexImage2D(GL_TEXTURE_2D, 0, 4, texture->w, texture->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture->pixels); - } - -/* - - - gluBuild2DMipmaps(GL_TEXTURE_2D, - 0, - texture->w, - texture->h, - GL_RGBA, - GL_UNSIGNED_BYTE, - texture->pixels); - */ - SDL_FreeSurface(texture); - return textureID; -} - -int GraphicsDruid::loadTranspTexture(char* path, float* transpColor, int id){ - - SDL_Surface* texture; - texture = IMG_Load(path); - if (!texture){ -#ifdef _DEBUG - printf ("Error while loading image: %s\n", SDL_GetError()); -#endif - return -1; - } - - - Uint32 colorKey = SDL_MapRGB(texture->format, - (Uint8)(transpColor[0] * 255), - (Uint8)(transpColor[1] * 255), - (Uint8)(transpColor[2] * 255)); - //SDL_SetAlpha(texture, 0, SDL_ALPHA_OPAQUE); - - SDL_SetColorKey(texture, SDL_SRCCOLORKEY, colorKey); - - //SDL_Surface* alphaSurface = SDL_DisplayFormatAlpha(texture); - texture = SDL_DisplayFormatAlpha(texture); - - return loadTexture(texture); -} - -int GraphicsDruid::getNewTextureID(int id){ - - if (id != -1){ - for (int i = 0; i < instance->reserved; i++){ - if (instance->idArray[i] == id){ - freeTexture(id); - instance->textureCount--; - break; - } - } - } - - GLuint newId; - - if (id == -1){ - glGenTextures (1, &newId); - } - else - newId = id; - - int index = 0; - while (instance->idArray[index] != -1 && index < instance->reserved){ - index++; - } - - // out of space, make more - if (index >= instance->reserved){ - instance->idArray = (int*) realloc(instance->idArray, (instance->reserved + ID_ARRAY_GROW)*sizeof(int)); - - for (int i = instance->reserved + 1; i < instance->reserved + ID_ARRAY_GROW; i++) - instance->idArray[i] = -1; - - instance->reserved += ID_ARRAY_GROW; - } - else - instance->idArray[index] = newId; - - - instance->textureCount++; - return newId; -} - -void GraphicsDruid::freeTexture(int id){ - if (id > -1 && id < instance->reserved){ - instance->idArray[id] = -1; - const unsigned int helpInt = id; - glDeleteTextures(1, &helpInt); - } -} - +#include "graphics.h" +#include + +GraphicsDruid *GraphicsDruid::instance = 0; + +GraphicsDruid::GraphicsDruid(void){ + this->reserved = 0; +} + +GraphicsDruid::~GraphicsDruid(void){ +} + +void GraphicsDruid::init(void){ + instance->textureCount = 0; + instance->reserved = ID_ARRAY_INIT_SIZE; + instance->idArray = (int*) calloc(ID_ARRAY_INIT_SIZE, sizeof(int)); + + for (int i=0; i < instance->reserved; i++){ + instance->idArray[i] = -1; + } +} + +void GraphicsDruid::destroy(void){ + if (instance->textureCount > 0){ + glDeleteTextures(GL_TEXTURE_2D, (const unsigned int*)instance->idArray); + } + free(instance->idArray); + instance->idArray = 0; + delete instance; + instance = 0; +} + +GraphicsDruid &GraphicsDruid::getInstance(void){ + + if (!instance){ + instance = new GraphicsDruid; + init(); + } + return *instance; +} + +int GraphicsDruid::loadTexture(SDL_Surface *texture, int id, int format){ + + int textureID = id == -1 ? getNewTextureID(id) : id; + + // register texture in OpenGL + glBindTexture (GL_TEXTURE_2D, textureID); + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);//_MIPMAP_NEAREST); + //glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + + //printf("w: %i, h: %i, format: %i, RGBA: %i, pixels: %p\n", + // texture->w, texture->h, format, GL_RGBA, texture->pixels); + //printf("Pitch: %i, Bpp: %i\n", texture->pitch, texture->format->BytesPerPixel); + + /*gluBuild2DMipmaps(GL_TEXTURE_2D, + 4, + texture->w, + texture->h, + format, + GL_UNSIGNED_BYTE, + texture->pixels);*/ + int w = texture->w; + int h = texture->h; + /*int i; + while (w > 0){ + w >>= 1; + i++; + } + w = 1; + for (;i > 1; i--) w <<= 1; + while (h > 0){ + h >>= 1; + i++; + } + h = 1; + for (;i > 1; i--) h <<= 1;*/ + //glTexImage2D(GL_TEXTURE_2D, 0, texture->format->BytesPerPixel, w, h, 0, format, GL_UNSIGNED_BYTE, texture->pixels); + if (texture->format->BytesPerPixel == 3){ + glTexImage2D(GL_TEXTURE_2D, 0, 3, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, texture->pixels); + } else if (texture->format->BytesPerPixel == 4){ + glTexImage2D(GL_TEXTURE_2D, 0, 4, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture->pixels); + } + //SDL_FreeSurface(texture); + //SDL_FreeSurface(alphaSurface); + return textureID; +} + +int GraphicsDruid::loadTexture(char* path, int id){ + + SDL_Surface* texture; + texture = IMG_Load(path); + + if (!texture){ +#ifdef _DEBUG + printf ("Error while loading image: %s\n", SDL_GetError()); +#endif + return -1; + } + int textureID = getNewTextureID(id); + + + // register texture in OpenGL + glBindTexture (GL_TEXTURE_2D, textureID); + + //glPixelStorei (GL_UNPACK_ALIGNMENT, 1); + + // NOTE : Making some assumptions about texture parameters + //glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + //glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); + glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + + glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + + //printf("w: %i, h: %i, RGBA: %i, pixels: %p\n", + // texture->w, texture->h, GL_RGBA, texture->pixels); + //printf("Pitch: %i, Bpp: %i\n", texture->pitch, texture->format->BytesPerPixel); + + if (texture->format->BytesPerPixel == 3){ + /*gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, + texture->w, + texture->h, + GL_RGB, GL_UNSIGNED_BYTE, + texture->pixels);*/ + glTexImage2D(GL_TEXTURE_2D, 0, 3, texture->w, texture->h, 0, GL_RGB, GL_UNSIGNED_BYTE, texture->pixels); + } + else if (texture->format->BytesPerPixel == 4){ + /*gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, + texture->w, + texture->h, + GL_RGBA, GL_UNSIGNED_BYTE, + texture->pixels);*/ + glTexImage2D(GL_TEXTURE_2D, 0, 4, texture->w, texture->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture->pixels); + } + +/* + + + gluBuild2DMipmaps(GL_TEXTURE_2D, + 0, + texture->w, + texture->h, + GL_RGBA, + GL_UNSIGNED_BYTE, + texture->pixels); + */ + SDL_FreeSurface(texture); + return textureID; +} + +int GraphicsDruid::loadTranspTexture(char* path, float* transpColor, int id){ + + SDL_Surface* texture; + texture = IMG_Load(path); + if (!texture){ +#ifdef _DEBUG + printf ("Error while loading image: %s\n", SDL_GetError()); +#endif + return -1; + } + + + Uint32 colorKey = SDL_MapRGB(texture->format, + (Uint8)(transpColor[0] * 255), + (Uint8)(transpColor[1] * 255), + (Uint8)(transpColor[2] * 255)); + //SDL_SetAlpha(texture, 0, SDL_ALPHA_OPAQUE); + + SDL_SetColorKey(texture, SDL_SRCCOLORKEY, colorKey); + + //SDL_Surface* alphaSurface = SDL_DisplayFormatAlpha(texture); + texture = SDL_DisplayFormatAlpha(texture); + + return loadTexture(texture); +} + +int GraphicsDruid::getNewTextureID(int id){ + + if (id != -1){ + for (int i = 0; i < instance->reserved; i++){ + if (instance->idArray[i] == id){ + freeTexture(id); + instance->textureCount--; + break; + } + } + } + + GLuint newId; + + if (id == -1){ + glGenTextures (1, &newId); + } + else + newId = id; + + int index = 0; + while (instance->idArray[index] != -1 && index < instance->reserved){ + index++; + } + + // out of space, make more + if (index >= instance->reserved){ + instance->idArray = (int*) realloc(instance->idArray, (instance->reserved + ID_ARRAY_GROW)*sizeof(int)); + + for (int i = instance->reserved + 1; i < instance->reserved + ID_ARRAY_GROW; i++) + instance->idArray[i] = -1; + + instance->reserved += ID_ARRAY_GROW; + } + else + instance->idArray[index] = newId; + + + instance->textureCount++; + return newId; +} + +void GraphicsDruid::freeTexture(int id){ + if (id > -1 && id < instance->reserved){ + instance->idArray[id] = -1; + const unsigned int helpInt = id; + glDeleteTextures(1, &helpInt); + } +} + diff --git a/src/graphics.h b/src/graphics.h index 0aad030..f267306 100644 --- a/src/graphics.h +++ b/src/graphics.h @@ -1,54 +1,54 @@ -#ifndef __GRAPHICS_H_INCLUDED__ -#define __GRAPHICS_H_INCLUDED__ - -#ifdef WIN32 -#pragma warning ( disable : 4700 ) -#endif - -#include "main.h" -#include "texture.h" -#include "glapi.h" - -const int ID_ARRAY_INIT_SIZE = 16; -const int ID_ARRAY_GROW = 8; - -#define DRUID GraphicsDruid::getInstance() -#define DIE_DRUID_DIE GraphicsDruid::destroy() -typedef unsigned char byte; -typedef struct jpeg_pixel{ - Uint8 red; - Uint8 green; - Uint8 blue; -}jpeg_pixel; - - - -class GraphicsDruid{ - -private: - - static GraphicsDruid* instance; - int* idArray; - int textureCount; - int reserved; - - GraphicsDruid(void); - ~GraphicsDruid(void); - - static void init(void); - static void destroy(void); - -public: - - static GraphicsDruid &getInstance(void); - int loadTexture(SDL_Surface *texture, int id = -1, int format = GL_RGB); - int loadTexture(char* path, int id = -1); - int loadTranspTexture(char* path, float* transpColor, int id = -1); - void freeTexture(int id); - void freeAll(void); - int getNewTextureID(int id); - -}; - -#endif - +#ifndef __GRAPHICS_H_INCLUDED__ +#define __GRAPHICS_H_INCLUDED__ + +#ifdef WIN32 +#pragma warning ( disable : 4700 ) +#endif + +#include "main.h" +#include "texture.h" +#include "glapi.h" + +const int ID_ARRAY_INIT_SIZE = 16; +const int ID_ARRAY_GROW = 8; + +#define DRUID GraphicsDruid::getInstance() +#define DIE_DRUID_DIE GraphicsDruid::destroy() +typedef unsigned char byte; +typedef struct jpeg_pixel{ + Uint8 red; + Uint8 green; + Uint8 blue; +}jpeg_pixel; + + + +class GraphicsDruid{ + +private: + + static GraphicsDruid* instance; + int* idArray; + int textureCount; + int reserved; + + GraphicsDruid(void); + ~GraphicsDruid(void); + + static void init(void); + static void destroy(void); + +public: + + static GraphicsDruid &getInstance(void); + int loadTexture(SDL_Surface *texture, int id = -1, int format = GL_RGB); + int loadTexture(char* path, int id = -1); + int loadTranspTexture(char* path, float* transpColor, int id = -1); + void freeTexture(int id); + void freeAll(void); + int getNewTextureID(int id); + +}; + +#endif + diff --git a/src/legoblocks.cpp b/src/legoblocks.cpp index 63882c6..bd0afb8 100644 --- a/src/legoblocks.cpp +++ b/src/legoblocks.cpp @@ -1,450 +1,450 @@ -#include "main.h" - -#include - -#include "legoblocks.h" -#include "utils.h" -#include "3dutils.h" -#include "objectfactory.h" -#include "vector.h" -#include "glapi.h" - -BasicBlock::BasicBlock(int width, int height, int depth) : MeshObject(createBox(-width/2.0, width/2.0, -height/2.0*BLOCKHEIGHT, BLOCKHEIGHT*height/2.0, -depth/2.0, depth/2.0)){ - appearance = new BasicBlockAppearance(width, height, depth); - //geometry = new MeshShape(this); -} - -void BasicBlock::setColor(float red, float green, float blue){ - appearance->getMaterial()->setColor(red, green, blue, 1); -} - - - -BasicBlockAppearance::BasicBlockAppearance(int width, int height, int depth){ - this->width = width; - this->height = height; - this->depth = depth; - vectorSet(displacement, 0, 0, 0); - gllist = glGenLists(1); - usematerial = true; -} - -void BasicBlockAppearance::prepare(){ - glNewList(gllist, GL_COMPILE); - - - float width = this->width; - float height = this->height * BLOCKHEIGHT; - - if (usematerial) material.enable(); - {//Block - //Front Face - glPushMatrix(); - glTranslatef(-width/2.0, -height/2.0, depth/2.0); - drawDetailRectangle(width, height); - glPopMatrix(); - - // Back Face - glPushMatrix(); - glTranslatef(width/2.0, -height/2.0, -depth/2.0); - glRotatef(180, 0, 1, 0); - drawDetailRectangle(width, height); - glPopMatrix(); - - // Top Face - glPushMatrix(); - glTranslatef(-width/2.0, height/2.0, depth/2.0); - glRotatef(-90, 1, 0, 0); - drawDetailRectangle(width, depth); - glPopMatrix(); - - // Bottom Face - glPushMatrix(); - glTranslatef(-width/2.0, -height/2.0, -depth/2.0); - glRotatef(90, 1, 0, 0); - drawDetailRectangle(width, depth); - glPopMatrix(); - - // Right face - glPushMatrix(); - glTranslatef(width/2.0, -height/2.0, depth/2.0); - glRotatef(90, 0, 1, 0); - drawDetailRectangle(depth, height); - glPopMatrix(); - - // Left Face - glPushMatrix(); - glTranslatef(-width/2.0, -height/2.0, -depth/2.0); - glRotatef(-90, 0, 1, 0); - drawDetailRectangle(depth, height); - glPopMatrix(); - } - - glPushMatrix(); - glTranslatef(0.5 - width/2.0, height - height/2.0, 0.5 - depth/2.0); - int x, z; - for (x = 0; x < width; x++){ - //glPushMatrix(); - for (z = 0; z < depth; z++){ - createKnob(); - glTranslatef(0, 0, 1); - } - glTranslatef(1, 0, -depth); - //glPopMatrix(); - } - glPopMatrix(); - - if (usematerial) material.disable(); - glEndList(); -} - -void BasicBlockAppearance::draw(){ - glPushMatrix(); - glTranslatef(displacement[0], displacement[1], displacement[2]); - glCallList(gllist); - glPopMatrix(); - //prepare(); -} - - -#define BLOCKDETAILGRID 1 - -void drawDetailRectangle(float width, float height){ - glBegin(GL_QUADS); - float x, y, x2, y2; - glNormal3f(0, 0, 1); - - for (y = 0; y < height; y += BLOCKDETAILGRID){ - y2 = y + BLOCKDETAILGRID; - if (y2 > height) y2 = height; - for (x = 0; x < width; x += BLOCKDETAILGRID){ - x2 = x + BLOCKDETAILGRID; - if (x2 > width) x2 = width; - - glTexCoord2f(x / width, y / height); - glVertex3f(x, y, 0); - - glTexCoord2f(x2 / width, y / height); - glVertex3f(x2, y, 0); - - glTexCoord2f(x2 / width, y2 / height); - glVertex3f(x2, y2, 0); - - glTexCoord2f(x / width, y2 / height); - glVertex3f(x, y2, 0); - } - } - glEnd(); -} - -#define KNOBROUNDNESS 0.03 - -int knobgllist; -int knobdetail; - -void renderKnob(int knobsegments){ - point2d knobpoints[4]; - knobpoints[0].x = 0.3; - knobpoints[0].y = 0; - knobpoints[1].x = 0.3; - knobpoints[1].y = BLOCKHEIGHT*0.5 - KNOBROUNDNESS; - knobpoints[2].x = 0.3 - KNOBROUNDNESS; - knobpoints[2].y = BLOCKHEIGHT*0.5; - knobpoints[3].x = 0; - knobpoints[3].y = BLOCKHEIGHT*0.5; - - point2d knobderivates[4]; - knobderivates[0].x = 0; - knobderivates[0].y = knobpoints[1].y - knobpoints[0].y; - knobderivates[1].x = 0; - knobderivates[1].y = knobpoints[2].y - knobpoints[1].y; - knobderivates[2].x = knobpoints[2].x - knobpoints[1].x; - knobderivates[2].y = 0; - knobderivates[3].x = knobpoints[3].x - knobpoints[2].x; - knobderivates[3].y = 0; - - createLathedSurface(knobpoints, knobderivates, 4, knobsegments, 4); -} - -void initKnob(void){ - glNewList(knobgllist, GL_COMPILE); - - renderKnob(knobdetail); - - glEndList(); -} - -void createKnob(int knobsegments){ - if (knobsegments != -1){ - renderKnob(knobsegments); - return; - } - glCallList(knobgllist); -} - - - - - -float knobroundness=0.05; -float pillarroundness=0.03; - -HeadAppearance::HeadAppearance(void){ - gllist = glGenLists(1); -} - -void HeadAppearance::prepare(void){ - glNewList(gllist, GL_COMPILE); - - glPushMatrix(); - - glTranslatef(0, -0.5, 0); - - point2d headpoints[14]; - - headpoints[0].x=0.0; headpoints[0].y=BLOCKHEIGHT*(0); - headpoints[1].x=0.4; headpoints[1].y=BLOCKHEIGHT*(0); - headpoints[2].x=0.45; headpoints[2].y=BLOCKHEIGHT*(0.35); - headpoints[3].x=0.55; headpoints[3].y=BLOCKHEIGHT*(0.5); - headpoints[4].x=0.62*1.0; headpoints[4].y=BLOCKHEIGHT*(0.65); - headpoints[5].x=0.65*1.0; headpoints[5].y=BLOCKHEIGHT*(1); - headpoints[6].x=0.65*1.0; headpoints[6].y=BLOCKHEIGHT*(1.75); - headpoints[7].x=0.65*1.0; headpoints[7].y=BLOCKHEIGHT*(2.35); - headpoints[8].x=0.62*1.0; headpoints[8].y=BLOCKHEIGHT*(2.60); - headpoints[9].x=0.55*1.0; headpoints[9].y=BLOCKHEIGHT*(2.80); - headpoints[10].x=0.4; headpoints[10].y=BLOCKHEIGHT*(2.95); - headpoints[11].x=0.3; headpoints[11].y=BLOCKHEIGHT*3.5-pillarroundness; - headpoints[12].x=0.3-pillarroundness; headpoints[12].y=BLOCKHEIGHT*3.5; - headpoints[13].x=0; headpoints[13].y=BLOCKHEIGHT*3.5; - headpoints[11].x=0; headpoints[11].y=BLOCKHEIGHT*3.0; - - glColor4f(0.8,0.8,0.0,1.0); - - - faceTexture->enable(); - glBlendFunc(GL_ONE, GL_SRC_ALPHA); - createLathedSurface(headpoints,NULL,12,16,24); - faceTexture->disable(); - - glTranslatef(0, BLOCKHEIGHT*3-0.05, 0); - - createKnob(16); - - glPopMatrix(); - - glEndList(); -} - -void HeadAppearance::draw(void){ - glCallList(gllist); -} - - - - - -FlowerAppearance::FlowerAppearance(int color1, int color2, int color3){ - gllist = glGenLists(1); - this->color1 = color1; - this->color2 = color2; - this->color3 = color3; -} - -void FlowerAppearance::prepare(void){ - glNewList(gllist, GL_COMPILE); - - glPushMatrix(); - - - int colors[]={color1,color2,color3}; - - glColor3f(0.0,0.6,0.0); - - point2d basepoints[8]; - basepoints[0].x=0.4; basepoints[0].y=0; - basepoints[1].x=0.4; basepoints[1].y=BLOCKHEIGHT*1.5-pillarroundness; - basepoints[2].x=0.4-pillarroundness; basepoints[2].y=BLOCKHEIGHT*1.5; - basepoints[3].x=0.3+pillarroundness; basepoints[3].y=BLOCKHEIGHT*1.5; - basepoints[4].x=0.3; basepoints[4].y=BLOCKHEIGHT*1.5+pillarroundness; - basepoints[5].x=0.3; basepoints[5].y=BLOCKHEIGHT*2.0-pillarroundness; - basepoints[6].x=0.3-pillarroundness; basepoints[6].y=BLOCKHEIGHT*2.0; - basepoints[7].x=0; basepoints[7].y=BLOCKHEIGHT*2.0; - - point2d basederivates[8]; - basederivates[0].x=0; basederivates[0].y=basepoints[1].y-basepoints[0].y; - basederivates[1].x=0; basederivates[1].y=basepoints[2].y-basepoints[1].y; - basederivates[2].x=basepoints[2].x-basepoints[1].x; basederivates[2].y=0; - basederivates[3].x=basepoints[4].x-basepoints[3].x; basederivates[3].y=0; - basederivates[4].x=0; basederivates[4].y=basepoints[4].y-basepoints[3].y; - basederivates[5].x=0; basederivates[5].y=basepoints[6].y-basepoints[5].y; - basederivates[6].x=basepoints[6].x-basepoints[5].x; basederivates[6].y=0; - basederivates[7].x=basepoints[7].x-basepoints[6].x; basederivates[7].y=0; - - createLathedSurface(basepoints,basederivates,8,8,8); - - int i,j; - for (i=0;i<3;i++){ - glColor3f(0.0,0.6,0.0); - glPushMatrix(); - glTranslatef(0,BLOCKHEIGHT,0.4); - glRotatef(20-90,1,0,0); - gluCylinder(gluNewQuadric(),0.1,0.1,BLOCKHEIGHT*(3+i*0.7),4,1); - glRotatef(90,1,0,0); - glTranslatef(0,BLOCKHEIGHT*(3+i*0.7),0); - - float r,g,b; - switch(colors[i]){ - case FLOWER_RED: - r=1.0; g=0.0; b=0.0; - break; - case FLOWER_YELLOW: - r=1.0; g=1.0; b=0.0; - break; - case FLOWER_WHITE: - r=1.0; g=1.0; b=1.0; - break; - } - - glDisable(GL_CULL_FACE); - glColor3f(r,g,b); - createKnob(); - - /* Terälehdet tehdään triangle-fanilla */ - glBegin(GL_TRIANGLE_FAN); - glNormal3f(0.0,1.0,0.0); - glVertex3f(0.0,0.0,0.0); - float x,z; - for (j=0;j<24;j+=4){ - x=sin((j+0)*2*PI/24)*0.4; - z=cos((j+0)*2*PI/24)*0.4; - glVertex3f(x,0.0,z); - x=sin((j+1)*2*PI/24)*0.55; - z=cos((j+1)*2*PI/24)*0.55; - glVertex3f(x,0.0,z); - x=sin((j+2)*2*PI/24)*0.6; - z=cos((j+2)*2*PI/24)*0.6; - glVertex3f(x,0.0,z); - x=sin((j+3)*2*PI/24)*0.55; - z=cos((j+3)*2*PI/24)*0.55; - glVertex3f(x,0.0,z); - } - glVertex3f(0,0.0,0.4); - glEnd(); - glEnable(GL_CULL_FACE); - - glPopMatrix(); - - glRotatef(120,0,1,0); - } - - glPopMatrix(); - - glEndList(); -} - -void FlowerAppearance::draw(void){ - glCallList(gllist); -} - - - - - -LampAppearance::LampAppearance(void){ - gllist = glGenLists(1); -} - -void LampAppearance::prepare(void){ - glNewList(gllist, GL_COMPILE); - - glPushMatrix(); - - //glTranslatef(0, -1, 0); - - //glRotatef(180, 1, 0, 0); - - glDisable(GL_LIGHTING); - - point2d lightpoints[11]; - lightpoints[0].x=0.4; lightpoints[0].y=BLOCKHEIGHT*(0); - lightpoints[1].x=0.55; lightpoints[1].y=BLOCKHEIGHT*(0); - lightpoints[2].x=0.62; lightpoints[2].y=BLOCKHEIGHT*(0+0.15); - lightpoints[3].x=0.65; lightpoints[3].y=BLOCKHEIGHT*(0+0.5); - lightpoints[4].x=0.68; lightpoints[4].y=BLOCKHEIGHT*(0+1.25); - lightpoints[5].x=0.65; lightpoints[5].y=BLOCKHEIGHT*(0+2); - lightpoints[6].x=0.62; lightpoints[6].y=BLOCKHEIGHT*(0+2.35); - lightpoints[7].x=0.55; lightpoints[7].y=BLOCKHEIGHT*(0+2.5); - lightpoints[8].x=0.4; lightpoints[8].y=BLOCKHEIGHT*(0+2.5); - lightpoints[9].x=0.4; lightpoints[9].y=BLOCKHEIGHT*(0+3); - lightpoints[10].x=0.0; lightpoints[10].y=BLOCKHEIGHT*(0+3); - glColor4f(0.8,0.8,0.8,0.5); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); - - createLathedSurface(lightpoints,NULL,11,8,11); - - glEnable(GL_LIGHTING); - - /*glColor3f(0.5, 0.5, 0.5); - - glBegin(GL_LINES); - glVertex3f(0, 1, 0); - glVertex3f(0, -100, 0); - glEnd();*/ - - - /*float screencoords[3] - getPointCoordinates(0,lighty,0); - - glLoadIdentity(); - glTranslatef(screencoords.x,screencoords.y,0); - glDisable(GL_DEPTH_TEST); - glEnable(GL_CULL_FACE); - glEnable(GL_BLEND); - - glBlendFunc(GL_ONE,GL_ONE); - glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D,*flaretexture); - - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - float sizey=8.0/distance*staticlightflarebrightnesses[lightnumber]; - float sizex=sizey*height/width; - - if (distance>0.5){ - glBegin(GL_QUADS); - glColor3f(staticlightflarebrightnesses[lightnumber],staticlightflarebrightnesses[lightnumber],staticlightflarebrightnesses[lightnumber]); - - glTexCoord2f(0.0, 0.0); - glVertex2f(-sizex,sizey); - - glTexCoord2f(0.0, 1.0); - glVertex2f(-sizex,-sizey); - - glTexCoord2f(1.0, 1.0); - glVertex2f( sizex,-sizey); - - glTexCoord2f(1.0, 0.0); - glVertex2f( sizex,sizey); - glEnd(); - } - - glDisable(GL_TEXTURE_2D); - - glDisable(GL_BLEND); - - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity();*/ - - - - glPopMatrix(); - - glEndList(); -} - -void LampAppearance::draw(void){ - glCallList(gllist); -} +#include "main.h" + +#include + +#include "legoblocks.h" +#include "utils.h" +#include "3dutils.h" +#include "objectfactory.h" +#include "vector.h" +#include "glapi.h" + +BasicBlock::BasicBlock(int width, int height, int depth) : MeshObject(createBox(-width/2.0, width/2.0, -height/2.0*BLOCKHEIGHT, BLOCKHEIGHT*height/2.0, -depth/2.0, depth/2.0)){ + appearance = new BasicBlockAppearance(width, height, depth); + //geometry = new MeshShape(this); +} + +void BasicBlock::setColor(float red, float green, float blue){ + appearance->getMaterial()->setColor(red, green, blue, 1); +} + + + +BasicBlockAppearance::BasicBlockAppearance(int width, int height, int depth){ + this->width = width; + this->height = height; + this->depth = depth; + vectorSet(displacement, 0, 0, 0); + gllist = glGenLists(1); + usematerial = true; +} + +void BasicBlockAppearance::prepare(){ + glNewList(gllist, GL_COMPILE); + + + float width = this->width; + float height = this->height * BLOCKHEIGHT; + + if (usematerial) material.enable(); + {//Block + //Front Face + glPushMatrix(); + glTranslatef(-width/2.0, -height/2.0, depth/2.0); + drawDetailRectangle(width, height); + glPopMatrix(); + + // Back Face + glPushMatrix(); + glTranslatef(width/2.0, -height/2.0, -depth/2.0); + glRotatef(180, 0, 1, 0); + drawDetailRectangle(width, height); + glPopMatrix(); + + // Top Face + glPushMatrix(); + glTranslatef(-width/2.0, height/2.0, depth/2.0); + glRotatef(-90, 1, 0, 0); + drawDetailRectangle(width, depth); + glPopMatrix(); + + // Bottom Face + glPushMatrix(); + glTranslatef(-width/2.0, -height/2.0, -depth/2.0); + glRotatef(90, 1, 0, 0); + drawDetailRectangle(width, depth); + glPopMatrix(); + + // Right face + glPushMatrix(); + glTranslatef(width/2.0, -height/2.0, depth/2.0); + glRotatef(90, 0, 1, 0); + drawDetailRectangle(depth, height); + glPopMatrix(); + + // Left Face + glPushMatrix(); + glTranslatef(-width/2.0, -height/2.0, -depth/2.0); + glRotatef(-90, 0, 1, 0); + drawDetailRectangle(depth, height); + glPopMatrix(); + } + + glPushMatrix(); + glTranslatef(0.5 - width/2.0, height - height/2.0, 0.5 - depth/2.0); + int x, z; + for (x = 0; x < width; x++){ + //glPushMatrix(); + for (z = 0; z < depth; z++){ + createKnob(); + glTranslatef(0, 0, 1); + } + glTranslatef(1, 0, -depth); + //glPopMatrix(); + } + glPopMatrix(); + + if (usematerial) material.disable(); + glEndList(); +} + +void BasicBlockAppearance::draw(){ + glPushMatrix(); + glTranslatef(displacement[0], displacement[1], displacement[2]); + glCallList(gllist); + glPopMatrix(); + //prepare(); +} + + +#define BLOCKDETAILGRID 1 + +void drawDetailRectangle(float width, float height){ + glBegin(GL_QUADS); + float x, y, x2, y2; + glNormal3f(0, 0, 1); + + for (y = 0; y < height; y += BLOCKDETAILGRID){ + y2 = y + BLOCKDETAILGRID; + if (y2 > height) y2 = height; + for (x = 0; x < width; x += BLOCKDETAILGRID){ + x2 = x + BLOCKDETAILGRID; + if (x2 > width) x2 = width; + + glTexCoord2f(x / width, y / height); + glVertex3f(x, y, 0); + + glTexCoord2f(x2 / width, y / height); + glVertex3f(x2, y, 0); + + glTexCoord2f(x2 / width, y2 / height); + glVertex3f(x2, y2, 0); + + glTexCoord2f(x / width, y2 / height); + glVertex3f(x, y2, 0); + } + } + glEnd(); +} + +#define KNOBROUNDNESS 0.03 + +int knobgllist; +int knobdetail; + +void renderKnob(int knobsegments){ + point2d knobpoints[4]; + knobpoints[0].x = 0.3; + knobpoints[0].y = 0; + knobpoints[1].x = 0.3; + knobpoints[1].y = BLOCKHEIGHT*0.5 - KNOBROUNDNESS; + knobpoints[2].x = 0.3 - KNOBROUNDNESS; + knobpoints[2].y = BLOCKHEIGHT*0.5; + knobpoints[3].x = 0; + knobpoints[3].y = BLOCKHEIGHT*0.5; + + point2d knobderivates[4]; + knobderivates[0].x = 0; + knobderivates[0].y = knobpoints[1].y - knobpoints[0].y; + knobderivates[1].x = 0; + knobderivates[1].y = knobpoints[2].y - knobpoints[1].y; + knobderivates[2].x = knobpoints[2].x - knobpoints[1].x; + knobderivates[2].y = 0; + knobderivates[3].x = knobpoints[3].x - knobpoints[2].x; + knobderivates[3].y = 0; + + createLathedSurface(knobpoints, knobderivates, 4, knobsegments, 4); +} + +void initKnob(void){ + glNewList(knobgllist, GL_COMPILE); + + renderKnob(knobdetail); + + glEndList(); +} + +void createKnob(int knobsegments){ + if (knobsegments != -1){ + renderKnob(knobsegments); + return; + } + glCallList(knobgllist); +} + + + + + +float knobroundness=0.05; +float pillarroundness=0.03; + +HeadAppearance::HeadAppearance(void){ + gllist = glGenLists(1); +} + +void HeadAppearance::prepare(void){ + glNewList(gllist, GL_COMPILE); + + glPushMatrix(); + + glTranslatef(0, -0.5, 0); + + point2d headpoints[14]; + + headpoints[0].x=0.0; headpoints[0].y=BLOCKHEIGHT*(0); + headpoints[1].x=0.4; headpoints[1].y=BLOCKHEIGHT*(0); + headpoints[2].x=0.45; headpoints[2].y=BLOCKHEIGHT*(0.35); + headpoints[3].x=0.55; headpoints[3].y=BLOCKHEIGHT*(0.5); + headpoints[4].x=0.62*1.0; headpoints[4].y=BLOCKHEIGHT*(0.65); + headpoints[5].x=0.65*1.0; headpoints[5].y=BLOCKHEIGHT*(1); + headpoints[6].x=0.65*1.0; headpoints[6].y=BLOCKHEIGHT*(1.75); + headpoints[7].x=0.65*1.0; headpoints[7].y=BLOCKHEIGHT*(2.35); + headpoints[8].x=0.62*1.0; headpoints[8].y=BLOCKHEIGHT*(2.60); + headpoints[9].x=0.55*1.0; headpoints[9].y=BLOCKHEIGHT*(2.80); + headpoints[10].x=0.4; headpoints[10].y=BLOCKHEIGHT*(2.95); + headpoints[11].x=0.3; headpoints[11].y=BLOCKHEIGHT*3.5-pillarroundness; + headpoints[12].x=0.3-pillarroundness; headpoints[12].y=BLOCKHEIGHT*3.5; + headpoints[13].x=0; headpoints[13].y=BLOCKHEIGHT*3.5; + headpoints[11].x=0; headpoints[11].y=BLOCKHEIGHT*3.0; + + glColor4f(0.8,0.8,0.0,1.0); + + + faceTexture->enable(); + glBlendFunc(GL_ONE, GL_SRC_ALPHA); + createLathedSurface(headpoints,NULL,12,16,24); + faceTexture->disable(); + + glTranslatef(0, BLOCKHEIGHT*3-0.05, 0); + + createKnob(16); + + glPopMatrix(); + + glEndList(); +} + +void HeadAppearance::draw(void){ + glCallList(gllist); +} + + + + + +FlowerAppearance::FlowerAppearance(int color1, int color2, int color3){ + gllist = glGenLists(1); + this->color1 = color1; + this->color2 = color2; + this->color3 = color3; +} + +void FlowerAppearance::prepare(void){ + glNewList(gllist, GL_COMPILE); + + glPushMatrix(); + + + int colors[]={color1,color2,color3}; + + glColor3f(0.0,0.6,0.0); + + point2d basepoints[8]; + basepoints[0].x=0.4; basepoints[0].y=0; + basepoints[1].x=0.4; basepoints[1].y=BLOCKHEIGHT*1.5-pillarroundness; + basepoints[2].x=0.4-pillarroundness; basepoints[2].y=BLOCKHEIGHT*1.5; + basepoints[3].x=0.3+pillarroundness; basepoints[3].y=BLOCKHEIGHT*1.5; + basepoints[4].x=0.3; basepoints[4].y=BLOCKHEIGHT*1.5+pillarroundness; + basepoints[5].x=0.3; basepoints[5].y=BLOCKHEIGHT*2.0-pillarroundness; + basepoints[6].x=0.3-pillarroundness; basepoints[6].y=BLOCKHEIGHT*2.0; + basepoints[7].x=0; basepoints[7].y=BLOCKHEIGHT*2.0; + + point2d basederivates[8]; + basederivates[0].x=0; basederivates[0].y=basepoints[1].y-basepoints[0].y; + basederivates[1].x=0; basederivates[1].y=basepoints[2].y-basepoints[1].y; + basederivates[2].x=basepoints[2].x-basepoints[1].x; basederivates[2].y=0; + basederivates[3].x=basepoints[4].x-basepoints[3].x; basederivates[3].y=0; + basederivates[4].x=0; basederivates[4].y=basepoints[4].y-basepoints[3].y; + basederivates[5].x=0; basederivates[5].y=basepoints[6].y-basepoints[5].y; + basederivates[6].x=basepoints[6].x-basepoints[5].x; basederivates[6].y=0; + basederivates[7].x=basepoints[7].x-basepoints[6].x; basederivates[7].y=0; + + createLathedSurface(basepoints,basederivates,8,8,8); + + int i,j; + for (i=0;i<3;i++){ + glColor3f(0.0,0.6,0.0); + glPushMatrix(); + glTranslatef(0,BLOCKHEIGHT,0.4); + glRotatef(20-90,1,0,0); + gluCylinder(gluNewQuadric(),0.1,0.1,BLOCKHEIGHT*(3+i*0.7),4,1); + glRotatef(90,1,0,0); + glTranslatef(0,BLOCKHEIGHT*(3+i*0.7),0); + + float r,g,b; + switch(colors[i]){ + case FLOWER_RED: + r=1.0; g=0.0; b=0.0; + break; + case FLOWER_YELLOW: + r=1.0; g=1.0; b=0.0; + break; + case FLOWER_WHITE: + r=1.0; g=1.0; b=1.0; + break; + } + + glDisable(GL_CULL_FACE); + glColor3f(r,g,b); + createKnob(); + + /* Terälehdet tehdään triangle-fanilla */ + glBegin(GL_TRIANGLE_FAN); + glNormal3f(0.0,1.0,0.0); + glVertex3f(0.0,0.0,0.0); + float x,z; + for (j=0;j<24;j+=4){ + x=sin((j+0)*2*PI/24)*0.4; + z=cos((j+0)*2*PI/24)*0.4; + glVertex3f(x,0.0,z); + x=sin((j+1)*2*PI/24)*0.55; + z=cos((j+1)*2*PI/24)*0.55; + glVertex3f(x,0.0,z); + x=sin((j+2)*2*PI/24)*0.6; + z=cos((j+2)*2*PI/24)*0.6; + glVertex3f(x,0.0,z); + x=sin((j+3)*2*PI/24)*0.55; + z=cos((j+3)*2*PI/24)*0.55; + glVertex3f(x,0.0,z); + } + glVertex3f(0,0.0,0.4); + glEnd(); + glEnable(GL_CULL_FACE); + + glPopMatrix(); + + glRotatef(120,0,1,0); + } + + glPopMatrix(); + + glEndList(); +} + +void FlowerAppearance::draw(void){ + glCallList(gllist); +} + + + + + +LampAppearance::LampAppearance(void){ + gllist = glGenLists(1); +} + +void LampAppearance::prepare(void){ + glNewList(gllist, GL_COMPILE); + + glPushMatrix(); + + //glTranslatef(0, -1, 0); + + //glRotatef(180, 1, 0, 0); + + glDisable(GL_LIGHTING); + + point2d lightpoints[11]; + lightpoints[0].x=0.4; lightpoints[0].y=BLOCKHEIGHT*(0); + lightpoints[1].x=0.55; lightpoints[1].y=BLOCKHEIGHT*(0); + lightpoints[2].x=0.62; lightpoints[2].y=BLOCKHEIGHT*(0+0.15); + lightpoints[3].x=0.65; lightpoints[3].y=BLOCKHEIGHT*(0+0.5); + lightpoints[4].x=0.68; lightpoints[4].y=BLOCKHEIGHT*(0+1.25); + lightpoints[5].x=0.65; lightpoints[5].y=BLOCKHEIGHT*(0+2); + lightpoints[6].x=0.62; lightpoints[6].y=BLOCKHEIGHT*(0+2.35); + lightpoints[7].x=0.55; lightpoints[7].y=BLOCKHEIGHT*(0+2.5); + lightpoints[8].x=0.4; lightpoints[8].y=BLOCKHEIGHT*(0+2.5); + lightpoints[9].x=0.4; lightpoints[9].y=BLOCKHEIGHT*(0+3); + lightpoints[10].x=0.0; lightpoints[10].y=BLOCKHEIGHT*(0+3); + glColor4f(0.8,0.8,0.8,0.5); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); + + createLathedSurface(lightpoints,NULL,11,8,11); + + glEnable(GL_LIGHTING); + + /*glColor3f(0.5, 0.5, 0.5); + + glBegin(GL_LINES); + glVertex3f(0, 1, 0); + glVertex3f(0, -100, 0); + glEnd();*/ + + + /*float screencoords[3] + getPointCoordinates(0,lighty,0); + + glLoadIdentity(); + glTranslatef(screencoords.x,screencoords.y,0); + glDisable(GL_DEPTH_TEST); + glEnable(GL_CULL_FACE); + glEnable(GL_BLEND); + + glBlendFunc(GL_ONE,GL_ONE); + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D,*flaretexture); + + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + float sizey=8.0/distance*staticlightflarebrightnesses[lightnumber]; + float sizex=sizey*height/width; + + if (distance>0.5){ + glBegin(GL_QUADS); + glColor3f(staticlightflarebrightnesses[lightnumber],staticlightflarebrightnesses[lightnumber],staticlightflarebrightnesses[lightnumber]); + + glTexCoord2f(0.0, 0.0); + glVertex2f(-sizex,sizey); + + glTexCoord2f(0.0, 1.0); + glVertex2f(-sizex,-sizey); + + glTexCoord2f(1.0, 1.0); + glVertex2f( sizex,-sizey); + + glTexCoord2f(1.0, 0.0); + glVertex2f( sizex,sizey); + glEnd(); + } + + glDisable(GL_TEXTURE_2D); + + glDisable(GL_BLEND); + + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity();*/ + + + + glPopMatrix(); + + glEndList(); +} + +void LampAppearance::draw(void){ + glCallList(gllist); +} diff --git a/src/legoblocks.h b/src/legoblocks.h index 572c84d..bd17b9a 100644 --- a/src/legoblocks.h +++ b/src/legoblocks.h @@ -1,91 +1,91 @@ -#ifndef __LEGOBLOCKS_H_INCLUDED__ -#define __LEGOBLOCKS_H_INCLUDED__ - -//#include "mesh.h" -#include "object.h" -#include "material.h" -#include "mesh.h" - -#define BLOCKHEIGHT 0.4 - -class BasicBlock : public MeshObject{ -private: - int width, height, depth; - -public: - BasicBlock(int width, int height, int depth); - - void setColor(float red, float green, float blue); -}; - - -class BasicBlockAppearance : public Appearance{ -private: - int width, height, depth; - int gllist; - -protected: - bool usematerial; - -public: - float displacement[3]; - - BasicBlockAppearance(int width, int height, int depth); - - virtual void prepare(void); - virtual void draw(void); -}; - -void drawDetailRectangle(float width, float height); - -extern int knobgllist; -extern int knobdetail; -void initKnob(void); -void createKnob(int knobsegments = -1); - - - -class HeadAppearance : public Appearance{ -private: - int gllist; - -public: - HeadAppearance(void); - - void prepare(void); - void draw(void); -}; - - - -#define FLOWER_RED 1 -#define FLOWER_YELLOW 2 -#define FLOWER_WHITE 3 - -class FlowerAppearance : public Appearance{ -private: - int gllist; - int color1, color2, color3; - -public: - FlowerAppearance(int color1, int color2, int color3); - - void prepare(void); - void draw(void); -}; - - - -class LampAppearance : public Appearance{ -private: - int gllist; - -public: - LampAppearance(void); - - void prepare(void); - void draw(void); -}; - - -#endif +#ifndef __LEGOBLOCKS_H_INCLUDED__ +#define __LEGOBLOCKS_H_INCLUDED__ + +//#include "mesh.h" +#include "object.h" +#include "material.h" +#include "mesh.h" + +#define BLOCKHEIGHT 0.4 + +class BasicBlock : public MeshObject{ +private: + int width, height, depth; + +public: + BasicBlock(int width, int height, int depth); + + void setColor(float red, float green, float blue); +}; + + +class BasicBlockAppearance : public Appearance{ +private: + int width, height, depth; + int gllist; + +protected: + bool usematerial; + +public: + float displacement[3]; + + BasicBlockAppearance(int width, int height, int depth); + + virtual void prepare(void); + virtual void draw(void); +}; + +void drawDetailRectangle(float width, float height); + +extern int knobgllist; +extern int knobdetail; +void initKnob(void); +void createKnob(int knobsegments = -1); + + + +class HeadAppearance : public Appearance{ +private: + int gllist; + +public: + HeadAppearance(void); + + void prepare(void); + void draw(void); +}; + + + +#define FLOWER_RED 1 +#define FLOWER_YELLOW 2 +#define FLOWER_WHITE 3 + +class FlowerAppearance : public Appearance{ +private: + int gllist; + int color1, color2, color3; + +public: + FlowerAppearance(int color1, int color2, int color3); + + void prepare(void); + void draw(void); +}; + + + +class LampAppearance : public Appearance{ +private: + int gllist; + +public: + LampAppearance(void); + + void prepare(void); + void draw(void); +}; + + +#endif diff --git a/src/legoman.cpp b/src/legoman.cpp index 71ddea1..f3491bf 100644 --- a/src/legoman.cpp +++ b/src/legoman.cpp @@ -1,1021 +1,1021 @@ -#include "main.h" - -#include - -#include "legoman.h" -#include "object.h" -#include "sphere.h" -#include "world.h" -#include "legoblocks.h" -#include "vector.h" -#include "collision.h" -#include "objectfactory.h" -#include "utils.h" -#include "particle.h" -#include "fight.h" -#include "glapi.h" - - - - -BodyPart::BodyPart(Legoman *parent, float strength){ - this->parent = parent; - this->strength = strength; - reset(); -} - -void BodyPart::reset(void){ - this->energy = 1; - this->attached = true; - this->immortal = 0; - vectorSet(position, 0, 0, 0); - vectorSet(momentum, 0, 0, 0); - matrixIdentity(rotation); - vectorSet(angularmomentum, 0, 0, 0); -} - -void BodyPart::move(void){ - if (immortal > 0) immortal--; - Object::move(); -} - -void BodyPart::hitForce(float speed, float *speed2, Object *source){ - if (parent->isHarmfulObject(source)){ - float tolerance = 0.3; - if (speed > tolerance){ - Sound *sound; - sound = hitsound1; - float volume = (speed-tolerance)*0.4; - if (volume > 1) volume = 1; - volume = 1; - sound->setVolume(volume); - sound->play(30 + random(120)); - - int i; - for (i = 0; i < (int)(speed-0.5); i++){ - float vel[3] = {randomf(2)-1, randomf(3), randomf(2)-1}; - vectorAdd(vel, speed2); - createBlood(position, vel); - } - - //makeDamage(0.1); - if (this == parent->head && source == parent->opponent->head){ - speed *= 0.1; - } - makeDamage(speed*0.1); - } - } else{ - Object::hitForce(speed, speed2, source); - } -} - -void BodyPart::makeDamage(float amount){ - if (strength == 0) return; - if (energy == 0) return; - if (!parent->opponent->isAlive()) return; - if (immortal > 0) return; - - energy -= amount/strength; - if (energy < 0) energy = 0; - if (energy == 0){ - parent->releasePart(this); - } - immortal = 30; -} - - -Sensor::Sensor(){ -} - -void Sensor::attach(Object *object, float *relativeposition){ - vectorCopy(this->relativeposition, relativeposition); - this->object = object; - update(); - update(); - update(); - update(); -} - -void Sensor::attach(Object *object){ - float position[3] = {0, 0, 0}; - attach(object, position); -} - -void Sensor::update(void){ - vectorCopy(oldposition, position); - vectorCopy(oldvelocity, velocity); - - object->transformPoint(position, relativeposition); - - vectorSub(velocity, position, oldposition); - vectorSub(acceleration, velocity, oldvelocity); - - //printf("V: %f, %f, %f\n", velocity[0], velocity[1], velocity[2]); -} - -void Sensor::getPosition(float *target){ - vectorCopy(target, position); -} - -void Sensor::getVelocity(float *target){ - vectorCopy(target, velocity); -} - -void Sensor::getAcceleration(float *target){ - vectorCopy(target, acceleration); -} - -//float rightHandOffset[3] = {-0.60, 0.45, 0.0}; -float rightHandOffset[3] = {-0.40, 0.45, 0.0}; -//float leftHandOffset[3] = {0.60, 0.46, 0.0}; -float leftHandOffset[3] = {0.40, 0.46, 0.0}; -//float leftPalmOffset[3] = {0.28, -0.3, -0.38}; -float leftPalmOffset[3] = {0.08, -0.3, -0.38}; -//float rightPalmOffset[3] = {-0.30, -0.3, -0.38}; -float rightPalmOffset[3] = {-0.10, -0.3, -0.38}; -float waistOffset[3] = {0.0, 0.2, 0.0}; -float rightLegOffset[3] = {-0.15, 0.4, 0.0}; -float leftLegOffset[3] = {0.1, 0.4, 0.0}; - -Legoman::Legoman(int side){ - this->side = side; - - int collisiongroup, collisiongrouphand; - if (side == PLAYER1){ - collisiongroup = COLLISIONGROUP_MAN1; - collisiongrouphand = COLLISIONGROUP_MAN1HAND; - } - if (side == PLAYER2){ - collisiongroup = COLLISIONGROUP_MAN2; - collisiongrouphand = COLLISIONGROUP_MAN2HAND; - } - - float torsocolor[3], legcolor[3]; - - if (side == PLAYER1){ - vectorSet(torsocolor, 1, 0, 0); - vectorSet(legcolor, 0, 0, 1); - } else if (side == PLAYER2){ - vectorSet(torsocolor, 0, 0, 1); - vectorSet(legcolor, 1, 0, 0); - } - - //Legs - Mesh* geomLegMesh = createBox(-0.45, 0.45, -BLOCKHEIGHT*LEGHEIGHT/2.0, BLOCKHEIGHT*LEGHEIGHT/2.0, -0.5, 0.5); - float tmpScale = 1.0; - - //Left leg - { - leftleg = new BodyPart(this, 8); - Mesh* leftLegMesh = loadAscModel((char*)LEFTLEGASC, MODELSCALE, leftLegOffset); - MeshShape *leftLegGeom = new MeshShape(leftleg, geomLegMesh); - leftleg->geometry = leftLegGeom; - leftleg->appearance = new MeshAppearance(leftLegMesh); - //leftleg->appearance = new MeshAppearance(geomLegMesh); - leftleg->appearance->material.setColor(legcolor[0], legcolor[1], legcolor[2], 1); - vectorSet(leftleg->position, -0.6, BLOCKHEIGHT*(LEGHEIGHT/2.0), 0); - leftleg->setGravity(true); - leftleg->setMass(LEGHEIGHT/3.0); - leftleg->setCollisionGroup(collisiongroup); - } - - //Right leg - { - rightleg = new BodyPart(this, 8); - Mesh* rightLegMesh = loadAscModel((char*)RIGHTLEGASC, MODELSCALE, rightLegOffset); - MeshShape *rightLegGeom = new MeshShape(rightleg, geomLegMesh); - rightleg->geometry = rightLegGeom; - rightleg->appearance = new MeshAppearance(rightLegMesh); - //rightleg->appearance = new MeshAppearance(geomLegMesh); - rightleg->appearance->material.setColor(legcolor[0], legcolor[1], legcolor[2], 1); - vectorSet(rightleg->position, 0.6, BLOCKHEIGHT*(LEGHEIGHT/2.0), 0); - rightleg->setGravity(true); - rightleg->setMass(LEGHEIGHT/3.0); - rightleg->setCollisionGroup(collisiongroup); - } - - - //Waist - { - waist = new BodyPart(this, 0); - Mesh* waistMesh = loadAscModel((char*)WAISTASC, MODELSCALE, waistOffset); - MeshAppearance* waistappearance = new MeshAppearance(waistMesh); - waistappearance->material.setColor(0, 1, 0, 1); - - Mesh *waistGeomMesh = createBox(-1 + 0.1, 1 - 0.1, 0, BLOCKHEIGHT*WAISTHEIGHT/2.0, 0.1, 0.4); - MeshShape *waistgeometry = new MeshShape(waist, waistGeomMesh); - waist->geometry = waistgeometry; - waist->appearance = waistappearance; - //waist->appearance = new MeshAppearance(waistGeomMesh); - vectorSet(waist->position, 0, BLOCKHEIGHT*(LEGHEIGHT + WAISTHEIGHT/2.0), 0); - waist->setGravity(true); - waist->setMass(2*WAISTHEIGHT/3.0); - waist->setCollisionGroup(collisiongroup); - } - - - //Torso - { - torso = new BodyPart(this, 4); - Mesh* torsoMesh = loadAscModel((char*)TORSOASC, TORSOSCALE); - //int i; - //for (i = 0; i < torsoMesh->polygoncount; i++) torsoMesh->polygons[i].smooth = false; - MeshAppearance* torsoAppearance = new MeshAppearance(torsoMesh); - torsoAppearance->material.setColor(torsocolor[0], torsocolor[1], torsocolor[2], 1); - Mesh *torsoGeomMesh = createBox(-1, 1, -BLOCKHEIGHT*TORSOHEIGHT/2.0, BLOCKHEIGHT*TORSOHEIGHT/2.0, -0.5, 0.5); - MeshShape *torsogeometry = new MeshShape(torso, torsoGeomMesh); - torso->geometry = torsogeometry; - torso->appearance = torsoAppearance; - //torso->appearance = new MeshAppearance(torsoGeomMesh); - vectorSet(torso->position, 0, BLOCKHEIGHT*(LEGHEIGHT + WAISTHEIGHT + TORSOHEIGHT/2.0), 0); - torso->setGravity(true); - torso->setMass(2*TORSOHEIGHT/3.0); - torso->setCollisionGroup(collisiongroup); - } - - - //Hands - //Mesh *handMeshGeom = createBox(-0.4, 0.4, -BLOCKHEIGHT*HANDHEIGHT/2.0, BLOCKHEIGHT*HANDHEIGHT/2.0, -0.5, 0.5); - Mesh *handMeshGeom = createBox(-0.2, 0.2, -BLOCKHEIGHT*HANDHEIGHT/2.0, BLOCKHEIGHT*HANDHEIGHT/2.0, -0.5, 0.5); - - - //Left hand - { - lefthand = new BodyPart(this, 5); - - Mesh* leftHandMesh = loadAscModel((char*)LEFTARMASC, MODELSCALE, leftHandOffset); - Mesh* leftPalmMesh = loadAscModel((char*)LEFTPALMASC, MODELSCALE, leftPalmOffset); - MultiAppearance *a = new MultiAppearance(); - Appearance *arm = new MeshAppearance(leftHandMesh); - Appearance *palm = new MeshAppearance(leftPalmMesh); - arm->material.setColor(torsocolor[0], torsocolor[1], torsocolor[2], 1); - palm->material.setColor(1, 1, 0, 1); - a->addAppearance(arm); - a->addAppearance(palm); - MeshShape *lefthandgeometry = new MeshShape(lefthand, handMeshGeom); - lefthand->geometry = lefthandgeometry; - lefthand->appearance = a;//new MeshAppearance(leftHandMesh); - //lefthand->appearance = new MeshAppearance(handMeshGeom); - //lefthand->appearance->material.setColor(1, 0, 0, 1); - vectorSet(lefthand->position, -1.3, BLOCKHEIGHT*(LEGHEIGHT + WAISTHEIGHT + TORSOHEIGHT - HANDHEIGHT/2.0), 0); - lefthand->setGravity(true); - lefthand->setMass(HANDHEIGHT/3.0); - lefthand->setCollisionGroup(collisiongrouphand); - } - - //Right hand - { - righthand = new BodyPart(this, 5); - Mesh* rightHandMesh = loadAscModel((char*)RIGHTARMASC, MODELSCALE, rightHandOffset); - Mesh* rightPalmMesh = loadAscModel((char*)RIGHTPALMASC, MODELSCALE, rightPalmOffset); - MultiAppearance *a = new MultiAppearance(); - Appearance *arm = new MeshAppearance(rightHandMesh); - arm->material.setColor(torsocolor[0], torsocolor[1], torsocolor[2], 1); - Appearance *palm = new MeshAppearance(rightPalmMesh); - palm->material.setColor(1, 1, 0, 1); - a->addAppearance(arm); - a->addAppearance(palm); - MeshShape *righthandgeometry = new MeshShape(righthand, handMeshGeom); - righthand->geometry = righthandgeometry; - righthand->appearance = a; - //righthand->appearance = new MeshAppearance(handMeshGeom); - vectorSet(righthand->position, 1.3, BLOCKHEIGHT*(LEGHEIGHT + WAISTHEIGHT + TORSOHEIGHT - HANDHEIGHT/2.0), 0); - righthand->setGravity(true); - righthand->setMass(HANDHEIGHT/3.0); - righthand->setCollisionGroup(collisiongrouphand); - } - - - //Head - { - head = new BodyPart(this, 2); - Appearance *headappearance = new HeadAppearance(); - float r = BLOCKHEIGHT*HEADHEIGHT/2; - /*SphereAppearance *headappearance = new SphereAppearance(); - headappearance->setRadius(r); - headappearance->material.setColor(1, 1, 0, 1);*/ - SphereShape *headgeometry = new SphereShape(head); - headgeometry->setRadius(r); - head->geometry = headgeometry; - head->appearance = headappearance; - vectorSet(head->position, 0, BLOCKHEIGHT*(LEGHEIGHT + WAISTHEIGHT + TORSOHEIGHT + HEADHEIGHT/2 + 0.5), 0); - head->setGravity(true); - head->setMass(4.0/3*PI*r*r*r); - head->setCollisionGroup(collisiongroup); - } - - - headsensor = new Sensor(); - torsosensor = new Sensor(); - - - - headvisual = new DamageVisual(head, damageHead, false, - -0.5, -2, 0.5, -1); - - torsovisual = new DamageVisual(torso, damageTorso, false, - -0.5, -1, 0.5, 0); - - lefthandvisual = new DamageVisual(lefthand, damageHand, true, - 0.4, -1, 0.9, 0); - - righthandvisual = new DamageVisual(righthand, damageHand, true, - -0.4, -1, -0.9, 0); - - leftlegvisual = new DamageVisual(leftleg, damageLeg, true, - 0, 0, 0.5, 1); - - rightlegvisual = new DamageVisual(rightleg, damageLeg, true, - -0, 0, -0.5, 1); - - - harmfulobjects = NULL; - - - walkphase = 0; - jumpphase = 0; - hitside = 0; - - alive = true; -} - -void Legoman::insertToWorld(World *world){ - this->world = world; - - - world->addChild(rightleg); - world->addChild(leftleg); - world->addChild(waist); - world->addChild(torso); - world->addChild(lefthand); - world->addChild(righthand); - world->addChild(head); - float linkpoint[3]; - - vectorSet(linkpoint, 0, BLOCKHEIGHT*(LEGHEIGHT + WAISTHEIGHT + TORSOHEIGHT + HEADHEIGHT), 0); - headlinks[0] = world->addLink(head, torso, linkpoint); - - vectorSet(linkpoint, 0, BLOCKHEIGHT*(LEGHEIGHT + WAISTHEIGHT + TORSOHEIGHT), 0); - headlinks[1] = world->addLink(head, torso, linkpoint); - - vectorSet(linkpoint, 0, BLOCKHEIGHT*(LEGHEIGHT + WAISTHEIGHT + TORSOHEIGHT + HEADHEIGHT*0.5), 1); - headlinks[2] = world->addLink(head, torso, linkpoint); - - head->attached = true; - - - vectorSet(linkpoint, -1, BLOCKHEIGHT*(LEGHEIGHT + WAISTHEIGHT + TORSOHEIGHT) - 0.5, 0); - lefthandlinks[0] = world->addLink(torso, lefthand, linkpoint); - - vectorSet(linkpoint, -2, BLOCKHEIGHT*(LEGHEIGHT + WAISTHEIGHT + TORSOHEIGHT) - 0.5, 0); - lefthandlinks[1] = world->addLink(torso, lefthand, linkpoint); - - lefthand->attached = true; - - - vectorSet(linkpoint, 1, BLOCKHEIGHT*(LEGHEIGHT + WAISTHEIGHT + TORSOHEIGHT) - 0.5, 0); - righthandlinks[0] = world->addLink(torso, righthand, linkpoint); - - vectorSet(linkpoint, 2, BLOCKHEIGHT*(LEGHEIGHT + WAISTHEIGHT + TORSOHEIGHT) - 0.5, 0); - righthandlinks[1] = world->addLink(torso, righthand, linkpoint); - - righthand->attached = true; - - - vectorSet(linkpoint, -1, BLOCKHEIGHT*(LEGHEIGHT + WAISTHEIGHT), -0.5); - world->addLink(torso, waist, linkpoint); - - vectorSet(linkpoint, 1, BLOCKHEIGHT*(LEGHEIGHT + WAISTHEIGHT), -0.5); - world->addLink(torso, waist, linkpoint); - - vectorSet(linkpoint, -1, BLOCKHEIGHT*(LEGHEIGHT + WAISTHEIGHT), 0.5); - world->addLink(torso, waist, linkpoint); - - vectorSet(linkpoint, 1, BLOCKHEIGHT*(LEGHEIGHT + WAISTHEIGHT), 0.5); - world->addLink(torso, waist, linkpoint); - - waist->attached = true; - - - vectorSet(linkpoint, -1, BLOCKHEIGHT*(LEGHEIGHT + WAISTHEIGHT)-0.5, 0); - leftleglinks[0] = world->addLink(waist, leftleg, linkpoint); - - vectorSet(linkpoint, 0, BLOCKHEIGHT*(LEGHEIGHT + WAISTHEIGHT)-0.5, 0); - leftleglinks[1] = world->addLink(waist, leftleg, linkpoint); - - lll = leftleglinks[1]; - - leftleg->attached = true; - - - vectorSet(linkpoint, 0, BLOCKHEIGHT*(LEGHEIGHT + WAISTHEIGHT)-0.5, 0); - rightleglinks[0] = world->addLink(waist, rightleg, linkpoint); - - vectorSet(linkpoint, 1, BLOCKHEIGHT*(LEGHEIGHT + WAISTHEIGHT)-0.5, 0); - rightleglinks[1] = world->addLink(waist, rightleg, linkpoint); - - rll = rightleglinks[0]; - - rightleg->attached = true; - - - leftleglinks[2] = world->addLink(waist, leftleg, NULL); - leftleglink = leftleglinks[2]; - leftleglink->enabled = false; - rightleglinks[2] = world->addLink(waist, rightleg, NULL); - rightleglink = rightleglinks[2]; - rightleglink->enabled = false; - - lefthandlinks[2] = world->addLink(torso, lefthand, NULL); - lefthandlink = lefthandlinks[2]; - lefthandlink->enabled = false; - righthandlinks[2] = world->addLink(torso, righthand, NULL); - righthandlink = righthandlinks[2]; - righthandlink->enabled = false; -} - -void Legoman::heal(void){ - headlinks[0]->enabled = true; - headlinks[1]->enabled = true; - headlinks[2]->enabled = true; - lefthandlinks[0]->enabled = true; - lefthandlinks[1]->enabled = true; - lefthandlinks[2]->enabled = true; - righthandlinks[0]->enabled = true; - righthandlinks[1]->enabled = true; - righthandlinks[2]->enabled = true; - leftleglinks[0]->enabled = true; - leftleglinks[1]->enabled = true; - leftleglinks[2]->enabled = true; - rightleglinks[0]->enabled = true; - rightleglinks[1]->enabled = true; - rightleglinks[2]->enabled = true; - - leftleglink->enabled = false; - rightleglink->enabled = false; - lefthandlink->enabled = false; - righthandlink->enabled = false; - - leftleg->reset(); - rightleg->reset(); - waist->reset(); - torso->reset(); - lefthand->reset(); - righthand->reset(); - head->reset(); - vectorSet(leftleg->position, -0.6, BLOCKHEIGHT*(LEGHEIGHT/2.0), 0); - vectorSet(rightleg->position, 0.6, BLOCKHEIGHT*(LEGHEIGHT/2.0), 0); - vectorSet(waist->position, 0, BLOCKHEIGHT*(LEGHEIGHT + WAISTHEIGHT/2.0), 0); - vectorSet(torso->position, 0, BLOCKHEIGHT*(LEGHEIGHT + WAISTHEIGHT + TORSOHEIGHT/2.0), 0); - vectorSet(lefthand->position, -1.3, BLOCKHEIGHT*(LEGHEIGHT + WAISTHEIGHT + TORSOHEIGHT - HANDHEIGHT/2.0), 0); - vectorSet(righthand->position, 1.3, BLOCKHEIGHT*(LEGHEIGHT + WAISTHEIGHT + TORSOHEIGHT - HANDHEIGHT/2.0), 0); - vectorSet(head->position, 0, BLOCKHEIGHT*(LEGHEIGHT + WAISTHEIGHT + TORSOHEIGHT + HEADHEIGHT/2 + 0.5), 0); - - headsensor->attach(head); - torsosensor->attach(torso); - - alive = true; -} - -void Legoman::lockPart(int part){ - if (part & LEFTLEG && leftleg->energy > 0){ - float linkpoint[3]; - vectorScale(linkpoint, &leftleg->rotation[3], -1); - //vectorAdd(linkpoint, leftleg->position); - vectorAdd(linkpoint, waist->position); - vectorAdd(linkpoint, lll->point1); - world->renewLink(leftleglink, linkpoint); - } - if (part & RIGHTLEG && rightleg->energy > 0){ - float linkpoint[3]; - vectorScale(linkpoint, &rightleg->rotation[3], -1); - //vectorAdd(linkpoint, rightleg->position); - vectorAdd(linkpoint, waist->position); - vectorAdd(linkpoint, rll->point1); - world->renewLink(rightleglink, linkpoint); - } - if (part & LEFTHAND && lefthand->energy > 0){ - float linkpoint[3]; - vectorScale(linkpoint, &lefthand->rotation[3], -1); - vectorAdd(linkpoint, lefthand->position); - world->renewLink(lefthandlink, linkpoint); - } - if (part & RIGHTHAND && righthand->energy > 0){ - float linkpoint[3]; - vectorScale(linkpoint, &righthand->rotation[3], -1); - vectorAdd(linkpoint, righthand->position); - world->renewLink(righthandlink, linkpoint); - } - - headsensor->attach(head); - torsosensor->attach(torso); -} - -void Legoman::addHarmfulObject(Object *object){ - objectlist *node = new objectlist(); - node->object = object; - node->next = harmfulobjects; - harmfulobjects = node; -} - -bool Legoman::isHarmfulObject(Object *object){ - objectlist *node = harmfulobjects; - while (node != NULL){ - if (node->object == object) return true; - node = node->next; - } - return false; -} - -float Legoman::getInvMass(void){ - float mass = torso->getMass() + waist->getMass(); - if (head->attached) mass += head->getMass(); - if (lefthand->attached) mass += lefthand->getMass(); - if (righthand->attached) mass += righthand->getMass(); - if (leftleg->attached) mass += leftleg->getMass(); - if (rightleg->attached) mass += rightleg->getMass(); - return 1.0/mass; -} - -void Legoman::addOpponent(Legoman *opponent){ - this->opponent = opponent; - opponent->addHarmfulObject(head); - opponent->addHarmfulObject(lefthand); - opponent->addHarmfulObject(righthand); - opponent->addHarmfulObject(leftleg); - opponent->addHarmfulObject(rightleg); -} - -void Legoman::unlockPart(int part){ - if (part & LEFTLEG){ - leftleglink->enabled = false; - } - if (part & RIGHTLEG){ - rightleglink->enabled = false; - } - if (part & LEFTHAND){ - lefthandlink->enabled = false; - } - if (part & RIGHTHAND){ - righthandlink->enabled = false; - } -} - -void Legoman::move(float *movement){ - vectorAdd(leftleg->position, movement); - vectorAdd(rightleg->position, movement); - vectorAdd(waist->position, movement); - vectorAdd(torso->position, movement); - vectorAdd(lefthand->position, movement); - vectorAdd(righthand->position, movement); - vectorAdd(head->position, movement); -} - -#define LEGSPEED 0.03 - -#define BALANCEANGLE (PI/12) - -void Legoman::balance(void){ - if (!alive || !head->attached) return; - - float headpos[3], torsopos[3]; - headsensor->getPosition(headpos); - torsosensor->getPosition(torsopos); - float posdiff[3]; - vectorSub(posdiff, headpos, torsopos); - float posdifflen = vectorLength(posdiff); - float angle = acos(posdiff[1]/posdifflen); - - float headtarget[3]; - vectorSet(headtarget, 0, posdifflen, 0); - vectorAdd(headtarget, torsopos); - - float force[3]; - vectorSub(force, headtarget, headpos); - - float headvel[3], torsovel[3]; - headsensor->getVelocity(headvel); - torsosensor->getVelocity(torsovel); - float veldiff[3]; - vectorSub(veldiff, headvel, torsovel); - vectorScale(veldiff, 50); - - vectorSaturate(veldiff, 0, 10); - - vectorSub(force, veldiff); - - if (angle < BALANCEANGLE){ - vectorScale(force, pow(1-angle/BALANCEANGLE, 0.1)); - vectorScale(force, 100); - head->addExternalForce(force); - } - - if (walkdelay == 0){ - if (walkphase > 0){ - walkphase --; - updateLegs(); - } - } - - vectorScale(lefthand->angularmomentum, 0.98); - vectorScale(righthand->angularmomentum, 0.98); -} - -void Legoman::update(void){ - if (walkdelay > 0){ - walkdelay--; - } - - /*if (jumpphase > 0){ - jumpphase--; - }*/ - if (torso->momentum[1] < 0 && isOnGround()){ - jumpphase--; - if (jumpphase == 0) jumpenabled = true; - } - - if (hitside < 10) hitside += 2; - //hitside = -hitside; - /*if (hitside > 0){ - hitside = -hitside; - }/* else{ - hitside = 0; - }*/ - - if (alive){ - if (head->position[1] < 0){// && torso->momentum[1] < 0){ - fallOff(); - } - - headsensor->update(); - torsosensor->update(); - - balance(); - } -} - -void Legoman::updateLegs(void){ - float temp[3]; - float angle; - - walkphase = sfmod(walkphase, PI/LEGSPEED); - - //Left leg - angle = sfmod(walkphase*LEGSPEED, PI); - if (angle > PI/4) angle = PI/2 - angle; - if (angle < -PI/4) angle = -PI/2 - angle; - vectorSet(temp, 0, -cos(angle), -sin(angle)); - vectorAdd(temp, lll->point1); - vectorCopy(leftleglink->point1, temp); - - //Right leg - angle = sfmod(walkphase*LEGSPEED + PI/2, PI); - if (angle > PI/4) angle = PI/2 - angle; - if (angle < -PI/4) angle = -PI/2 - angle; - vectorSet(temp, 0, -cos(angle), -sin(angle)); - vectorAdd(temp, rll->point1); - vectorCopy(rightleglink->point1, temp); -} - -void Legoman::walk(float amount){ - walkdelay = 20; - - float sign; - if (amount > 0) sign = 1; - else sign = -1; - - walkphase += sign; - - updateLegs(); - - if (!isStanding()) return; - - float movement[3]; - float xdir[3], ydir[3], zdir[3]; - - //vectorScale(ydir, &torso->rotation[3], 1); - vectorSet(ydir, 0, 1, 0); - vectorScale(zdir, &torso->rotation[6], -1); - vectorCross(xdir, ydir, zdir); - vectorNormalize(xdir); - //vectorScale(xdir, &torso->rotation[0], 1); - - float oldmomentum[3]; - vectorCopy(oldmomentum, torso->momentum); - - float xmove[3], ymove[3], zmove[3]; - - vectorProject(xmove, oldmomentum, xdir); - vectorProject(ymove, oldmomentum, ydir); - vectorProject(zmove, oldmomentum, zdir); - - vectorScale(xmove, 0.5); - float wh = waist->position[1]; - if (wh < WAISTHEIGHT + 1.0){ - float hd = WAISTHEIGHT + 1.0 - wh; - vectorScale(ymove, ydir, hd*10); - } - float newz[3]; - vectorScale(newz, zdir, 6*sign); - float ztemp[3]; - vectorProject(ztemp, newz, ydir); - vectorSub(newz, ztemp); - vectorScale(newz, 0.8); - vectorScale(zmove, 0.2); - vectorAdd(zmove, newz); - - vectorCopy(movement, xmove); - vectorAdd(movement, ymove); - vectorAdd(movement, zmove); - - //if (isStanding() && isOnGround()) - - vectorCopy(torso->momentum, movement); - vectorScale(movement, torso->invmass*waist->getMass()); - vectorCopy(waist->momentum, movement); - - - /*float speed = vectorDot(oldmomentum, movement); - float speedadd = 1; - float maxspeed = 5; - /*speed += speedadd; - if (speed > maxspeed) speed = maxspeed; - if (speed + speedadd > maxspeed){ - speedadd = maxspeed - speed; - } - - vectorScale(movement, speedadd); - if (waist->position[1] < WAISTHEIGHT + 1.0){ - movement[1] = 3; - } - vectorAdd(torso->momentum, movement);*/ - - /*float proj[3]; - vectorProject(proj, oldmomentum, movement); - float len = vectorLength(proj); - vectorAdd(movement, proj); - vectorSaturate(movement, 0, - - movement[1] = 300; - //torso->addExternalForce(movement); - }*/ - - /*float linkpoint[3]; - vectorScale(linkpoint, &leftleg->rotation[3], -1); - vectorAdd(linkpoint, leftleg->position);*/ - - /*float movement[3]; - float temp[3]; - vectorScale(temp, &torso->rotation[3], amount*0.1); - vectorScale(movement, &torso->rotation[6], amount); - vectorAdd(movement, temp); - - if (walkphase == 0){ - walkphase = 40; - vectorAdd(leftleg->momentum, movement); - } - if (walkphase == 20){ - walkphase = 19; - vectorAdd(rightleg->momentum, movement); - }*/ - - /*float axis[3]; - vectorScale(axis, &leftleg->rotation[0], amount); - - if (walkphase == 0){ - //walkphase = 40; - vectorAdd(leftleg->angularmomentum, axis); - vectorAdd(rightleg->angularmomentum, axis); - }*/ - /*if (walkphase == 0){ - walkphase = 1; - vectorAdd(rightleg->momentum, movement); - }*/ - /*float axis[3]; - float movement[3]; - - if (walkphase == 0){ - unlockPart(LEFTLEG); - - vectorScale(axis, &leftleg->rotation[0], 5); - vectorAdd(leftleg->angularmomentum, axis); - - float temp[3]; - vectorScale(temp, &torso->rotation[6], -10); - vectorScale(movement, &torso->rotation[3], 5); - vectorAdd(movement, temp); - vectorAdd(torso->momentum, movement); - vectorAdd(leftleg->momentum, movement); - - walkphase = 40; - }*/ -} - -void Legoman::turn(float amount){ - float axis[3]; - if (isStanding()){ - vectorScale(axis, &torso->rotation[3], amount); - vectorCopy(torso->angularmomentum, axis); - } else{ - vectorScale(axis, &torso->rotation[3], amount*0.3); - vectorAdd(torso->angularmomentum, axis); - } -} - -void Legoman::hit(void){ - if (!lefthand->attached && !righthand->attached) return; - /*float leftdot = vectorDot(&lefthand->rotation[3], &torso->rotation[6]); - float rightdot = vectorDot(&righthand->rotation[3], &torso->rotation[6]); - if (leftdot < rightdot){ - hitside = LEFTHAND; - } else{ - hitside = RIGHTHAND; - }*/ - - if (hitside >= 10) hitside -= 9; - else hitside -= 2; - - if ((hitside & 1) && !lefthand->attached) hitside++; - if (!(hitside & 1) && !righthand->attached) hitside++; - - float axis[3]; - if (hitside & 1){ - vectorScale(axis, &lefthand->rotation[0], 20); - vectorCopy(lefthand->angularmomentum, axis); - } else{ - vectorScale(axis, &righthand->rotation[0], 20); - vectorCopy(righthand->angularmomentum, axis); - } -} - -void Legoman::jump(void){ - if (!leftleg->attached && !rightleg->attached) return; - if (jumpenabled){// == 0 && isOnGround()){ - float r = BLOCKHEIGHT*HEADHEIGHT/2; - float strength = (2*LEGHEIGHT + 2*WAISTHEIGHT + 2*TORSOHEIGHT - + 2*HANDHEIGHT + 4.0*PI*r*r*r)/3.0*getInvMass(); - float jumpvector[3] = {0, 100.0/strength, 0}; - - //vectorCopy(torso->momentum, jumpvector); - torso->momentum[1] = jumpvector[1]; - head->momentum[1] = 0;// jumpvector[1]; - waist->momentum[1] = 0;// jumpvector[1]; - leftleg->momentum[1] = 0;// jumpvector[1]; - rightleg->momentum[1] = 0;// jumpvector[1]; - lefthand->momentum[1] = 0;// jumpvector[1]; - righthand->momentum[1] = 0;// jumpvector[1]; - //vectorSet(head->momentum, 0, 0, 0); - //jumpphase = 150; - jumpsound->play(); - jumpenabled = false; - } - jumpphase = 2; -} - -bool Legoman::isOnGround(void){ - //if (!isStanding()) return false; - float wh = waist->position[1]; - if (wh > WAISTHEIGHT + 1.5) return false; - if (fabs(torso->momentum[1]) > 10) return false; - //if (fabs(head->momentum[1]) > 10) return false; - //if (fabs(waist->momentum[1]) > 3) return false; - return true; -} - -bool Legoman::isStanding(void){ - if (!leftleg->attached && !rightleg->attached) return false; - float headpos[3], torsopos[3]; - headsensor->getPosition(headpos); - torsosensor->getPosition(torsopos); - float posdiff[3]; - vectorSub(posdiff, headpos, torsopos); - float posdifflen = vectorLength(posdiff); - float angle = acos(posdiff[1]/posdifflen); - - if (angle < BALANCEANGLE) return true; - else return false; -} - -void Legoman::fallOff(void){ - if (dead) return; - if (rand()&1) fallsound1->play(); - else fallsound2->play(); - die(); - head->energy = 0; - torso->energy = 0; - lefthand->energy = 0; - righthand->energy = 0; - waist->energy = 0; - leftleg->energy = 0; - rightleg->energy = 0; -} - -void Legoman::releasePart(BodyPart *part){ - if (dead) return; - if (part == head){ - headlinks[0]->enabled = false; - headlinks[1]->enabled = false; - headlinks[2]->enabled = false; - head->attached = false; - //float move[3]; - //vectorScale(move, &head->rotation[3], 1); - //vectorAdd(head->position, move); - die(); - } else if (part == lefthand){ - lefthandlinks[0]->enabled = false; - lefthandlinks[1]->enabled = false; - lefthandlinks[2]->enabled = false; - lefthand->attached = false; - } else if (part == righthand){ - righthandlinks[0]->enabled = false; - righthandlinks[1]->enabled = false; - righthandlinks[2]->enabled = false; - righthand->attached = false; - } else if (part == leftleg){ - leftleglinks[0]->enabled = false; - leftleglinks[1]->enabled = false; - leftleglinks[2]->enabled = false; - leftleg->attached = false; - } else if (part == rightleg){ - rightleglinks[0]->enabled = false; - rightleglinks[1]->enabled = false; - rightleglinks[2]->enabled = false; - rightleg->attached = false; - } else if (part == torso){ - die(); - } - if (!lefthand->attached && !righthand->attached && - !leftleg->attached && !rightleg->attached) die(); -} - -void Legoman::die(void){ - if (dead) return; - alive = false; - lll->enabled = false; - rll->enabled = false; - gameOver(this); -} - -bool Legoman::isAlive(void){ - return alive; -} - -Legoman *Legoman::getOpponent(void){ - return opponent; -} - -void Legoman::drawVisuals(void){ - headvisual->draw(); - torsovisual->draw(); - lefthandvisual->draw(); - righthandvisual->draw(); - leftlegvisual->draw(); - rightlegvisual->draw(); -} - - - -DamageVisual::DamageVisual(BodyPart *object, Texture *texture, bool mirror, - float x1, float y1, float x2, float y2){ - this->object = object; - this->texture = texture; - - this->x1 = x1; - this->y1 = y1; - this->x2 = x2; - this->y2 = y2; - - float d = 3.0/512; - - if (mirror){ - this->tx1 = 1-d; - this->tx2 = 0+d+0.01; - } else{ - this->tx1 = 0+d+0.01; - this->tx2 = 1-d; - } - this->ty1 = 0+d; - this->ty2 = 1-d; -} - -void DamageVisual::draw(void){ - float energy = object->energy; - texture->enable(); - - glBegin(GL_QUADS); - if (energy > 0) glColor3f(1-energy, energy, 0); - else glColor3f(0.3, 0.3, 0.3); - - glTexCoord2f(tx1, ty1); - glVertex2f(x1, y1); - - glTexCoord2f(tx1, ty2); - glVertex2f(x1, y2); - - glTexCoord2f(tx2, ty2); - glVertex2f(x2, y2); - - glTexCoord2f(tx2, ty1); - glVertex2f(x2, y1); - glEnd(); -} +#include "main.h" + +#include + +#include "legoman.h" +#include "object.h" +#include "sphere.h" +#include "world.h" +#include "legoblocks.h" +#include "vector.h" +#include "collision.h" +#include "objectfactory.h" +#include "utils.h" +#include "particle.h" +#include "fight.h" +#include "glapi.h" + + + + +BodyPart::BodyPart(Legoman *parent, float strength){ + this->parent = parent; + this->strength = strength; + reset(); +} + +void BodyPart::reset(void){ + this->energy = 1; + this->attached = true; + this->immortal = 0; + vectorSet(position, 0, 0, 0); + vectorSet(momentum, 0, 0, 0); + matrixIdentity(rotation); + vectorSet(angularmomentum, 0, 0, 0); +} + +void BodyPart::move(void){ + if (immortal > 0) immortal--; + Object::move(); +} + +void BodyPart::hitForce(float speed, float *speed2, Object *source){ + if (parent->isHarmfulObject(source)){ + float tolerance = 0.3; + if (speed > tolerance){ + Sound *sound; + sound = hitsound1; + float volume = (speed-tolerance)*0.4; + if (volume > 1) volume = 1; + volume = 1; + sound->setVolume(volume); + sound->play(30 + random(120)); + + int i; + for (i = 0; i < (int)(speed-0.5); i++){ + float vel[3] = {randomf(2)-1, randomf(3), randomf(2)-1}; + vectorAdd(vel, speed2); + createBlood(position, vel); + } + + //makeDamage(0.1); + if (this == parent->head && source == parent->opponent->head){ + speed *= 0.1; + } + makeDamage(speed*0.1); + } + } else{ + Object::hitForce(speed, speed2, source); + } +} + +void BodyPart::makeDamage(float amount){ + if (strength == 0) return; + if (energy == 0) return; + if (!parent->opponent->isAlive()) return; + if (immortal > 0) return; + + energy -= amount/strength; + if (energy < 0) energy = 0; + if (energy == 0){ + parent->releasePart(this); + } + immortal = 30; +} + + +Sensor::Sensor(){ +} + +void Sensor::attach(Object *object, float *relativeposition){ + vectorCopy(this->relativeposition, relativeposition); + this->object = object; + update(); + update(); + update(); + update(); +} + +void Sensor::attach(Object *object){ + float position[3] = {0, 0, 0}; + attach(object, position); +} + +void Sensor::update(void){ + vectorCopy(oldposition, position); + vectorCopy(oldvelocity, velocity); + + object->transformPoint(position, relativeposition); + + vectorSub(velocity, position, oldposition); + vectorSub(acceleration, velocity, oldvelocity); + + //printf("V: %f, %f, %f\n", velocity[0], velocity[1], velocity[2]); +} + +void Sensor::getPosition(float *target){ + vectorCopy(target, position); +} + +void Sensor::getVelocity(float *target){ + vectorCopy(target, velocity); +} + +void Sensor::getAcceleration(float *target){ + vectorCopy(target, acceleration); +} + +//float rightHandOffset[3] = {-0.60, 0.45, 0.0}; +float rightHandOffset[3] = {-0.40, 0.45, 0.0}; +//float leftHandOffset[3] = {0.60, 0.46, 0.0}; +float leftHandOffset[3] = {0.40, 0.46, 0.0}; +//float leftPalmOffset[3] = {0.28, -0.3, -0.38}; +float leftPalmOffset[3] = {0.08, -0.3, -0.38}; +//float rightPalmOffset[3] = {-0.30, -0.3, -0.38}; +float rightPalmOffset[3] = {-0.10, -0.3, -0.38}; +float waistOffset[3] = {0.0, 0.2, 0.0}; +float rightLegOffset[3] = {-0.15, 0.4, 0.0}; +float leftLegOffset[3] = {0.1, 0.4, 0.0}; + +Legoman::Legoman(int side){ + this->side = side; + + int collisiongroup, collisiongrouphand; + if (side == PLAYER1){ + collisiongroup = COLLISIONGROUP_MAN1; + collisiongrouphand = COLLISIONGROUP_MAN1HAND; + } + if (side == PLAYER2){ + collisiongroup = COLLISIONGROUP_MAN2; + collisiongrouphand = COLLISIONGROUP_MAN2HAND; + } + + float torsocolor[3], legcolor[3]; + + if (side == PLAYER1){ + vectorSet(torsocolor, 1, 0, 0); + vectorSet(legcolor, 0, 0, 1); + } else if (side == PLAYER2){ + vectorSet(torsocolor, 0, 0, 1); + vectorSet(legcolor, 1, 0, 0); + } + + //Legs + Mesh* geomLegMesh = createBox(-0.45, 0.45, -BLOCKHEIGHT*LEGHEIGHT/2.0, BLOCKHEIGHT*LEGHEIGHT/2.0, -0.5, 0.5); + float tmpScale = 1.0; + + //Left leg + { + leftleg = new BodyPart(this, 8); + Mesh* leftLegMesh = loadAscModel((char*)LEFTLEGASC, MODELSCALE, leftLegOffset); + MeshShape *leftLegGeom = new MeshShape(leftleg, geomLegMesh); + leftleg->geometry = leftLegGeom; + leftleg->appearance = new MeshAppearance(leftLegMesh); + //leftleg->appearance = new MeshAppearance(geomLegMesh); + leftleg->appearance->material.setColor(legcolor[0], legcolor[1], legcolor[2], 1); + vectorSet(leftleg->position, -0.6, BLOCKHEIGHT*(LEGHEIGHT/2.0), 0); + leftleg->setGravity(true); + leftleg->setMass(LEGHEIGHT/3.0); + leftleg->setCollisionGroup(collisiongroup); + } + + //Right leg + { + rightleg = new BodyPart(this, 8); + Mesh* rightLegMesh = loadAscModel((char*)RIGHTLEGASC, MODELSCALE, rightLegOffset); + MeshShape *rightLegGeom = new MeshShape(rightleg, geomLegMesh); + rightleg->geometry = rightLegGeom; + rightleg->appearance = new MeshAppearance(rightLegMesh); + //rightleg->appearance = new MeshAppearance(geomLegMesh); + rightleg->appearance->material.setColor(legcolor[0], legcolor[1], legcolor[2], 1); + vectorSet(rightleg->position, 0.6, BLOCKHEIGHT*(LEGHEIGHT/2.0), 0); + rightleg->setGravity(true); + rightleg->setMass(LEGHEIGHT/3.0); + rightleg->setCollisionGroup(collisiongroup); + } + + + //Waist + { + waist = new BodyPart(this, 0); + Mesh* waistMesh = loadAscModel((char*)WAISTASC, MODELSCALE, waistOffset); + MeshAppearance* waistappearance = new MeshAppearance(waistMesh); + waistappearance->material.setColor(0, 1, 0, 1); + + Mesh *waistGeomMesh = createBox(-1 + 0.1, 1 - 0.1, 0, BLOCKHEIGHT*WAISTHEIGHT/2.0, 0.1, 0.4); + MeshShape *waistgeometry = new MeshShape(waist, waistGeomMesh); + waist->geometry = waistgeometry; + waist->appearance = waistappearance; + //waist->appearance = new MeshAppearance(waistGeomMesh); + vectorSet(waist->position, 0, BLOCKHEIGHT*(LEGHEIGHT + WAISTHEIGHT/2.0), 0); + waist->setGravity(true); + waist->setMass(2*WAISTHEIGHT/3.0); + waist->setCollisionGroup(collisiongroup); + } + + + //Torso + { + torso = new BodyPart(this, 4); + Mesh* torsoMesh = loadAscModel((char*)TORSOASC, TORSOSCALE); + //int i; + //for (i = 0; i < torsoMesh->polygoncount; i++) torsoMesh->polygons[i].smooth = false; + MeshAppearance* torsoAppearance = new MeshAppearance(torsoMesh); + torsoAppearance->material.setColor(torsocolor[0], torsocolor[1], torsocolor[2], 1); + Mesh *torsoGeomMesh = createBox(-1, 1, -BLOCKHEIGHT*TORSOHEIGHT/2.0, BLOCKHEIGHT*TORSOHEIGHT/2.0, -0.5, 0.5); + MeshShape *torsogeometry = new MeshShape(torso, torsoGeomMesh); + torso->geometry = torsogeometry; + torso->appearance = torsoAppearance; + //torso->appearance = new MeshAppearance(torsoGeomMesh); + vectorSet(torso->position, 0, BLOCKHEIGHT*(LEGHEIGHT + WAISTHEIGHT + TORSOHEIGHT/2.0), 0); + torso->setGravity(true); + torso->setMass(2*TORSOHEIGHT/3.0); + torso->setCollisionGroup(collisiongroup); + } + + + //Hands + //Mesh *handMeshGeom = createBox(-0.4, 0.4, -BLOCKHEIGHT*HANDHEIGHT/2.0, BLOCKHEIGHT*HANDHEIGHT/2.0, -0.5, 0.5); + Mesh *handMeshGeom = createBox(-0.2, 0.2, -BLOCKHEIGHT*HANDHEIGHT/2.0, BLOCKHEIGHT*HANDHEIGHT/2.0, -0.5, 0.5); + + + //Left hand + { + lefthand = new BodyPart(this, 5); + + Mesh* leftHandMesh = loadAscModel((char*)LEFTARMASC, MODELSCALE, leftHandOffset); + Mesh* leftPalmMesh = loadAscModel((char*)LEFTPALMASC, MODELSCALE, leftPalmOffset); + MultiAppearance *a = new MultiAppearance(); + Appearance *arm = new MeshAppearance(leftHandMesh); + Appearance *palm = new MeshAppearance(leftPalmMesh); + arm->material.setColor(torsocolor[0], torsocolor[1], torsocolor[2], 1); + palm->material.setColor(1, 1, 0, 1); + a->addAppearance(arm); + a->addAppearance(palm); + MeshShape *lefthandgeometry = new MeshShape(lefthand, handMeshGeom); + lefthand->geometry = lefthandgeometry; + lefthand->appearance = a;//new MeshAppearance(leftHandMesh); + //lefthand->appearance = new MeshAppearance(handMeshGeom); + //lefthand->appearance->material.setColor(1, 0, 0, 1); + vectorSet(lefthand->position, -1.3, BLOCKHEIGHT*(LEGHEIGHT + WAISTHEIGHT + TORSOHEIGHT - HANDHEIGHT/2.0), 0); + lefthand->setGravity(true); + lefthand->setMass(HANDHEIGHT/3.0); + lefthand->setCollisionGroup(collisiongrouphand); + } + + //Right hand + { + righthand = new BodyPart(this, 5); + Mesh* rightHandMesh = loadAscModel((char*)RIGHTARMASC, MODELSCALE, rightHandOffset); + Mesh* rightPalmMesh = loadAscModel((char*)RIGHTPALMASC, MODELSCALE, rightPalmOffset); + MultiAppearance *a = new MultiAppearance(); + Appearance *arm = new MeshAppearance(rightHandMesh); + arm->material.setColor(torsocolor[0], torsocolor[1], torsocolor[2], 1); + Appearance *palm = new MeshAppearance(rightPalmMesh); + palm->material.setColor(1, 1, 0, 1); + a->addAppearance(arm); + a->addAppearance(palm); + MeshShape *righthandgeometry = new MeshShape(righthand, handMeshGeom); + righthand->geometry = righthandgeometry; + righthand->appearance = a; + //righthand->appearance = new MeshAppearance(handMeshGeom); + vectorSet(righthand->position, 1.3, BLOCKHEIGHT*(LEGHEIGHT + WAISTHEIGHT + TORSOHEIGHT - HANDHEIGHT/2.0), 0); + righthand->setGravity(true); + righthand->setMass(HANDHEIGHT/3.0); + righthand->setCollisionGroup(collisiongrouphand); + } + + + //Head + { + head = new BodyPart(this, 2); + Appearance *headappearance = new HeadAppearance(); + float r = BLOCKHEIGHT*HEADHEIGHT/2; + /*SphereAppearance *headappearance = new SphereAppearance(); + headappearance->setRadius(r); + headappearance->material.setColor(1, 1, 0, 1);*/ + SphereShape *headgeometry = new SphereShape(head); + headgeometry->setRadius(r); + head->geometry = headgeometry; + head->appearance = headappearance; + vectorSet(head->position, 0, BLOCKHEIGHT*(LEGHEIGHT + WAISTHEIGHT + TORSOHEIGHT + HEADHEIGHT/2 + 0.5), 0); + head->setGravity(true); + head->setMass(4.0/3*PI*r*r*r); + head->setCollisionGroup(collisiongroup); + } + + + headsensor = new Sensor(); + torsosensor = new Sensor(); + + + + headvisual = new DamageVisual(head, damageHead, false, + -0.5, -2, 0.5, -1); + + torsovisual = new DamageVisual(torso, damageTorso, false, + -0.5, -1, 0.5, 0); + + lefthandvisual = new DamageVisual(lefthand, damageHand, true, + 0.4, -1, 0.9, 0); + + righthandvisual = new DamageVisual(righthand, damageHand, true, + -0.4, -1, -0.9, 0); + + leftlegvisual = new DamageVisual(leftleg, damageLeg, true, + 0, 0, 0.5, 1); + + rightlegvisual = new DamageVisual(rightleg, damageLeg, true, + -0, 0, -0.5, 1); + + + harmfulobjects = NULL; + + + walkphase = 0; + jumpphase = 0; + hitside = 0; + + alive = true; +} + +void Legoman::insertToWorld(World *world){ + this->world = world; + + + world->addChild(rightleg); + world->addChild(leftleg); + world->addChild(waist); + world->addChild(torso); + world->addChild(lefthand); + world->addChild(righthand); + world->addChild(head); + float linkpoint[3]; + + vectorSet(linkpoint, 0, BLOCKHEIGHT*(LEGHEIGHT + WAISTHEIGHT + TORSOHEIGHT + HEADHEIGHT), 0); + headlinks[0] = world->addLink(head, torso, linkpoint); + + vectorSet(linkpoint, 0, BLOCKHEIGHT*(LEGHEIGHT + WAISTHEIGHT + TORSOHEIGHT), 0); + headlinks[1] = world->addLink(head, torso, linkpoint); + + vectorSet(linkpoint, 0, BLOCKHEIGHT*(LEGHEIGHT + WAISTHEIGHT + TORSOHEIGHT + HEADHEIGHT*0.5), 1); + headlinks[2] = world->addLink(head, torso, linkpoint); + + head->attached = true; + + + vectorSet(linkpoint, -1, BLOCKHEIGHT*(LEGHEIGHT + WAISTHEIGHT + TORSOHEIGHT) - 0.5, 0); + lefthandlinks[0] = world->addLink(torso, lefthand, linkpoint); + + vectorSet(linkpoint, -2, BLOCKHEIGHT*(LEGHEIGHT + WAISTHEIGHT + TORSOHEIGHT) - 0.5, 0); + lefthandlinks[1] = world->addLink(torso, lefthand, linkpoint); + + lefthand->attached = true; + + + vectorSet(linkpoint, 1, BLOCKHEIGHT*(LEGHEIGHT + WAISTHEIGHT + TORSOHEIGHT) - 0.5, 0); + righthandlinks[0] = world->addLink(torso, righthand, linkpoint); + + vectorSet(linkpoint, 2, BLOCKHEIGHT*(LEGHEIGHT + WAISTHEIGHT + TORSOHEIGHT) - 0.5, 0); + righthandlinks[1] = world->addLink(torso, righthand, linkpoint); + + righthand->attached = true; + + + vectorSet(linkpoint, -1, BLOCKHEIGHT*(LEGHEIGHT + WAISTHEIGHT), -0.5); + world->addLink(torso, waist, linkpoint); + + vectorSet(linkpoint, 1, BLOCKHEIGHT*(LEGHEIGHT + WAISTHEIGHT), -0.5); + world->addLink(torso, waist, linkpoint); + + vectorSet(linkpoint, -1, BLOCKHEIGHT*(LEGHEIGHT + WAISTHEIGHT), 0.5); + world->addLink(torso, waist, linkpoint); + + vectorSet(linkpoint, 1, BLOCKHEIGHT*(LEGHEIGHT + WAISTHEIGHT), 0.5); + world->addLink(torso, waist, linkpoint); + + waist->attached = true; + + + vectorSet(linkpoint, -1, BLOCKHEIGHT*(LEGHEIGHT + WAISTHEIGHT)-0.5, 0); + leftleglinks[0] = world->addLink(waist, leftleg, linkpoint); + + vectorSet(linkpoint, 0, BLOCKHEIGHT*(LEGHEIGHT + WAISTHEIGHT)-0.5, 0); + leftleglinks[1] = world->addLink(waist, leftleg, linkpoint); + + lll = leftleglinks[1]; + + leftleg->attached = true; + + + vectorSet(linkpoint, 0, BLOCKHEIGHT*(LEGHEIGHT + WAISTHEIGHT)-0.5, 0); + rightleglinks[0] = world->addLink(waist, rightleg, linkpoint); + + vectorSet(linkpoint, 1, BLOCKHEIGHT*(LEGHEIGHT + WAISTHEIGHT)-0.5, 0); + rightleglinks[1] = world->addLink(waist, rightleg, linkpoint); + + rll = rightleglinks[0]; + + rightleg->attached = true; + + + leftleglinks[2] = world->addLink(waist, leftleg, NULL); + leftleglink = leftleglinks[2]; + leftleglink->enabled = false; + rightleglinks[2] = world->addLink(waist, rightleg, NULL); + rightleglink = rightleglinks[2]; + rightleglink->enabled = false; + + lefthandlinks[2] = world->addLink(torso, lefthand, NULL); + lefthandlink = lefthandlinks[2]; + lefthandlink->enabled = false; + righthandlinks[2] = world->addLink(torso, righthand, NULL); + righthandlink = righthandlinks[2]; + righthandlink->enabled = false; +} + +void Legoman::heal(void){ + headlinks[0]->enabled = true; + headlinks[1]->enabled = true; + headlinks[2]->enabled = true; + lefthandlinks[0]->enabled = true; + lefthandlinks[1]->enabled = true; + lefthandlinks[2]->enabled = true; + righthandlinks[0]->enabled = true; + righthandlinks[1]->enabled = true; + righthandlinks[2]->enabled = true; + leftleglinks[0]->enabled = true; + leftleglinks[1]->enabled = true; + leftleglinks[2]->enabled = true; + rightleglinks[0]->enabled = true; + rightleglinks[1]->enabled = true; + rightleglinks[2]->enabled = true; + + leftleglink->enabled = false; + rightleglink->enabled = false; + lefthandlink->enabled = false; + righthandlink->enabled = false; + + leftleg->reset(); + rightleg->reset(); + waist->reset(); + torso->reset(); + lefthand->reset(); + righthand->reset(); + head->reset(); + vectorSet(leftleg->position, -0.6, BLOCKHEIGHT*(LEGHEIGHT/2.0), 0); + vectorSet(rightleg->position, 0.6, BLOCKHEIGHT*(LEGHEIGHT/2.0), 0); + vectorSet(waist->position, 0, BLOCKHEIGHT*(LEGHEIGHT + WAISTHEIGHT/2.0), 0); + vectorSet(torso->position, 0, BLOCKHEIGHT*(LEGHEIGHT + WAISTHEIGHT + TORSOHEIGHT/2.0), 0); + vectorSet(lefthand->position, -1.3, BLOCKHEIGHT*(LEGHEIGHT + WAISTHEIGHT + TORSOHEIGHT - HANDHEIGHT/2.0), 0); + vectorSet(righthand->position, 1.3, BLOCKHEIGHT*(LEGHEIGHT + WAISTHEIGHT + TORSOHEIGHT - HANDHEIGHT/2.0), 0); + vectorSet(head->position, 0, BLOCKHEIGHT*(LEGHEIGHT + WAISTHEIGHT + TORSOHEIGHT + HEADHEIGHT/2 + 0.5), 0); + + headsensor->attach(head); + torsosensor->attach(torso); + + alive = true; +} + +void Legoman::lockPart(int part){ + if (part & LEFTLEG && leftleg->energy > 0){ + float linkpoint[3]; + vectorScale(linkpoint, &leftleg->rotation[3], -1); + //vectorAdd(linkpoint, leftleg->position); + vectorAdd(linkpoint, waist->position); + vectorAdd(linkpoint, lll->point1); + world->renewLink(leftleglink, linkpoint); + } + if (part & RIGHTLEG && rightleg->energy > 0){ + float linkpoint[3]; + vectorScale(linkpoint, &rightleg->rotation[3], -1); + //vectorAdd(linkpoint, rightleg->position); + vectorAdd(linkpoint, waist->position); + vectorAdd(linkpoint, rll->point1); + world->renewLink(rightleglink, linkpoint); + } + if (part & LEFTHAND && lefthand->energy > 0){ + float linkpoint[3]; + vectorScale(linkpoint, &lefthand->rotation[3], -1); + vectorAdd(linkpoint, lefthand->position); + world->renewLink(lefthandlink, linkpoint); + } + if (part & RIGHTHAND && righthand->energy > 0){ + float linkpoint[3]; + vectorScale(linkpoint, &righthand->rotation[3], -1); + vectorAdd(linkpoint, righthand->position); + world->renewLink(righthandlink, linkpoint); + } + + headsensor->attach(head); + torsosensor->attach(torso); +} + +void Legoman::addHarmfulObject(Object *object){ + objectlist *node = new objectlist(); + node->object = object; + node->next = harmfulobjects; + harmfulobjects = node; +} + +bool Legoman::isHarmfulObject(Object *object){ + objectlist *node = harmfulobjects; + while (node != NULL){ + if (node->object == object) return true; + node = node->next; + } + return false; +} + +float Legoman::getInvMass(void){ + float mass = torso->getMass() + waist->getMass(); + if (head->attached) mass += head->getMass(); + if (lefthand->attached) mass += lefthand->getMass(); + if (righthand->attached) mass += righthand->getMass(); + if (leftleg->attached) mass += leftleg->getMass(); + if (rightleg->attached) mass += rightleg->getMass(); + return 1.0/mass; +} + +void Legoman::addOpponent(Legoman *opponent){ + this->opponent = opponent; + opponent->addHarmfulObject(head); + opponent->addHarmfulObject(lefthand); + opponent->addHarmfulObject(righthand); + opponent->addHarmfulObject(leftleg); + opponent->addHarmfulObject(rightleg); +} + +void Legoman::unlockPart(int part){ + if (part & LEFTLEG){ + leftleglink->enabled = false; + } + if (part & RIGHTLEG){ + rightleglink->enabled = false; + } + if (part & LEFTHAND){ + lefthandlink->enabled = false; + } + if (part & RIGHTHAND){ + righthandlink->enabled = false; + } +} + +void Legoman::move(float *movement){ + vectorAdd(leftleg->position, movement); + vectorAdd(rightleg->position, movement); + vectorAdd(waist->position, movement); + vectorAdd(torso->position, movement); + vectorAdd(lefthand->position, movement); + vectorAdd(righthand->position, movement); + vectorAdd(head->position, movement); +} + +#define LEGSPEED 0.03 + +#define BALANCEANGLE (PI/12) + +void Legoman::balance(void){ + if (!alive || !head->attached) return; + + float headpos[3], torsopos[3]; + headsensor->getPosition(headpos); + torsosensor->getPosition(torsopos); + float posdiff[3]; + vectorSub(posdiff, headpos, torsopos); + float posdifflen = vectorLength(posdiff); + float angle = acos(posdiff[1]/posdifflen); + + float headtarget[3]; + vectorSet(headtarget, 0, posdifflen, 0); + vectorAdd(headtarget, torsopos); + + float force[3]; + vectorSub(force, headtarget, headpos); + + float headvel[3], torsovel[3]; + headsensor->getVelocity(headvel); + torsosensor->getVelocity(torsovel); + float veldiff[3]; + vectorSub(veldiff, headvel, torsovel); + vectorScale(veldiff, 50); + + vectorSaturate(veldiff, 0, 10); + + vectorSub(force, veldiff); + + if (angle < BALANCEANGLE){ + vectorScale(force, pow(1-angle/BALANCEANGLE, 0.1)); + vectorScale(force, 100); + head->addExternalForce(force); + } + + if (walkdelay == 0){ + if (walkphase > 0){ + walkphase --; + updateLegs(); + } + } + + vectorScale(lefthand->angularmomentum, 0.98); + vectorScale(righthand->angularmomentum, 0.98); +} + +void Legoman::update(void){ + if (walkdelay > 0){ + walkdelay--; + } + + /*if (jumpphase > 0){ + jumpphase--; + }*/ + if (torso->momentum[1] < 0 && isOnGround()){ + jumpphase--; + if (jumpphase == 0) jumpenabled = true; + } + + if (hitside < 10) hitside += 2; + //hitside = -hitside; + /*if (hitside > 0){ + hitside = -hitside; + }/* else{ + hitside = 0; + }*/ + + if (alive){ + if (head->position[1] < 0){// && torso->momentum[1] < 0){ + fallOff(); + } + + headsensor->update(); + torsosensor->update(); + + balance(); + } +} + +void Legoman::updateLegs(void){ + float temp[3]; + float angle; + + walkphase = sfmod(walkphase, PI/LEGSPEED); + + //Left leg + angle = sfmod(walkphase*LEGSPEED, PI); + if (angle > PI/4) angle = PI/2 - angle; + if (angle < -PI/4) angle = -PI/2 - angle; + vectorSet(temp, 0, -cos(angle), -sin(angle)); + vectorAdd(temp, lll->point1); + vectorCopy(leftleglink->point1, temp); + + //Right leg + angle = sfmod(walkphase*LEGSPEED + PI/2, PI); + if (angle > PI/4) angle = PI/2 - angle; + if (angle < -PI/4) angle = -PI/2 - angle; + vectorSet(temp, 0, -cos(angle), -sin(angle)); + vectorAdd(temp, rll->point1); + vectorCopy(rightleglink->point1, temp); +} + +void Legoman::walk(float amount){ + walkdelay = 20; + + float sign; + if (amount > 0) sign = 1; + else sign = -1; + + walkphase += sign; + + updateLegs(); + + if (!isStanding()) return; + + float movement[3]; + float xdir[3], ydir[3], zdir[3]; + + //vectorScale(ydir, &torso->rotation[3], 1); + vectorSet(ydir, 0, 1, 0); + vectorScale(zdir, &torso->rotation[6], -1); + vectorCross(xdir, ydir, zdir); + vectorNormalize(xdir); + //vectorScale(xdir, &torso->rotation[0], 1); + + float oldmomentum[3]; + vectorCopy(oldmomentum, torso->momentum); + + float xmove[3], ymove[3], zmove[3]; + + vectorProject(xmove, oldmomentum, xdir); + vectorProject(ymove, oldmomentum, ydir); + vectorProject(zmove, oldmomentum, zdir); + + vectorScale(xmove, 0.5); + float wh = waist->position[1]; + if (wh < WAISTHEIGHT + 1.0){ + float hd = WAISTHEIGHT + 1.0 - wh; + vectorScale(ymove, ydir, hd*10); + } + float newz[3]; + vectorScale(newz, zdir, 6*sign); + float ztemp[3]; + vectorProject(ztemp, newz, ydir); + vectorSub(newz, ztemp); + vectorScale(newz, 0.8); + vectorScale(zmove, 0.2); + vectorAdd(zmove, newz); + + vectorCopy(movement, xmove); + vectorAdd(movement, ymove); + vectorAdd(movement, zmove); + + //if (isStanding() && isOnGround()) + + vectorCopy(torso->momentum, movement); + vectorScale(movement, torso->invmass*waist->getMass()); + vectorCopy(waist->momentum, movement); + + + /*float speed = vectorDot(oldmomentum, movement); + float speedadd = 1; + float maxspeed = 5; + /*speed += speedadd; + if (speed > maxspeed) speed = maxspeed; + if (speed + speedadd > maxspeed){ + speedadd = maxspeed - speed; + } + + vectorScale(movement, speedadd); + if (waist->position[1] < WAISTHEIGHT + 1.0){ + movement[1] = 3; + } + vectorAdd(torso->momentum, movement);*/ + + /*float proj[3]; + vectorProject(proj, oldmomentum, movement); + float len = vectorLength(proj); + vectorAdd(movement, proj); + vectorSaturate(movement, 0, + + movement[1] = 300; + //torso->addExternalForce(movement); + }*/ + + /*float linkpoint[3]; + vectorScale(linkpoint, &leftleg->rotation[3], -1); + vectorAdd(linkpoint, leftleg->position);*/ + + /*float movement[3]; + float temp[3]; + vectorScale(temp, &torso->rotation[3], amount*0.1); + vectorScale(movement, &torso->rotation[6], amount); + vectorAdd(movement, temp); + + if (walkphase == 0){ + walkphase = 40; + vectorAdd(leftleg->momentum, movement); + } + if (walkphase == 20){ + walkphase = 19; + vectorAdd(rightleg->momentum, movement); + }*/ + + /*float axis[3]; + vectorScale(axis, &leftleg->rotation[0], amount); + + if (walkphase == 0){ + //walkphase = 40; + vectorAdd(leftleg->angularmomentum, axis); + vectorAdd(rightleg->angularmomentum, axis); + }*/ + /*if (walkphase == 0){ + walkphase = 1; + vectorAdd(rightleg->momentum, movement); + }*/ + /*float axis[3]; + float movement[3]; + + if (walkphase == 0){ + unlockPart(LEFTLEG); + + vectorScale(axis, &leftleg->rotation[0], 5); + vectorAdd(leftleg->angularmomentum, axis); + + float temp[3]; + vectorScale(temp, &torso->rotation[6], -10); + vectorScale(movement, &torso->rotation[3], 5); + vectorAdd(movement, temp); + vectorAdd(torso->momentum, movement); + vectorAdd(leftleg->momentum, movement); + + walkphase = 40; + }*/ +} + +void Legoman::turn(float amount){ + float axis[3]; + if (isStanding()){ + vectorScale(axis, &torso->rotation[3], amount); + vectorCopy(torso->angularmomentum, axis); + } else{ + vectorScale(axis, &torso->rotation[3], amount*0.3); + vectorAdd(torso->angularmomentum, axis); + } +} + +void Legoman::hit(void){ + if (!lefthand->attached && !righthand->attached) return; + /*float leftdot = vectorDot(&lefthand->rotation[3], &torso->rotation[6]); + float rightdot = vectorDot(&righthand->rotation[3], &torso->rotation[6]); + if (leftdot < rightdot){ + hitside = LEFTHAND; + } else{ + hitside = RIGHTHAND; + }*/ + + if (hitside >= 10) hitside -= 9; + else hitside -= 2; + + if ((hitside & 1) && !lefthand->attached) hitside++; + if (!(hitside & 1) && !righthand->attached) hitside++; + + float axis[3]; + if (hitside & 1){ + vectorScale(axis, &lefthand->rotation[0], 20); + vectorCopy(lefthand->angularmomentum, axis); + } else{ + vectorScale(axis, &righthand->rotation[0], 20); + vectorCopy(righthand->angularmomentum, axis); + } +} + +void Legoman::jump(void){ + if (!leftleg->attached && !rightleg->attached) return; + if (jumpenabled){// == 0 && isOnGround()){ + float r = BLOCKHEIGHT*HEADHEIGHT/2; + float strength = (2*LEGHEIGHT + 2*WAISTHEIGHT + 2*TORSOHEIGHT + + 2*HANDHEIGHT + 4.0*PI*r*r*r)/3.0*getInvMass(); + float jumpvector[3] = {0, 100.0/strength, 0}; + + //vectorCopy(torso->momentum, jumpvector); + torso->momentum[1] = jumpvector[1]; + head->momentum[1] = 0;// jumpvector[1]; + waist->momentum[1] = 0;// jumpvector[1]; + leftleg->momentum[1] = 0;// jumpvector[1]; + rightleg->momentum[1] = 0;// jumpvector[1]; + lefthand->momentum[1] = 0;// jumpvector[1]; + righthand->momentum[1] = 0;// jumpvector[1]; + //vectorSet(head->momentum, 0, 0, 0); + //jumpphase = 150; + jumpsound->play(); + jumpenabled = false; + } + jumpphase = 2; +} + +bool Legoman::isOnGround(void){ + //if (!isStanding()) return false; + float wh = waist->position[1]; + if (wh > WAISTHEIGHT + 1.5) return false; + if (fabs(torso->momentum[1]) > 10) return false; + //if (fabs(head->momentum[1]) > 10) return false; + //if (fabs(waist->momentum[1]) > 3) return false; + return true; +} + +bool Legoman::isStanding(void){ + if (!leftleg->attached && !rightleg->attached) return false; + float headpos[3], torsopos[3]; + headsensor->getPosition(headpos); + torsosensor->getPosition(torsopos); + float posdiff[3]; + vectorSub(posdiff, headpos, torsopos); + float posdifflen = vectorLength(posdiff); + float angle = acos(posdiff[1]/posdifflen); + + if (angle < BALANCEANGLE) return true; + else return false; +} + +void Legoman::fallOff(void){ + if (dead) return; + if (rand()&1) fallsound1->play(); + else fallsound2->play(); + die(); + head->energy = 0; + torso->energy = 0; + lefthand->energy = 0; + righthand->energy = 0; + waist->energy = 0; + leftleg->energy = 0; + rightleg->energy = 0; +} + +void Legoman::releasePart(BodyPart *part){ + if (dead) return; + if (part == head){ + headlinks[0]->enabled = false; + headlinks[1]->enabled = false; + headlinks[2]->enabled = false; + head->attached = false; + //float move[3]; + //vectorScale(move, &head->rotation[3], 1); + //vectorAdd(head->position, move); + die(); + } else if (part == lefthand){ + lefthandlinks[0]->enabled = false; + lefthandlinks[1]->enabled = false; + lefthandlinks[2]->enabled = false; + lefthand->attached = false; + } else if (part == righthand){ + righthandlinks[0]->enabled = false; + righthandlinks[1]->enabled = false; + righthandlinks[2]->enabled = false; + righthand->attached = false; + } else if (part == leftleg){ + leftleglinks[0]->enabled = false; + leftleglinks[1]->enabled = false; + leftleglinks[2]->enabled = false; + leftleg->attached = false; + } else if (part == rightleg){ + rightleglinks[0]->enabled = false; + rightleglinks[1]->enabled = false; + rightleglinks[2]->enabled = false; + rightleg->attached = false; + } else if (part == torso){ + die(); + } + if (!lefthand->attached && !righthand->attached && + !leftleg->attached && !rightleg->attached) die(); +} + +void Legoman::die(void){ + if (dead) return; + alive = false; + lll->enabled = false; + rll->enabled = false; + gameOver(this); +} + +bool Legoman::isAlive(void){ + return alive; +} + +Legoman *Legoman::getOpponent(void){ + return opponent; +} + +void Legoman::drawVisuals(void){ + headvisual->draw(); + torsovisual->draw(); + lefthandvisual->draw(); + righthandvisual->draw(); + leftlegvisual->draw(); + rightlegvisual->draw(); +} + + + +DamageVisual::DamageVisual(BodyPart *object, Texture *texture, bool mirror, + float x1, float y1, float x2, float y2){ + this->object = object; + this->texture = texture; + + this->x1 = x1; + this->y1 = y1; + this->x2 = x2; + this->y2 = y2; + + float d = 3.0/512; + + if (mirror){ + this->tx1 = 1-d; + this->tx2 = 0+d+0.01; + } else{ + this->tx1 = 0+d+0.01; + this->tx2 = 1-d; + } + this->ty1 = 0+d; + this->ty2 = 1-d; +} + +void DamageVisual::draw(void){ + float energy = object->energy; + texture->enable(); + + glBegin(GL_QUADS); + if (energy > 0) glColor3f(1-energy, energy, 0); + else glColor3f(0.3, 0.3, 0.3); + + glTexCoord2f(tx1, ty1); + glVertex2f(x1, y1); + + glTexCoord2f(tx1, ty2); + glVertex2f(x1, y2); + + glTexCoord2f(tx2, ty2); + glVertex2f(x2, y2); + + glTexCoord2f(tx2, ty1); + glVertex2f(x2, y1); + glEnd(); +} diff --git a/src/legoman.h b/src/legoman.h index 61ae7a4..6f5401c 100644 --- a/src/legoman.h +++ b/src/legoman.h @@ -1,197 +1,197 @@ -#ifndef __LEGOMAN_H_INCLUDED__ -#define __LEGOMAN_H_INCLUDED__ - -class BodyPart; -class Sensor; -class Legoman; -class DamageVisual; - -#include "object.h" -#include "world.h" - -#define LEGHEIGHT 4 -#define WAISTHEIGHT 1 -#define TORSOHEIGHT 4 -#define HANDHEIGHT 6 -#define HEADHEIGHT 3 - -#define PLAYER1 1 -#define PLAYER2 2 - -#define LEFTLEG 1 -#define RIGHTLEG 2 -#define LEFTHAND 4 -#define RIGHTHAND 8 - - -const char LEFTLEGASC[] = DATAPATH"blockolegscaled.asc"; -const char RIGHTLEGASC[] = DATAPATH"blockolegscaled.asc"; -const char WAISTASC[] = DATAPATH"blockowaistscaled.asc"; -const char TORSOASC[] = DATAPATH"blockotorsoscaled.asc"; -const char LEFTARMASC[] = DATAPATH"leftarm.asc"; -const char RIGHTARMASC[] = DATAPATH"rightarm.asc"; -const char LEFTPALMASC[] = DATAPATH"leftpalm.asc"; -const char RIGHTPALMASC[] = DATAPATH"rightpalm.asc"; - - -#define MODELSCALE 0.12 -#define TORSOSCALE 0.115 - - -class BodyPart : public Object{ -private: - float energy; - float strength; - Legoman *parent; - - bool attached; - - int immortal; - -public: - BodyPart(Legoman *parent, float strength); - - void move(void); - - void hitForce(float speed, float *speed2, Object *source); - - void makeDamage(float amount); - - void reset(void); - - friend class DamageVisual; - friend class Legoman; -}; - -class Sensor{ -private: - float relativeposition[3]; - Object *object; - - float position[3], oldposition[3]; - float velocity[3], oldvelocity[3]; - float acceleration[3]; - -public: - Sensor(); - - void attach(Object *object, float *relativeposition); - void attach(Object *object); - void update(void); - - void getPosition(float *target); - void getVelocity(float *target); - void getAcceleration(float *target); -}; - -class Legoman{ -private: - int side; - - bool alive; - - BodyPart *head; - BodyPart *torso; - BodyPart *waist; - BodyPart *lefthand, *righthand; - BodyPart *leftleg, *rightleg; - - DamageVisual *headvisual; - DamageVisual *torsovisual; - DamageVisual *lefthandvisual, *righthandvisual; - DamageVisual *leftlegvisual, *rightlegvisual; - - ObjectLink *leftleglink, *rightleglink; - ObjectLink *lefthandlink, *righthandlink; - ObjectLink *lll, *rll; - - ObjectLink *leftleglinks[3], *rightleglinks[3]; - ObjectLink *lefthandlinks[3], *righthandlinks[3]; - ObjectLink *headlinks[3]; - - objectlist *harmfulobjects; - - Legoman *opponent; - - Sensor *headsensor, *torsosensor; - - int walkphase, walkdelay; - int jumpphase; - int hitside; - - bool jumpenabled; - int hitcounter; - - World *world; - - void balance(void); - void updateLegs(void); - bool isStanding(void); - bool isOnGround(void); - float getInvMass(void); - - void fallOff(void); - void releasePart(BodyPart *part); - void die(void); - -public: - Legoman(int side); - - void insertToWorld(World *world); - void heal(void); - - void addHarmfulObject(Object *object); - bool isHarmfulObject(Object *object); - - void addOpponent(Legoman *opponent); - - //Call once per frame - void update(void); - - //Lock both legs at the same time by calling - //lockLeg(LEFTLEG | RIGHTLEG); - void lockPart(int part); - void unlockPart(int part); - - //Relative movement - void move(float *movement); - - void turn(float amount); - void walk(float amount); - - void jump(void); - void hit(void); - - bool isAlive(void); - Legoman *getOpponent(void); - - void drawVisuals(); - - friend class BodyPart; - friend void drawEnd(int framecount); -}; - - - -extern Texture *damageHead; -extern Texture *damageTorso; -extern Texture *damageHand; -extern Texture *damageLeg; - - -class DamageVisual{ -private: - BodyPart *object; - float x1, y1, x2, y2; - float tx1, ty1, tx2, ty2; - Texture *texture; - -public: - DamageVisual(BodyPart *object, Texture *texture, bool mirror, - float x1, float y1, float x2, float y2); - - void draw(void); -}; - -#endif - +#ifndef __LEGOMAN_H_INCLUDED__ +#define __LEGOMAN_H_INCLUDED__ + +class BodyPart; +class Sensor; +class Legoman; +class DamageVisual; + +#include "object.h" +#include "world.h" + +#define LEGHEIGHT 4 +#define WAISTHEIGHT 1 +#define TORSOHEIGHT 4 +#define HANDHEIGHT 6 +#define HEADHEIGHT 3 + +#define PLAYER1 1 +#define PLAYER2 2 + +#define LEFTLEG 1 +#define RIGHTLEG 2 +#define LEFTHAND 4 +#define RIGHTHAND 8 + + +const char LEFTLEGASC[] = DATAPATH"blockolegscaled.asc"; +const char RIGHTLEGASC[] = DATAPATH"blockolegscaled.asc"; +const char WAISTASC[] = DATAPATH"blockowaistscaled.asc"; +const char TORSOASC[] = DATAPATH"blockotorsoscaled.asc"; +const char LEFTARMASC[] = DATAPATH"leftarm.asc"; +const char RIGHTARMASC[] = DATAPATH"rightarm.asc"; +const char LEFTPALMASC[] = DATAPATH"leftpalm.asc"; +const char RIGHTPALMASC[] = DATAPATH"rightpalm.asc"; + + +#define MODELSCALE 0.12 +#define TORSOSCALE 0.115 + + +class BodyPart : public Object{ +private: + float energy; + float strength; + Legoman *parent; + + bool attached; + + int immortal; + +public: + BodyPart(Legoman *parent, float strength); + + void move(void); + + void hitForce(float speed, float *speed2, Object *source); + + void makeDamage(float amount); + + void reset(void); + + friend class DamageVisual; + friend class Legoman; +}; + +class Sensor{ +private: + float relativeposition[3]; + Object *object; + + float position[3], oldposition[3]; + float velocity[3], oldvelocity[3]; + float acceleration[3]; + +public: + Sensor(); + + void attach(Object *object, float *relativeposition); + void attach(Object *object); + void update(void); + + void getPosition(float *target); + void getVelocity(float *target); + void getAcceleration(float *target); +}; + +class Legoman{ +private: + int side; + + bool alive; + + BodyPart *head; + BodyPart *torso; + BodyPart *waist; + BodyPart *lefthand, *righthand; + BodyPart *leftleg, *rightleg; + + DamageVisual *headvisual; + DamageVisual *torsovisual; + DamageVisual *lefthandvisual, *righthandvisual; + DamageVisual *leftlegvisual, *rightlegvisual; + + ObjectLink *leftleglink, *rightleglink; + ObjectLink *lefthandlink, *righthandlink; + ObjectLink *lll, *rll; + + ObjectLink *leftleglinks[3], *rightleglinks[3]; + ObjectLink *lefthandlinks[3], *righthandlinks[3]; + ObjectLink *headlinks[3]; + + objectlist *harmfulobjects; + + Legoman *opponent; + + Sensor *headsensor, *torsosensor; + + int walkphase, walkdelay; + int jumpphase; + int hitside; + + bool jumpenabled; + int hitcounter; + + World *world; + + void balance(void); + void updateLegs(void); + bool isStanding(void); + bool isOnGround(void); + float getInvMass(void); + + void fallOff(void); + void releasePart(BodyPart *part); + void die(void); + +public: + Legoman(int side); + + void insertToWorld(World *world); + void heal(void); + + void addHarmfulObject(Object *object); + bool isHarmfulObject(Object *object); + + void addOpponent(Legoman *opponent); + + //Call once per frame + void update(void); + + //Lock both legs at the same time by calling + //lockLeg(LEFTLEG | RIGHTLEG); + void lockPart(int part); + void unlockPart(int part); + + //Relative movement + void move(float *movement); + + void turn(float amount); + void walk(float amount); + + void jump(void); + void hit(void); + + bool isAlive(void); + Legoman *getOpponent(void); + + void drawVisuals(); + + friend class BodyPart; + friend void drawEnd(int framecount); +}; + + + +extern Texture *damageHead; +extern Texture *damageTorso; +extern Texture *damageHand; +extern Texture *damageLeg; + + +class DamageVisual{ +private: + BodyPart *object; + float x1, y1, x2, y2; + float tx1, ty1, tx2, ty2; + Texture *texture; + +public: + DamageVisual(BodyPart *object, Texture *texture, bool mirror, + float x1, float y1, float x2, float y2); + + void draw(void); +}; + +#endif + diff --git a/src/light.cpp b/src/light.cpp index b00c2c3..a69161f 100644 --- a/src/light.cpp +++ b/src/light.cpp @@ -1,192 +1,192 @@ -#include "main.h" - -#include "light.h" -#include "camera.h" -#include "vector.h" -#include "glapi.h" - -static int glnextlightnum = 0; - -static Light *lights[GL_MAX_LIGHTS]; - -Light::Light(void){ - setPosition(0, 0, 0); - setColor(1, 1, 1); - setSpecular(0, 0, 0); - setAttenuation(1, 0, 0); - setEnabled(false); - glnum = GL_LIGHT0 + glnextlightnum; - lights[glnextlightnum] = this; - glnextlightnum++; -} - -void Light::setPosition(float x, float y, float z){ - position[0] = x; - position[1] = y; - position[2] = z; - position[3] = 1; -} - -void Light::setDirection(float x, float y, float z){ - position[0] = -x; - position[1] = -y; - position[2] = -z; - position[3] = 0; -} - -void Light::setColor(float red, float green, float blue){ - diffuse[0] = red; - diffuse[1] = green; - diffuse[2] = blue; - diffuse[3] = 1; - glLightfv(glnum, GL_DIFFUSE, diffuse); -} - -void Light::setSpecular(float red, float green, float blue){ - specular[0] = red; - specular[1] = green; - specular[2] = blue; - specular[3] = 1; - glLightfv(glnum, GL_SPECULAR, specular); -} - -void Light::setAttenuation(float constant, float linear, float quadratic){ - attenuation[0] = constant; - attenuation[1] = linear; - attenuation[2] = quadratic; - glLightf(glnum, GL_CONSTANT_ATTENUATION, attenuation[0]); - glLightf(glnum, GL_LINEAR_ATTENUATION, attenuation[1]); - glLightf(glnum, GL_QUADRATIC_ATTENUATION, attenuation[2]); -} - -void Light::setEnabled(bool enabled){ - this->enabled = enabled; - if (enabled) glEnable(glnum); - else glDisable(glnum); -} - -void Light::glUpdate(void){ - glLightfv(glnum, GL_POSITION, position); -} - -extern Camera camera; - - -void Light::createFlare(void){ - glPushMatrix(); - - GLint viewport[4]; - glGetIntegerv(GL_VIEWPORT, viewport); - - int width = viewport[2]; - int height = viewport[3]; - - glTranslatef(position[0], position[1], position[2]); - - GLboolean lightingenabled = glIsEnabled(GL_LIGHTING); - glDisable(GL_LIGHTING); - - /*float cx=cameratarget.x-cameraposition.x; - float cy=cameratarget.y-cameraposition.y; - float cz=cameratarget.z-cameraposition.z; - float len=sqrt(cx*cx+cy*cy+cz*cz); - cx/=len; - cy/=len; - cz/=len;*/ - float dir[3]; - float cameratarget[3], cameraposition[3]; - camera.getTarget(cameratarget); - camera.getPosition(cameraposition); - vectorSub(dir, cameratarget, cameraposition); - vectorNormalize(dir); - - float dir2[3]; - vectorSub(dir2, position, cameraposition); - float distance = vectorDot(dir2, dir); - - /*float xd=(staticlightpositions[lightnumber].x-cameraposition.x)*cx; - float yd=(staticlightpositions[lightnumber].y-cameraposition.y)*cy; - float zd=(staticlightpositions[lightnumber].z-cameraposition.z)*cz; - float distance=xd+yd+zd;*/ - - - float screencoords[3]; - /*GLint viewport[4]; - glGetIntegerv(GL_VIEWPORT, viewport); - - int width=viewport[2]; - int height=viewport[3];*/ - - GLdouble modelviewm[16], projectionm[16]; - glGetDoublev(GL_MODELVIEW_MATRIX, modelviewm); - glGetDoublev(GL_PROJECTION_MATRIX, projectionm); - - GLdouble wx,wy,wz; - if (gluProject(0, 0, 0, modelviewm, projectionm, viewport, &wx, &wy, &wz) == GL_FALSE){ - printf("Failure\n"); - } - - screencoords[0] = (float)(2*wx-width)/width; - screencoords[1] = (float)(2*wy-height)/height; - screencoords[2] = wz; - - - //getPointCoordinates(screencoords); - //point3d screencoords = getPointCoordinates(0, 0, 0); - - glLoadIdentity(); - glTranslatef(screencoords[0], screencoords[1], 0); - glDisable(GL_DEPTH_TEST); - glEnable(GL_CULL_FACE); - glEnable(GL_BLEND); - - glBlendFunc(GL_ONE,GL_ONE); - //glEnable(GL_TEXTURE_2D); - //glBindTexture(GL_TEXTURE_2D, flaretexture->getId()); - - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - float sizey = 6.0/distance * 1.0;//staticlightflarebrightnesses[lightnumber]; - float sizex = sizey * height/width; - - if (distance>0.5){ - glBegin(GL_QUADS); - //glColor3f(staticlightflarebrightnesses[lightnumber],staticlightflarebrightnesses[lightnumber],staticlightflarebrightnesses[lightnumber]); - glColor3fv(diffuse); - - glTexCoord2f(0.0, 0.0); - glVertex2f(-sizex,sizey); - - glTexCoord2f(0.0, 1.0); - glVertex2f(-sizex,-sizey); - - glTexCoord2f(1.0, 1.0); - glVertex2f( sizex,-sizey); - - glTexCoord2f(1.0, 0.0); - glVertex2f( sizex,sizey); - glEnd(); - } - - //glDisable(GL_TEXTURE_2D); - - glDisable(GL_BLEND); - - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - - if (lightingenabled) glEnable(GL_LIGHTING); - glEnable(GL_DEPTH_TEST); - - glPopMatrix(); -} - -void updateLights(void){ - int i; - for (i = 0; i < glnextlightnum; i++){ - Light *light = lights[i]; - light->glUpdate(); - } -} +#include "main.h" + +#include "light.h" +#include "camera.h" +#include "vector.h" +#include "glapi.h" + +static int glnextlightnum = 0; + +static Light *lights[GL_MAX_LIGHTS]; + +Light::Light(void){ + setPosition(0, 0, 0); + setColor(1, 1, 1); + setSpecular(0, 0, 0); + setAttenuation(1, 0, 0); + setEnabled(false); + glnum = GL_LIGHT0 + glnextlightnum; + lights[glnextlightnum] = this; + glnextlightnum++; +} + +void Light::setPosition(float x, float y, float z){ + position[0] = x; + position[1] = y; + position[2] = z; + position[3] = 1; +} + +void Light::setDirection(float x, float y, float z){ + position[0] = -x; + position[1] = -y; + position[2] = -z; + position[3] = 0; +} + +void Light::setColor(float red, float green, float blue){ + diffuse[0] = red; + diffuse[1] = green; + diffuse[2] = blue; + diffuse[3] = 1; + glLightfv(glnum, GL_DIFFUSE, diffuse); +} + +void Light::setSpecular(float red, float green, float blue){ + specular[0] = red; + specular[1] = green; + specular[2] = blue; + specular[3] = 1; + glLightfv(glnum, GL_SPECULAR, specular); +} + +void Light::setAttenuation(float constant, float linear, float quadratic){ + attenuation[0] = constant; + attenuation[1] = linear; + attenuation[2] = quadratic; + glLightf(glnum, GL_CONSTANT_ATTENUATION, attenuation[0]); + glLightf(glnum, GL_LINEAR_ATTENUATION, attenuation[1]); + glLightf(glnum, GL_QUADRATIC_ATTENUATION, attenuation[2]); +} + +void Light::setEnabled(bool enabled){ + this->enabled = enabled; + if (enabled) glEnable(glnum); + else glDisable(glnum); +} + +void Light::glUpdate(void){ + glLightfv(glnum, GL_POSITION, position); +} + +extern Camera camera; + + +void Light::createFlare(void){ + glPushMatrix(); + + GLint viewport[4]; + glGetIntegerv(GL_VIEWPORT, viewport); + + int width = viewport[2]; + int height = viewport[3]; + + glTranslatef(position[0], position[1], position[2]); + + GLboolean lightingenabled = glIsEnabled(GL_LIGHTING); + glDisable(GL_LIGHTING); + + /*float cx=cameratarget.x-cameraposition.x; + float cy=cameratarget.y-cameraposition.y; + float cz=cameratarget.z-cameraposition.z; + float len=sqrt(cx*cx+cy*cy+cz*cz); + cx/=len; + cy/=len; + cz/=len;*/ + float dir[3]; + float cameratarget[3], cameraposition[3]; + camera.getTarget(cameratarget); + camera.getPosition(cameraposition); + vectorSub(dir, cameratarget, cameraposition); + vectorNormalize(dir); + + float dir2[3]; + vectorSub(dir2, position, cameraposition); + float distance = vectorDot(dir2, dir); + + /*float xd=(staticlightpositions[lightnumber].x-cameraposition.x)*cx; + float yd=(staticlightpositions[lightnumber].y-cameraposition.y)*cy; + float zd=(staticlightpositions[lightnumber].z-cameraposition.z)*cz; + float distance=xd+yd+zd;*/ + + + float screencoords[3]; + /*GLint viewport[4]; + glGetIntegerv(GL_VIEWPORT, viewport); + + int width=viewport[2]; + int height=viewport[3];*/ + + GLdouble modelviewm[16], projectionm[16]; + glGetDoublev(GL_MODELVIEW_MATRIX, modelviewm); + glGetDoublev(GL_PROJECTION_MATRIX, projectionm); + + GLdouble wx,wy,wz; + if (gluProject(0, 0, 0, modelviewm, projectionm, viewport, &wx, &wy, &wz) == GL_FALSE){ + printf("Failure\n"); + } + + screencoords[0] = (float)(2*wx-width)/width; + screencoords[1] = (float)(2*wy-height)/height; + screencoords[2] = wz; + + + //getPointCoordinates(screencoords); + //point3d screencoords = getPointCoordinates(0, 0, 0); + + glLoadIdentity(); + glTranslatef(screencoords[0], screencoords[1], 0); + glDisable(GL_DEPTH_TEST); + glEnable(GL_CULL_FACE); + glEnable(GL_BLEND); + + glBlendFunc(GL_ONE,GL_ONE); + //glEnable(GL_TEXTURE_2D); + //glBindTexture(GL_TEXTURE_2D, flaretexture->getId()); + + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + float sizey = 6.0/distance * 1.0;//staticlightflarebrightnesses[lightnumber]; + float sizex = sizey * height/width; + + if (distance>0.5){ + glBegin(GL_QUADS); + //glColor3f(staticlightflarebrightnesses[lightnumber],staticlightflarebrightnesses[lightnumber],staticlightflarebrightnesses[lightnumber]); + glColor3fv(diffuse); + + glTexCoord2f(0.0, 0.0); + glVertex2f(-sizex,sizey); + + glTexCoord2f(0.0, 1.0); + glVertex2f(-sizex,-sizey); + + glTexCoord2f(1.0, 1.0); + glVertex2f( sizex,-sizey); + + glTexCoord2f(1.0, 0.0); + glVertex2f( sizex,sizey); + glEnd(); + } + + //glDisable(GL_TEXTURE_2D); + + glDisable(GL_BLEND); + + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + if (lightingenabled) glEnable(GL_LIGHTING); + glEnable(GL_DEPTH_TEST); + + glPopMatrix(); +} + +void updateLights(void){ + int i; + for (i = 0; i < glnextlightnum; i++){ + Light *light = lights[i]; + light->glUpdate(); + } +} diff --git a/src/light.h b/src/light.h index 56715cc..10313aa 100644 --- a/src/light.h +++ b/src/light.h @@ -1,30 +1,30 @@ -#ifndef __LIGHT_H_INCLUDED__ -#define __LIGHT_H_INCLUDED__ - -class Light{ -private: - float position[4]; - float diffuse[4]; - float specular[4]; - float attenuation[3]; - bool enabled; - int glnum; - -public: - //Creates DISABLED light - Light(void); - - void setPosition(float x, float y, float z); - void setDirection(float x, float y, float z); - void setColor(float red, float green, float blue); - void setSpecular(float red, float green, float blue); - void setAttenuation(float constant, float linear, float quadratic); - void setEnabled(bool enabled); - void glUpdate(void); - void createFlare(void); -}; - -void updateLights(void); - -#endif - +#ifndef __LIGHT_H_INCLUDED__ +#define __LIGHT_H_INCLUDED__ + +class Light{ +private: + float position[4]; + float diffuse[4]; + float specular[4]; + float attenuation[3]; + bool enabled; + int glnum; + +public: + //Creates DISABLED light + Light(void); + + void setPosition(float x, float y, float z); + void setDirection(float x, float y, float z); + void setColor(float red, float green, float blue); + void setSpecular(float red, float green, float blue); + void setAttenuation(float constant, float linear, float quadratic); + void setEnabled(bool enabled); + void glUpdate(void); + void createFlare(void); +}; + +void updateLights(void); + +#endif + diff --git a/src/main.cpp b/src/main.cpp index e86217a..e65d8f7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,145 +1,145 @@ -#include "main.h" - -#include -#include -#include -#ifdef WIN32 -#include -#endif - -#include "audio.h" -#include "run.h" -#include "texture.h" -#include "fight.h" -#include "font.h" -#include "3dutils.h" - -#include "glapi.h" - -int screenwidth=1024; -int screenheight=768; -int screenbpp; - -void exitProgram(int code){ - SDL_Quit(); - //uninitAudio(); - exit(code); -} - -void changeResolution(int width, int height, bool fullscreen){ - int mode = SDL_OPENGL; - if (fullscreen) mode |= SDL_FULLSCREEN; - if (!SDL_SetVideoMode(width, height, screenbpp, mode)){ - fprintf(stderr,"Couldn't set %i*%i*%i opengl video mode: %s\n",screenwidth,screenheight,screenbpp,SDL_GetError()); - exitProgram(-1); - } - - setupOpengl(width, height); - - screenwidth = width; - screenheight = height; - - if (fullscreen) SDL_ShowCursor(SDL_DISABLE); - else SDL_ShowCursor(SDL_ENABLE); - - initScenes(); -} - - -bool keys[SDLK_LAST] = {false}; - -void handleKeydown(SDL_keysym *keysym){ - keys[keysym->sym] = true; -} - - -void handleKeyup(SDL_keysym *keysym){ - keys[keysym->sym] = false; -} - -void processEvents(void){ - SDL_Event event; - while (SDL_PollEvent(&event)){ - switch (event.type){ - case SDL_KEYDOWN: - handleKeydown(&event.key.keysym); - break; - case SDL_KEYUP: - handleKeyup(&event.key.keysym); - break; - case SDL_VIDEORESIZE: - screenwidth=event.resize.w; - screenheight=event.resize.h; - setupOpengl(screenwidth,screenheight); - break; - case SDL_QUIT: - exitProgram(0); - break; - } - } -} - -int getTime(void){ -#ifdef WIN32 - return timeGetTime(); -#else - return SDL_GetTicks(); -#endif -} - -int main(int argc, char *argv[]){ - //printf("Initializing SDL.\n"); - - if ((SDL_Init(SDL_INIT_VIDEO)==-1)){ - printf("Could not initialize SDL: %s.\n",SDL_GetError()); - exitProgram(-1); - } - - const SDL_VideoInfo *info=SDL_GetVideoInfo(); - if (!info){ - printf("Could not get video info with SDL: %s.\n",SDL_GetError()); - exitProgram(-1); - } - screenbpp=info->vfmt->BitsPerPixel; - SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5); - SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5); - SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5); - SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16); - SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); - - - atexit(SDL_Quit); - - SDL_WM_SetCaption("BlockoFighter 2",NULL); - - initAudio(); - - changeResolution(screenwidth, screenheight, false); - - //printf("SDL initialized.\n"); - - - - double calculatefps = 200.0; - int framecounter, oldframecounter = 0; - int currenttime; - int framesdrawn=0; - int skipframes; - int starttime = getTime(); - - while (1){ - do{ - currenttime = getTime()-starttime; - framecounter = calculatefps*currenttime/1000.0; - } while (oldframecounter == framecounter); - skipframes = framecounter - oldframecounter; - for (; skipframes > 0; skipframes--){ - calculateFrame(++oldframecounter); - } - //calculateFrame(oldframecounter++); - processEvents(); - drawFrame(framecounter); - framesdrawn++; - } - return 0; -} +#include "main.h" + +#include +#include +#include +#ifdef WIN32 +#include +#endif + +#include "audio.h" +#include "run.h" +#include "texture.h" +#include "fight.h" +#include "font.h" +#include "3dutils.h" + +#include "glapi.h" + +int screenwidth=1024; +int screenheight=768; +int screenbpp; + +void exitProgram(int code){ + SDL_Quit(); + //uninitAudio(); + exit(code); +} + +void changeResolution(int width, int height, bool fullscreen){ + int mode = SDL_OPENGL; + if (fullscreen) mode |= SDL_FULLSCREEN; + if (!SDL_SetVideoMode(width, height, screenbpp, mode)){ + fprintf(stderr,"Couldn't set %i*%i*%i opengl video mode: %s\n",screenwidth,screenheight,screenbpp,SDL_GetError()); + exitProgram(-1); + } + + setupOpengl(width, height); + + screenwidth = width; + screenheight = height; + + if (fullscreen) SDL_ShowCursor(SDL_DISABLE); + else SDL_ShowCursor(SDL_ENABLE); + + initScenes(); +} + + +bool keys[SDLK_LAST] = {false}; + +void handleKeydown(SDL_keysym *keysym){ + keys[keysym->sym] = true; +} + + +void handleKeyup(SDL_keysym *keysym){ + keys[keysym->sym] = false; +} + +void processEvents(void){ + SDL_Event event; + while (SDL_PollEvent(&event)){ + switch (event.type){ + case SDL_KEYDOWN: + handleKeydown(&event.key.keysym); + break; + case SDL_KEYUP: + handleKeyup(&event.key.keysym); + break; + case SDL_VIDEORESIZE: + screenwidth=event.resize.w; + screenheight=event.resize.h; + setupOpengl(screenwidth,screenheight); + break; + case SDL_QUIT: + exitProgram(0); + break; + } + } +} + +int getTime(void){ +#ifdef WIN32 + return timeGetTime(); +#else + return SDL_GetTicks(); +#endif +} + +int main(int argc, char *argv[]){ + //printf("Initializing SDL.\n"); + + if ((SDL_Init(SDL_INIT_VIDEO)==-1)){ + printf("Could not initialize SDL: %s.\n",SDL_GetError()); + exitProgram(-1); + } + + const SDL_VideoInfo *info=SDL_GetVideoInfo(); + if (!info){ + printf("Could not get video info with SDL: %s.\n",SDL_GetError()); + exitProgram(-1); + } + screenbpp=info->vfmt->BitsPerPixel; + SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5); + SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5); + SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5); + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16); + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + + + atexit(SDL_Quit); + + SDL_WM_SetCaption("BlockoFighter 2",NULL); + + initAudio(); + + changeResolution(screenwidth, screenheight, false); + + //printf("SDL initialized.\n"); + + + + double calculatefps = 200.0; + int framecounter, oldframecounter = 0; + int currenttime; + int framesdrawn=0; + int skipframes; + int starttime = getTime(); + + while (1){ + do{ + currenttime = getTime()-starttime; + framecounter = calculatefps*currenttime/1000.0; + } while (oldframecounter == framecounter); + skipframes = framecounter - oldframecounter; + for (; skipframes > 0; skipframes--){ + calculateFrame(++oldframecounter); + } + //calculateFrame(oldframecounter++); + processEvents(); + drawFrame(framecounter); + framesdrawn++; + } + return 0; +} diff --git a/src/main.h b/src/main.h index 3f3495c..a4be720 100644 --- a/src/main.h +++ b/src/main.h @@ -1,27 +1,27 @@ -#ifndef __MAIN_H_INCLUDED__ -#define __MAIN_H_INCLUDED__ - - -#ifdef WIN32 -#pragma warning(disable:4244) //Disable: conversion from 'double' to 'double', possible loss of data -#pragma warning(disable:4305) //Disable: truncation from 'const double' to 'double' -#endif - -#include - -#define DATAPATH "data/" -extern bool keys[SDLK_LAST]; - -void exitProgram(int code); -void changeResolution(int width, int height, bool fullscreen); -extern int screenwidth, screenheight; - -extern int debugcounter; -#ifdef DEBUG -#define DP printf("%s: %i (Debug counter: %i)\n",__FILE__,__LINE__,debugcounter++); -#else -#define DP -#endif - -#endif - +#ifndef __MAIN_H_INCLUDED__ +#define __MAIN_H_INCLUDED__ + + +#ifdef WIN32 +#pragma warning(disable:4244) //Disable: conversion from 'double' to 'double', possible loss of data +#pragma warning(disable:4305) //Disable: truncation from 'const double' to 'double' +#endif + +#include + +#define DATAPATH "data/" +extern bool keys[SDLK_LAST]; + +void exitProgram(int code); +void changeResolution(int width, int height, bool fullscreen); +extern int screenwidth, screenheight; + +extern int debugcounter; +#ifdef DEBUG +#define DP printf("%s: %i (Debug counter: %i)\n",__FILE__,__LINE__,debugcounter++); +#else +#define DP +#endif + +#endif + diff --git a/src/material.cpp b/src/material.cpp index 6af5c9e..3dddc3e 100644 --- a/src/material.cpp +++ b/src/material.cpp @@ -1,60 +1,60 @@ -#include "main.h" - -#include "material.h" -#include "glapi.h" -#include "graphics.h" - -Material::Material(void){ - setColor(1, 1, 1, 1); - this->texture = new Texture; -} - -bool Material::loadTexture(char *path){ - if (!this->texture){ - this->texture = new Texture; - } - if (this->texture->loadImage(path)){ - setColor(1, 1, 1, 1); - return true; - } - return false; -} - -void Material::freeTexture(void){ - this->texture->~Texture(); -} - -void Material::setColor(float red, float green, float blue, float alpha){ - color[0] = red; - color[1] = green; - color[2] = blue; - color[3] = alpha; -} - -const float* Material::getColor(void){ - return color; -} - -void Material::enable(void){ - enabled = true; - glColor4fv(color); - this->texture->enable(); -} - -void Material::disable(void){ - enabled = false; - this->texture->disable(); -} - -bool Material::isEnabled(void){ - return enabled; -} - -Texture* Material::getTexture(void){ - return this->texture; -} - -void Material::setTexture(Texture* tex){ - //this->texture->~Texture; - this->texture = tex; -} +#include "main.h" + +#include "material.h" +#include "glapi.h" +#include "graphics.h" + +Material::Material(void){ + setColor(1, 1, 1, 1); + this->texture = new Texture; +} + +bool Material::loadTexture(char *path){ + if (!this->texture){ + this->texture = new Texture; + } + if (this->texture->loadImage(path)){ + setColor(1, 1, 1, 1); + return true; + } + return false; +} + +void Material::freeTexture(void){ + this->texture->~Texture(); +} + +void Material::setColor(float red, float green, float blue, float alpha){ + color[0] = red; + color[1] = green; + color[2] = blue; + color[3] = alpha; +} + +const float* Material::getColor(void){ + return color; +} + +void Material::enable(void){ + enabled = true; + glColor4fv(color); + this->texture->enable(); +} + +void Material::disable(void){ + enabled = false; + this->texture->disable(); +} + +bool Material::isEnabled(void){ + return enabled; +} + +Texture* Material::getTexture(void){ + return this->texture; +} + +void Material::setTexture(Texture* tex){ + //this->texture->~Texture; + this->texture = tex; +} diff --git a/src/material.h b/src/material.h index db58878..38888bc 100644 --- a/src/material.h +++ b/src/material.h @@ -1,29 +1,29 @@ -#ifndef __MATERIAL_H_INCLUDED__ -#define __MATERIAL_H_INCLUDED__ - -#include -#include "texture.h" - -class Material{ -private: - Texture* texture; - float color[4]; - bool enabled; - -public: - Material(void); - bool loadTexture(char *path); - void freeTexture(void); - - void setColor(float red, float green, float blue, float alpha); - const float* getColor(void); - void enable(void); - void disable(void); - bool isEnabled(void); - Texture* getTexture(void); - void setTexture(Texture* tex); - -}; - -#endif - +#ifndef __MATERIAL_H_INCLUDED__ +#define __MATERIAL_H_INCLUDED__ + +#include +#include "texture.h" + +class Material{ +private: + Texture* texture; + float color[4]; + bool enabled; + +public: + Material(void); + bool loadTexture(char *path); + void freeTexture(void); + + void setColor(float red, float green, float blue, float alpha); + const float* getColor(void); + void enable(void); + void disable(void); + bool isEnabled(void); + Texture* getTexture(void); + void setTexture(Texture* tex); + +}; + +#endif + diff --git a/src/menu.cpp b/src/menu.cpp index e7b8c42..300caba 100644 --- a/src/menu.cpp +++ b/src/menu.cpp @@ -1,847 +1,847 @@ -#include "main.h" - -#include - -#include "legoblocks.h" -#include "camera.h" -#include "light.h" -#include "audio.h" -#include "object.h" -#include "appearance.h" -#include "sphere.h" -#include "vector.h" -#include "collision.h" -#include "utils.h" -#include "graphics.h" -#include "objectfactory.h" -#include "world.h" -#include "3dutils.h" -#include "legoman.h" -#include "font.h" -#include "run.h" -#include "menu.h" -#include "fight.h" - -#include "glapi.h" - -Camera titlecamera; -Light titlelight; -World *titleworld; - -Sound *changesound; -Sound *selectsound; -Sound *menumusic; - -bool menuinitialized = false; - -void initMenu(void){ - if (!menuinitialized){ - titleworld = new World(); - } - - titlelight.setColor(1, 1, 1); - titlelight.setSpecular(1, 1, 1); - titlelight.setPosition(-0.5, BLOCKHEIGHT*16, 0.5); - titlelight.setAttenuation(0.0, 0.0, 0.01); - - if (!menuinitialized){ - Object *lamp; - lamp = new Object(); - lamp->appearance = new LampAppearance(); - lamp->setPosition(-0.5, BLOCKHEIGHT*15.5, 0.5); - titleworld->addChild(lamp); - - - //Floor - BasicBlock *floorblock; - - floorblock = new BasicBlock(33, 1, 5); - floorblock->setPosition(-0.5, -BLOCKHEIGHT/2.0 + BLOCKHEIGHT*(4*3+1), 0.5-5); - floorblock->setColor(0, 1, 0); - titleworld->addChild(floorblock); - - floorblock = new BasicBlock(41, 1, 10); - floorblock->setPosition(8.5-5, -BLOCKHEIGHT/2.0, 0.5-2.5); - floorblock->setColor(0, 1, 0); - titleworld->addChild(floorblock); - - floorblock = new BasicBlock(1, 4*3, 1); - floorblock->setPosition(-14.5, BLOCKHEIGHT*4*3/2.0, 0.5-5); - floorblock->setColor(1, 0, 0); - titleworld->addChild(floorblock); - - floorblock = new BasicBlock(1, 4*3, 1); - floorblock->setPosition(13.5, BLOCKHEIGHT*4*3/2.0, 0.5-5); - floorblock->setColor(1, 0, 0); - titleworld->addChild(floorblock); - - - - - //Letters - - //B - /*int Bsize = 8; - int Bwidth = 5; - int Bletter[8][4] = { - {0, 0, 4, 1}, - {0, 4, 3, 1}, - {0, 8, 4, 1}, - {0, 1, 1, 7}, - //{3, 1, 2, 1}, - {2, 3, 3, 1}, - {2, 5, 3, 1}, - //{3, 7, 2, 1}, - {4, 0, 1, 3}, - {4, 6, 1, 3}};*/ - int Bsize = 10; - int Bwidth = 5; - int Bletter[10][4] = { - {0, 0, 4, 1}, - {0, 4, 4, 1}, - {0, 8, 4, 1}, - {0, 1, 1, 7}, - {3, 1, 2, 1}, - {3, 3, 2, 1}, - {3, 5, 2, 1}, - {3, 7, 2, 1}, - {4, 2, 1, 1}, - {4, 6, 1, 1}}; - - //l - int lsize = 2; - int lwidth = 4; - int lletter[2][4] = { - {0, 0, 4, 1}, - {0, 1, 1, 4}}; - - //o - int osize = 4; - int owidth = 4; - int oletter[4][4] = { - {0, 0, 4, 1}, - {0, 4, 4, 1}, - {0, 1, 1, 3}, - {3, 1, 1, 3}}; - - //c - int csize = 5; - int cwidth = 4; - int cletter[5][4] = { - {0, 0, 4, 1}, - {0, 4, 4, 1}, - {0, 1, 1, 3}, - {3, 1, 1, 1}, - {3, 3, 1, 1}}; - /* {1, 0, 2, 1}, - {1, 4, 2, 1}, - {0, 1, 1, 3}, - {3, 1, 1, 1}, - {3, 3, 1, 1}};*/ - - //k - int ksize = 6; - int kwidth = 4; - int kletter[6][4] = { - {0, 0, 1, 5}, - {1, 2, 2, 1}, - {2, 1, 2, 1}, - {2, 3, 2, 1}, - {3, 0, 1, 1}, - {3, 4, 1, 1}}; - /* {0, 0, 1, 5}, - {1, 2, 1, 1}, - {2, 1, 1, 1}, - {2, 3, 1, 1}, - {3, 0, 1, 1}, - {3, 4, 1, 1}};*/ - - //F - int Fsize = 3; - int Fwidth = 3; - int Fletter[3][4] = { - {0, 0, 1, 7}, - {0, 4, 3, 1}, - {0, 7, 6, 1}}; - - //i - int isize = 1; - int iwidth = 1; - int iletter[1][4] = { - {0, 0, 1, 4}}; - - //g - int gsize = 5; - int gwidth = 4; - int gletter[5][4] = { - {0, 0, 4, 1}, - {0, 4, 4, 1}, - {0, 1, 1, 3}, - {3, 1, 1, 1}, - {2, 2, 2, 1}}; - - //h - int hsize = 3; - int hwidth = 1; - int hletter[3][4] = { - {0, 0, 1, 5}, - {3, 0, 1, 5}, - {0, 2, 4, 1}}; - - //t - int tsize = 2; - int twidth = 4; - int tletter[2][4] = { - {3, 0, 1, 6}, - {0, 6, 7, 1}}; - - //e - int esize = 5; - int ewidth = 4; - int eletter[5][4] = { - {0, 0, 4, 1}, - {0, 4, 4, 1}, - {0, 2, 3, 1}, - {0, 1, 1, 1}, - {0, 3, 1, 1}}; - - //r - int rsize = 6; - int rwidth = 4; - int rletter[6][4] = { - {0, 0, 1, 5}, - {0, 2, 3, 1}, - {0, 4, 3, 1}, - {2, 1, 2, 1}, - {3, 0, 1, 1}, - {2, 3, 2, 1}}; - /*int rsize = 5; - int rwidth = 4; - int rletter[5][4] = { - {0, 0, 1, 5}, - {0, 2, 3, 1}, - {0, 4, 3, 1}, - {3, 0, 1, 2}, - {3, 3, 1, 1}};*/ - - #define LETTERCOUNT 6 - int lettersizes[LETTERCOUNT] = { - Bsize, - lsize, - osize, - csize, - ksize, - osize - }; - int letterwidths[LETTERCOUNT] = { - Bwidth, - lwidth, - owidth, - cwidth, - kwidth, - owidth - }; - int *letters[LETTERCOUNT] = { - &Bletter[0][0], - &lletter[0][0], - &oletter[0][0], - &cletter[0][0], - &kletter[0][0], - &oletter[0][0] - }; - - #define LETTERCOUNT2 7 - int lettersizes2[LETTERCOUNT2] = { - Fsize, - isize, - gsize, - hsize, - tsize, - esize, - rsize - }; - int letterwidths2[LETTERCOUNT2] = { - Fwidth, - iwidth, - gwidth, - hwidth, - twidth, - ewidth, - rwidth - }; - int *letters2[LETTERCOUNT2] = { - &Fletter[0][0], - &iletter[0][0], - &gletter[0][0], - &hletter[0][0], - &tletter[0][0], - &eletter[0][0], - &rletter[0][0] - }; - BasicBlock *letterblock; - - float z = 0.5; - int i, j; - int dx = -15; - int dy = BLOCKHEIGHT*(4*3+1); - int dz = -5; - for (i = 0; i < LETTERCOUNT; i++){ - int size = lettersizes[i]; - int width = letterwidths[i]; - for (j = 0; j < size; j++){ - int x = letters[i][j*4+0]; - int y = letters[i][j*4+1]*3; - int w = letters[i][j*4+2]; - int h = letters[i][j*4+3]*3; - letterblock = new BasicBlock(w, h, 1); - letterblock->setPosition(dx+x+w/2.0, dy+BLOCKHEIGHT*(y+h/2.0), dz+z + randomf(0.1)); - letterblock->setColor(1, 0.5, 1); - titleworld->addChild(letterblock); - } - dx += width + 1; - } - dx = -5; - dy = 0; - dz = 0; - for (i = 0; i < LETTERCOUNT2; i++){ - int size = lettersizes2[i]; - int width = letterwidths2[i]; - for (j = 0; j < size; j++){ - int x = letters2[i][j*4+0]; - int y = letters2[i][j*4+1]*3; - int w = letters2[i][j*4+2]; - int h = letters2[i][j*4+3]*3; - letterblock = new BasicBlock(w, h, 1); - letterblock->setPosition(dx+x+w/2.0, dy+BLOCKHEIGHT*(y+h/2.0), dz+z + randomf(0.1)); - //float rotate[3] = {0, randomf(0.1), 0}; - //matrixCreateRotation(letterblock->rotation, rotate); - letterblock->setColor(1, 0.5, 1); - titleworld->addChild(letterblock); - } - dx += width + 1; - } - - - - Object *flower; - - flower = new Object(); - flower->appearance = new FlowerAppearance(FLOWER_RED, FLOWER_WHITE, FLOWER_YELLOW); - flower->setPosition(-7.5, 0, 1.5); - titleworld->addChild(flower); - - flower = new Object(); - flower->appearance = new FlowerAppearance(FLOWER_YELLOW, FLOWER_RED, FLOWER_YELLOW); - flower->setPosition(-11.5, 0, -2.5); - titleworld->addChild(flower); - - flower = new Object(); - flower->appearance = new FlowerAppearance(FLOWER_WHITE, FLOWER_WHITE, FLOWER_RED); - flower->setPosition(-14.5, 0, 0.5); - titleworld->addChild(flower); - - - - changesound = new Sound(DATAPATH"menuchange.wav"); - selectsound = new Sound(DATAPATH"menuselect.wav"); - menumusic = new Sound(DATAPATH"menu.mp3", true); - } - - titleworld->prepare(); - - menuinitialized = true; -} - -#define MODEMAIN 0 -#define MODEOPTIONS 1 - -#define MAINSTART 0 -#define MAINOPTIONS 1 -#define MAINQUIT 2 - -#define OPTIONSRESOLUTION 0 -#define OPTIONSFULLSCREEN 1 -#define OPTIONSDETAIL 2 -#define OPTIONSRETURN 3 - -int menuoption = MAINSTART; -int maxoption; -int menumode = MODEMAIN; -bool pressed = false; - -float obx1, oby1, obx2, oby2; -float bx1, by1, bx2, by2; -float interpolator = 1.0; - -int xres, yres; -int oldresolution; -int resolution = 2; -bool fullscreen = false; -int olddetail; -int detail = 2; - -#define RESOLUTIONCOUNT 6 -int resolutions[RESOLUTIONCOUNT][2] = { - {640, 480}, - {800, 600}, - {1024, 768}, - {1280, 960}, - {1280, 1024}, - {1600, 1200} -}; - -#define DETAILCOUNT 4 -char *details[DETAILCOUNT] = {"Off", "Low", "Medium", "High"}; - -int menurestartcounter = -1; - -void menuRestart(void){ - menurestartcounter = 0; -} - -void menuMain(void){ - interpolator = 0.0; - menumode = MODEMAIN; - menuoption = MAINOPTIONS; - obx1 = bx1; - oby1 = by1; - obx2 = bx2; - oby2 = by2; -} - -float menufade; - -int gamestart = 0; - -bool loading = true; - -void menuStartGame(void){ - menumusic->fadeOut(300); - gamestart = 200; - menurestartcounter = -1; -} - -void menuStartGame2(void){ - titlelight.setEnabled(false); - changeGameMode(FIGHTMODE); - startFight(); - menurestartcounter = -1; -} - -void menuOptions(void){ - interpolator = 0.0; - menumode = MODEOPTIONS; - menuoption = OPTIONSRESOLUTION; - obx1 = bx1; - oby1 = by1; - obx2 = bx2; - oby2 = by2; - oldresolution = resolution; - olddetail = detail; -} - -int quitcounter = -1; - -void menuEscPressed(void){ - menurestartcounter = -1; - //menumusic->stop(); - menumusic->fadeOut(200); - quitcounter = 0; -} - -void menuQuit(void){ - exitProgram(0); -} - - -void menuResolution(int dir){ - resolution += dir; - if (resolution < 0) resolution = 0; - if (resolution >= RESOLUTIONCOUNT) resolution = RESOLUTIONCOUNT-1; - //resolution = (resolution + RESOLUTIONCOUNT) % RESOLUTIONCOUNT; -} - -void calculateMenu(int framecount){ - if (framecount == 1){ - menumusic->setVolume(0); - menumusic->play(); - menumusic->fadeIn(300); - } - if (menurestartcounter != -1){ - menurestartcounter++; - if (menurestartcounter == 300){ - menumusic->play(); - menumusic->fadeIn(100); - menurestartcounter = -1; - } - } - - - menufade = -1; - - titlelight.setEnabled(true); - - if (framecount < 200){ - menufade = 1-framecount/200.0; - } else{ - loading = false; - } - - if (gamestart > 0){ - gamestart--; - if (gamestart == 0){ - menuStartGame2(); - } - menufade = (200-gamestart)/200.0; - } - - if (quitcounter != -1){ - menufade = quitcounter/200.0; - quitcounter++; - if (quitcounter == 200) menuQuit(); - } - - float cameratarget[3] = {0, 0, 0}; - titlecamera.setPosition(sin(framecount*0.001)*2-8, sin(framecount*0.0033)*2+15, cos(framecount*0.001)*2+25); - titlecamera.setTarget(cameratarget); - - titleworld->move(); - - xres = resolutions[resolution][0]; - yres = resolutions[resolution][1]; - - switch(menumode){ - case MODEMAIN: - maxoption = 2; - - bx1 = 0.03; - by1 = 0.49; - bx2 = 0.68; - by2 = 0.96; - - break; - case MODEOPTIONS: - maxoption = 3; - - bx1 = 0.1; - by1 = 0.3; - bx2 = 0.9; - by2 = 0.8; - break; - } - - if (interpolator < 1.0){ - interpolator += 0.02; - } else{ - interpolator = 1.0; - if (menufade == -1){ - if (keys[SDLK_DOWN]){ - if (!pressed){ - /*if (menuoption < maxoption){ - menuoption++; - changesound->play(); - }*/ - menuoption = (menuoption + 1)%(maxoption+1); - changesound->play(); - pressed = true; - } - } else if (keys[SDLK_UP]){ - if (!pressed){ - /*if (menuoption > 0){ - menuoption--; - changesound->play(); - }*/ - menuoption = (menuoption + maxoption)%(maxoption+1); - changesound->play(); - pressed = true; - } - } else if (keys[SDLK_LEFT]){ - if (!pressed){ - switch(menumode){ - case MODEOPTIONS: - switch(menuoption){ - case OPTIONSRESOLUTION: - menuResolution(-1); - break; - case OPTIONSDETAIL: - if (detail > 0) detail--; - break; - } - break; - } - selectsound->play(); - pressed = true; - } - } else if (keys[SDLK_RIGHT]){ - if (!pressed){ - switch(menumode){ - case MODEOPTIONS: - switch(menuoption){ - case OPTIONSRESOLUTION: - menuResolution(1); - break; - case OPTIONSDETAIL: - if (detail < DETAILCOUNT-1) detail++; - break; - } - break; - } - selectsound->play(); - pressed = true; - } - } else if (keys[SDLK_ESCAPE]){ - if (!pressed){ - switch(menumode){ - case MODEMAIN: - if (menuoption != MAINQUIT){ - menuoption = MAINQUIT; - changesound->play(); - } - else menuEscPressed(); - break; - case MODEOPTIONS: - selectsound->play(); - resolution = oldresolution; - detail = olddetail; - menuMain(); - break; - } - pressed = true; - } - } else if (keys[SDLK_RETURN]){ - if (!pressed){ - switch(menumode){ - case MODEMAIN: - switch(menuoption){ - case MAINSTART: - menuStartGame(); - break; - case MAINOPTIONS: - menuOptions(); - break; - case MAINQUIT: - menuEscPressed(); - break; - } - break; - case MODEOPTIONS: - switch(menuoption){ - case OPTIONSRESOLUTION: - if (resolution != oldresolution) changeResolution(xres, yres, fullscreen); - oldresolution = resolution; - break; - case OPTIONSFULLSCREEN: - fullscreen = !fullscreen; - changeResolution(xres, yres, fullscreen); - break; - case OPTIONSDETAIL: - setDetail(detail); - olddetail = detail; - break; - case OPTIONSRETURN: - if (resolution != oldresolution){ - changeResolution(xres, yres, fullscreen); - oldresolution = resolution; - } - if (detail != olddetail){ - setDetail(detail); - olddetail = detail; - } - menuMain(); - break; - } - break; - } - selectsound->play(); - pressed = true; - } - } else pressed = false; - } - } -} - -void drawMenu(int framecount){ - //createSkyBox(0, -20, 0, 400, 200, 400); - createSkyBox(-200, -200, -200, 400, 400, 400); - glLoadIdentity(); - titlecamera.glUpdate(); - - updateLights(); - - - - titleworld->draw(); - - - flaretexture->enable(); - titlelight.createFlare(); - flaretexture->disable(); - - - /*//2D-view - glDisable(GL_LIGHTING); - glDisable(GL_CULL_FACE); - glDisable(GL_DEPTH_TEST); - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - gluOrtho2D(0, 1, 1, 0); - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity();*/ - enable2D(); - - glColor3f(1, 1, 1); - print(0.73, 0.55, - "Programming:\n" \ - " Miika Sell\n" \ - " Juha Kaarlas\n" \ - "\n" \ - "Graphics:\n" \ - " Miika Sell\n" \ - " Juha Kaarlas\n" \ - "\n" \ - "Musics:\n" \ - " Osmand" - , 0.03); - - print(0.35, 0.965, "http://blockofighter.kicks-ass.net/", 0.02); - - print(0.88, 0.96, "Version 2.0", 0.02); - - tuxtexture->enable(); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glColor3f(1, 1, 1); - - float tuxx = 0.9; - float tuxy = 0.02; - float tuxw = 0.1*3/4; - float tuxh = 0.1; - glBegin(GL_QUADS); - glTexCoord2f(0, 0); - glVertex2f(tuxx, tuxy); - - glTexCoord2f(1, 0); - glVertex2f(tuxx+tuxw, tuxy); - - glTexCoord2f(1, 1); - glVertex2f(tuxx+tuxw, tuxy+tuxh); - - glTexCoord2f(0, 1); - glVertex2f(tuxx, tuxy+tuxh); - glEnd(); - tuxtexture->disable(); - - glColor3f(1, 1, 1); - print(0.88, 0.12, "supported", 0.02); - - - glEnable(GL_BLEND); - glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - glColor4f(0, 0, 0, 0.5); - float x1, y1, x2, y2; - x1 = (1-interpolator)*obx1 + interpolator*bx1; - y1 = (1-interpolator)*oby1 + interpolator*by1; - x2 = (1-interpolator)*obx2 + interpolator*bx2; - y2 = (1-interpolator)*oby2 + interpolator*by2; - glBegin(GL_QUADS); - glVertex2f(x1, y1); - glVertex2f(x2, y1); - glVertex2f(x2, y2); - glVertex2f(x1, y2); - glEnd(); - - if (interpolator == 1.0){ - switch(menumode){ - case MODEMAIN: - glColor3f(1, 1, 1); - print(0.05, 0.5, "Start game", 0.1); - print(0.05, 0.65, "Options", 0.1); - print(0.05, 0.8, "Quit", 0.1); - - x1 = 0.04; - x2 = 0.67; - switch(menuoption){ - case 0: - y1 = 0.5; - y2 = 0.65; - break; - case 1: - y1 = 0.65; - y2 = 0.79; - break; - case 2: - y1 = 0.79; - y2 = 0.95; - break; - } - break; - case MODEOPTIONS: - glColor3f(1, 1, 1); - char resolutionstring[22]; - sprintf(resolutionstring, "Resolution: %ix%i", xres, yres); - print(0.12, 0.32, resolutionstring, 0.07); - print(0.12, 0.42, "Toggle fullscreen", 0.07); - char detailstring[22]; - sprintf(detailstring, "Detail: %s", details[detail]); - print(0.12, 0.52, detailstring, 0.07); - print(0.12, 0.68, "Save and return", 0.07); - - x1 = 0.11; - x2 = 0.89; - switch(menuoption){ - case 0: - y1 = 0.32; - y2 = 0.42; - break; - case 1: - y1 = 0.42; - y2 = 0.52; - break; - case 2: - y1 = 0.52; - y2 = 0.62; - break; - case 3: - y1 = 0.68; - y2 = 0.78; - break; - } - break; - } - - glLineWidth(2); - - glColor4f(sin(framecount*0.04)*0.4+0.6, sin(framecount*0.04)*0.4+0.6, sin(framecount*0.04)*0.4+0.6, 0.5); - glBegin(GL_LINE_LOOP); - glVertex2f(x1, y1); - glVertex2f(x2, y1); - glVertex2f(x2, y2); - glVertex2f(x1, y2); - glEnd(); - } - - - if (menufade != -1){ - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glColor4f(0, 0, 0, menufade); - glBegin(GL_QUADS); - glVertex2f(0, 0); - glVertex2f(1, 0); - glVertex2f(1, 1); - glVertex2f(0, 1); - glEnd(); - if (loading){ - glColor4f(menufade, menufade, menufade, menufade); - print(0.08, 0.4, "Loading...", 0.2); - } - } - - disable2D(); - /*//Back to 3D-view - glPopMatrix(); - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glMatrixMode(GL_MODELVIEW);*/ -} +#include "main.h" + +#include + +#include "legoblocks.h" +#include "camera.h" +#include "light.h" +#include "audio.h" +#include "object.h" +#include "appearance.h" +#include "sphere.h" +#include "vector.h" +#include "collision.h" +#include "utils.h" +#include "graphics.h" +#include "objectfactory.h" +#include "world.h" +#include "3dutils.h" +#include "legoman.h" +#include "font.h" +#include "run.h" +#include "menu.h" +#include "fight.h" + +#include "glapi.h" + +Camera titlecamera; +Light titlelight; +World *titleworld; + +Sound *changesound; +Sound *selectsound; +Sound *menumusic; + +bool menuinitialized = false; + +void initMenu(void){ + if (!menuinitialized){ + titleworld = new World(); + } + + titlelight.setColor(1, 1, 1); + titlelight.setSpecular(1, 1, 1); + titlelight.setPosition(-0.5, BLOCKHEIGHT*16, 0.5); + titlelight.setAttenuation(0.0, 0.0, 0.01); + + if (!menuinitialized){ + Object *lamp; + lamp = new Object(); + lamp->appearance = new LampAppearance(); + lamp->setPosition(-0.5, BLOCKHEIGHT*15.5, 0.5); + titleworld->addChild(lamp); + + + //Floor + BasicBlock *floorblock; + + floorblock = new BasicBlock(33, 1, 5); + floorblock->setPosition(-0.5, -BLOCKHEIGHT/2.0 + BLOCKHEIGHT*(4*3+1), 0.5-5); + floorblock->setColor(0, 1, 0); + titleworld->addChild(floorblock); + + floorblock = new BasicBlock(41, 1, 10); + floorblock->setPosition(8.5-5, -BLOCKHEIGHT/2.0, 0.5-2.5); + floorblock->setColor(0, 1, 0); + titleworld->addChild(floorblock); + + floorblock = new BasicBlock(1, 4*3, 1); + floorblock->setPosition(-14.5, BLOCKHEIGHT*4*3/2.0, 0.5-5); + floorblock->setColor(1, 0, 0); + titleworld->addChild(floorblock); + + floorblock = new BasicBlock(1, 4*3, 1); + floorblock->setPosition(13.5, BLOCKHEIGHT*4*3/2.0, 0.5-5); + floorblock->setColor(1, 0, 0); + titleworld->addChild(floorblock); + + + + + //Letters + + //B + /*int Bsize = 8; + int Bwidth = 5; + int Bletter[8][4] = { + {0, 0, 4, 1}, + {0, 4, 3, 1}, + {0, 8, 4, 1}, + {0, 1, 1, 7}, + //{3, 1, 2, 1}, + {2, 3, 3, 1}, + {2, 5, 3, 1}, + //{3, 7, 2, 1}, + {4, 0, 1, 3}, + {4, 6, 1, 3}};*/ + int Bsize = 10; + int Bwidth = 5; + int Bletter[10][4] = { + {0, 0, 4, 1}, + {0, 4, 4, 1}, + {0, 8, 4, 1}, + {0, 1, 1, 7}, + {3, 1, 2, 1}, + {3, 3, 2, 1}, + {3, 5, 2, 1}, + {3, 7, 2, 1}, + {4, 2, 1, 1}, + {4, 6, 1, 1}}; + + //l + int lsize = 2; + int lwidth = 4; + int lletter[2][4] = { + {0, 0, 4, 1}, + {0, 1, 1, 4}}; + + //o + int osize = 4; + int owidth = 4; + int oletter[4][4] = { + {0, 0, 4, 1}, + {0, 4, 4, 1}, + {0, 1, 1, 3}, + {3, 1, 1, 3}}; + + //c + int csize = 5; + int cwidth = 4; + int cletter[5][4] = { + {0, 0, 4, 1}, + {0, 4, 4, 1}, + {0, 1, 1, 3}, + {3, 1, 1, 1}, + {3, 3, 1, 1}}; + /* {1, 0, 2, 1}, + {1, 4, 2, 1}, + {0, 1, 1, 3}, + {3, 1, 1, 1}, + {3, 3, 1, 1}};*/ + + //k + int ksize = 6; + int kwidth = 4; + int kletter[6][4] = { + {0, 0, 1, 5}, + {1, 2, 2, 1}, + {2, 1, 2, 1}, + {2, 3, 2, 1}, + {3, 0, 1, 1}, + {3, 4, 1, 1}}; + /* {0, 0, 1, 5}, + {1, 2, 1, 1}, + {2, 1, 1, 1}, + {2, 3, 1, 1}, + {3, 0, 1, 1}, + {3, 4, 1, 1}};*/ + + //F + int Fsize = 3; + int Fwidth = 3; + int Fletter[3][4] = { + {0, 0, 1, 7}, + {0, 4, 3, 1}, + {0, 7, 6, 1}}; + + //i + int isize = 1; + int iwidth = 1; + int iletter[1][4] = { + {0, 0, 1, 4}}; + + //g + int gsize = 5; + int gwidth = 4; + int gletter[5][4] = { + {0, 0, 4, 1}, + {0, 4, 4, 1}, + {0, 1, 1, 3}, + {3, 1, 1, 1}, + {2, 2, 2, 1}}; + + //h + int hsize = 3; + int hwidth = 1; + int hletter[3][4] = { + {0, 0, 1, 5}, + {3, 0, 1, 5}, + {0, 2, 4, 1}}; + + //t + int tsize = 2; + int twidth = 4; + int tletter[2][4] = { + {3, 0, 1, 6}, + {0, 6, 7, 1}}; + + //e + int esize = 5; + int ewidth = 4; + int eletter[5][4] = { + {0, 0, 4, 1}, + {0, 4, 4, 1}, + {0, 2, 3, 1}, + {0, 1, 1, 1}, + {0, 3, 1, 1}}; + + //r + int rsize = 6; + int rwidth = 4; + int rletter[6][4] = { + {0, 0, 1, 5}, + {0, 2, 3, 1}, + {0, 4, 3, 1}, + {2, 1, 2, 1}, + {3, 0, 1, 1}, + {2, 3, 2, 1}}; + /*int rsize = 5; + int rwidth = 4; + int rletter[5][4] = { + {0, 0, 1, 5}, + {0, 2, 3, 1}, + {0, 4, 3, 1}, + {3, 0, 1, 2}, + {3, 3, 1, 1}};*/ + + #define LETTERCOUNT 6 + int lettersizes[LETTERCOUNT] = { + Bsize, + lsize, + osize, + csize, + ksize, + osize + }; + int letterwidths[LETTERCOUNT] = { + Bwidth, + lwidth, + owidth, + cwidth, + kwidth, + owidth + }; + int *letters[LETTERCOUNT] = { + &Bletter[0][0], + &lletter[0][0], + &oletter[0][0], + &cletter[0][0], + &kletter[0][0], + &oletter[0][0] + }; + + #define LETTERCOUNT2 7 + int lettersizes2[LETTERCOUNT2] = { + Fsize, + isize, + gsize, + hsize, + tsize, + esize, + rsize + }; + int letterwidths2[LETTERCOUNT2] = { + Fwidth, + iwidth, + gwidth, + hwidth, + twidth, + ewidth, + rwidth + }; + int *letters2[LETTERCOUNT2] = { + &Fletter[0][0], + &iletter[0][0], + &gletter[0][0], + &hletter[0][0], + &tletter[0][0], + &eletter[0][0], + &rletter[0][0] + }; + BasicBlock *letterblock; + + float z = 0.5; + int i, j; + int dx = -15; + int dy = BLOCKHEIGHT*(4*3+1); + int dz = -5; + for (i = 0; i < LETTERCOUNT; i++){ + int size = lettersizes[i]; + int width = letterwidths[i]; + for (j = 0; j < size; j++){ + int x = letters[i][j*4+0]; + int y = letters[i][j*4+1]*3; + int w = letters[i][j*4+2]; + int h = letters[i][j*4+3]*3; + letterblock = new BasicBlock(w, h, 1); + letterblock->setPosition(dx+x+w/2.0, dy+BLOCKHEIGHT*(y+h/2.0), dz+z + randomf(0.1)); + letterblock->setColor(1, 0.5, 1); + titleworld->addChild(letterblock); + } + dx += width + 1; + } + dx = -5; + dy = 0; + dz = 0; + for (i = 0; i < LETTERCOUNT2; i++){ + int size = lettersizes2[i]; + int width = letterwidths2[i]; + for (j = 0; j < size; j++){ + int x = letters2[i][j*4+0]; + int y = letters2[i][j*4+1]*3; + int w = letters2[i][j*4+2]; + int h = letters2[i][j*4+3]*3; + letterblock = new BasicBlock(w, h, 1); + letterblock->setPosition(dx+x+w/2.0, dy+BLOCKHEIGHT*(y+h/2.0), dz+z + randomf(0.1)); + //float rotate[3] = {0, randomf(0.1), 0}; + //matrixCreateRotation(letterblock->rotation, rotate); + letterblock->setColor(1, 0.5, 1); + titleworld->addChild(letterblock); + } + dx += width + 1; + } + + + + Object *flower; + + flower = new Object(); + flower->appearance = new FlowerAppearance(FLOWER_RED, FLOWER_WHITE, FLOWER_YELLOW); + flower->setPosition(-7.5, 0, 1.5); + titleworld->addChild(flower); + + flower = new Object(); + flower->appearance = new FlowerAppearance(FLOWER_YELLOW, FLOWER_RED, FLOWER_YELLOW); + flower->setPosition(-11.5, 0, -2.5); + titleworld->addChild(flower); + + flower = new Object(); + flower->appearance = new FlowerAppearance(FLOWER_WHITE, FLOWER_WHITE, FLOWER_RED); + flower->setPosition(-14.5, 0, 0.5); + titleworld->addChild(flower); + + + + changesound = new Sound(DATAPATH"menuchange.wav"); + selectsound = new Sound(DATAPATH"menuselect.wav"); + menumusic = new Sound(DATAPATH"menu.mp3", true); + } + + titleworld->prepare(); + + menuinitialized = true; +} + +#define MODEMAIN 0 +#define MODEOPTIONS 1 + +#define MAINSTART 0 +#define MAINOPTIONS 1 +#define MAINQUIT 2 + +#define OPTIONSRESOLUTION 0 +#define OPTIONSFULLSCREEN 1 +#define OPTIONSDETAIL 2 +#define OPTIONSRETURN 3 + +int menuoption = MAINSTART; +int maxoption; +int menumode = MODEMAIN; +bool pressed = false; + +float obx1, oby1, obx2, oby2; +float bx1, by1, bx2, by2; +float interpolator = 1.0; + +int xres, yres; +int oldresolution; +int resolution = 2; +bool fullscreen = false; +int olddetail; +int detail = 2; + +#define RESOLUTIONCOUNT 6 +int resolutions[RESOLUTIONCOUNT][2] = { + {640, 480}, + {800, 600}, + {1024, 768}, + {1280, 960}, + {1280, 1024}, + {1600, 1200} +}; + +#define DETAILCOUNT 4 +char *details[DETAILCOUNT] = {"Off", "Low", "Medium", "High"}; + +int menurestartcounter = -1; + +void menuRestart(void){ + menurestartcounter = 0; +} + +void menuMain(void){ + interpolator = 0.0; + menumode = MODEMAIN; + menuoption = MAINOPTIONS; + obx1 = bx1; + oby1 = by1; + obx2 = bx2; + oby2 = by2; +} + +float menufade; + +int gamestart = 0; + +bool loading = true; + +void menuStartGame(void){ + menumusic->fadeOut(300); + gamestart = 200; + menurestartcounter = -1; +} + +void menuStartGame2(void){ + titlelight.setEnabled(false); + changeGameMode(FIGHTMODE); + startFight(); + menurestartcounter = -1; +} + +void menuOptions(void){ + interpolator = 0.0; + menumode = MODEOPTIONS; + menuoption = OPTIONSRESOLUTION; + obx1 = bx1; + oby1 = by1; + obx2 = bx2; + oby2 = by2; + oldresolution = resolution; + olddetail = detail; +} + +int quitcounter = -1; + +void menuEscPressed(void){ + menurestartcounter = -1; + //menumusic->stop(); + menumusic->fadeOut(200); + quitcounter = 0; +} + +void menuQuit(void){ + exitProgram(0); +} + + +void menuResolution(int dir){ + resolution += dir; + if (resolution < 0) resolution = 0; + if (resolution >= RESOLUTIONCOUNT) resolution = RESOLUTIONCOUNT-1; + //resolution = (resolution + RESOLUTIONCOUNT) % RESOLUTIONCOUNT; +} + +void calculateMenu(int framecount){ + if (framecount == 1){ + menumusic->setVolume(0); + menumusic->play(); + menumusic->fadeIn(300); + } + if (menurestartcounter != -1){ + menurestartcounter++; + if (menurestartcounter == 300){ + menumusic->play(); + menumusic->fadeIn(100); + menurestartcounter = -1; + } + } + + + menufade = -1; + + titlelight.setEnabled(true); + + if (framecount < 200){ + menufade = 1-framecount/200.0; + } else{ + loading = false; + } + + if (gamestart > 0){ + gamestart--; + if (gamestart == 0){ + menuStartGame2(); + } + menufade = (200-gamestart)/200.0; + } + + if (quitcounter != -1){ + menufade = quitcounter/200.0; + quitcounter++; + if (quitcounter == 200) menuQuit(); + } + + float cameratarget[3] = {0, 0, 0}; + titlecamera.setPosition(sin(framecount*0.001)*2-8, sin(framecount*0.0033)*2+15, cos(framecount*0.001)*2+25); + titlecamera.setTarget(cameratarget); + + titleworld->move(); + + xres = resolutions[resolution][0]; + yres = resolutions[resolution][1]; + + switch(menumode){ + case MODEMAIN: + maxoption = 2; + + bx1 = 0.03; + by1 = 0.49; + bx2 = 0.68; + by2 = 0.96; + + break; + case MODEOPTIONS: + maxoption = 3; + + bx1 = 0.1; + by1 = 0.3; + bx2 = 0.9; + by2 = 0.8; + break; + } + + if (interpolator < 1.0){ + interpolator += 0.02; + } else{ + interpolator = 1.0; + if (menufade == -1){ + if (keys[SDLK_DOWN]){ + if (!pressed){ + /*if (menuoption < maxoption){ + menuoption++; + changesound->play(); + }*/ + menuoption = (menuoption + 1)%(maxoption+1); + changesound->play(); + pressed = true; + } + } else if (keys[SDLK_UP]){ + if (!pressed){ + /*if (menuoption > 0){ + menuoption--; + changesound->play(); + }*/ + menuoption = (menuoption + maxoption)%(maxoption+1); + changesound->play(); + pressed = true; + } + } else if (keys[SDLK_LEFT]){ + if (!pressed){ + switch(menumode){ + case MODEOPTIONS: + switch(menuoption){ + case OPTIONSRESOLUTION: + menuResolution(-1); + break; + case OPTIONSDETAIL: + if (detail > 0) detail--; + break; + } + break; + } + selectsound->play(); + pressed = true; + } + } else if (keys[SDLK_RIGHT]){ + if (!pressed){ + switch(menumode){ + case MODEOPTIONS: + switch(menuoption){ + case OPTIONSRESOLUTION: + menuResolution(1); + break; + case OPTIONSDETAIL: + if (detail < DETAILCOUNT-1) detail++; + break; + } + break; + } + selectsound->play(); + pressed = true; + } + } else if (keys[SDLK_ESCAPE]){ + if (!pressed){ + switch(menumode){ + case MODEMAIN: + if (menuoption != MAINQUIT){ + menuoption = MAINQUIT; + changesound->play(); + } + else menuEscPressed(); + break; + case MODEOPTIONS: + selectsound->play(); + resolution = oldresolution; + detail = olddetail; + menuMain(); + break; + } + pressed = true; + } + } else if (keys[SDLK_RETURN]){ + if (!pressed){ + switch(menumode){ + case MODEMAIN: + switch(menuoption){ + case MAINSTART: + menuStartGame(); + break; + case MAINOPTIONS: + menuOptions(); + break; + case MAINQUIT: + menuEscPressed(); + break; + } + break; + case MODEOPTIONS: + switch(menuoption){ + case OPTIONSRESOLUTION: + if (resolution != oldresolution) changeResolution(xres, yres, fullscreen); + oldresolution = resolution; + break; + case OPTIONSFULLSCREEN: + fullscreen = !fullscreen; + changeResolution(xres, yres, fullscreen); + break; + case OPTIONSDETAIL: + setDetail(detail); + olddetail = detail; + break; + case OPTIONSRETURN: + if (resolution != oldresolution){ + changeResolution(xres, yres, fullscreen); + oldresolution = resolution; + } + if (detail != olddetail){ + setDetail(detail); + olddetail = detail; + } + menuMain(); + break; + } + break; + } + selectsound->play(); + pressed = true; + } + } else pressed = false; + } + } +} + +void drawMenu(int framecount){ + //createSkyBox(0, -20, 0, 400, 200, 400); + createSkyBox(-200, -200, -200, 400, 400, 400); + glLoadIdentity(); + titlecamera.glUpdate(); + + updateLights(); + + + + titleworld->draw(); + + + flaretexture->enable(); + titlelight.createFlare(); + flaretexture->disable(); + + + /*//2D-view + glDisable(GL_LIGHTING); + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + gluOrtho2D(0, 1, 1, 0); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity();*/ + enable2D(); + + glColor3f(1, 1, 1); + print(0.73, 0.55, + "Programming:\n" \ + " Miika Sell\n" \ + " Juha Kaarlas\n" \ + "\n" \ + "Graphics:\n" \ + " Miika Sell\n" \ + " Juha Kaarlas\n" \ + "\n" \ + "Musics:\n" \ + " Osmand" + , 0.03); + + print(0.35, 0.965, "http://blockofighter.kicks-ass.net/", 0.02); + + print(0.88, 0.96, "Version 2.0", 0.02); + + tuxtexture->enable(); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glColor3f(1, 1, 1); + + float tuxx = 0.9; + float tuxy = 0.02; + float tuxw = 0.1*3/4; + float tuxh = 0.1; + glBegin(GL_QUADS); + glTexCoord2f(0, 0); + glVertex2f(tuxx, tuxy); + + glTexCoord2f(1, 0); + glVertex2f(tuxx+tuxw, tuxy); + + glTexCoord2f(1, 1); + glVertex2f(tuxx+tuxw, tuxy+tuxh); + + glTexCoord2f(0, 1); + glVertex2f(tuxx, tuxy+tuxh); + glEnd(); + tuxtexture->disable(); + + glColor3f(1, 1, 1); + print(0.88, 0.12, "supported", 0.02); + + + glEnable(GL_BLEND); + glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + glColor4f(0, 0, 0, 0.5); + float x1, y1, x2, y2; + x1 = (1-interpolator)*obx1 + interpolator*bx1; + y1 = (1-interpolator)*oby1 + interpolator*by1; + x2 = (1-interpolator)*obx2 + interpolator*bx2; + y2 = (1-interpolator)*oby2 + interpolator*by2; + glBegin(GL_QUADS); + glVertex2f(x1, y1); + glVertex2f(x2, y1); + glVertex2f(x2, y2); + glVertex2f(x1, y2); + glEnd(); + + if (interpolator == 1.0){ + switch(menumode){ + case MODEMAIN: + glColor3f(1, 1, 1); + print(0.05, 0.5, "Start game", 0.1); + print(0.05, 0.65, "Options", 0.1); + print(0.05, 0.8, "Quit", 0.1); + + x1 = 0.04; + x2 = 0.67; + switch(menuoption){ + case 0: + y1 = 0.5; + y2 = 0.65; + break; + case 1: + y1 = 0.65; + y2 = 0.79; + break; + case 2: + y1 = 0.79; + y2 = 0.95; + break; + } + break; + case MODEOPTIONS: + glColor3f(1, 1, 1); + char resolutionstring[22]; + sprintf(resolutionstring, "Resolution: %ix%i", xres, yres); + print(0.12, 0.32, resolutionstring, 0.07); + print(0.12, 0.42, "Toggle fullscreen", 0.07); + char detailstring[22]; + sprintf(detailstring, "Detail: %s", details[detail]); + print(0.12, 0.52, detailstring, 0.07); + print(0.12, 0.68, "Save and return", 0.07); + + x1 = 0.11; + x2 = 0.89; + switch(menuoption){ + case 0: + y1 = 0.32; + y2 = 0.42; + break; + case 1: + y1 = 0.42; + y2 = 0.52; + break; + case 2: + y1 = 0.52; + y2 = 0.62; + break; + case 3: + y1 = 0.68; + y2 = 0.78; + break; + } + break; + } + + glLineWidth(2); + + glColor4f(sin(framecount*0.04)*0.4+0.6, sin(framecount*0.04)*0.4+0.6, sin(framecount*0.04)*0.4+0.6, 0.5); + glBegin(GL_LINE_LOOP); + glVertex2f(x1, y1); + glVertex2f(x2, y1); + glVertex2f(x2, y2); + glVertex2f(x1, y2); + glEnd(); + } + + + if (menufade != -1){ + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glColor4f(0, 0, 0, menufade); + glBegin(GL_QUADS); + glVertex2f(0, 0); + glVertex2f(1, 0); + glVertex2f(1, 1); + glVertex2f(0, 1); + glEnd(); + if (loading){ + glColor4f(menufade, menufade, menufade, menufade); + print(0.08, 0.4, "Loading...", 0.2); + } + } + + disable2D(); + /*//Back to 3D-view + glPopMatrix(); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW);*/ +} diff --git a/src/menu.h b/src/menu.h index 8d8ef73..0abb04f 100644 --- a/src/menu.h +++ b/src/menu.h @@ -1,19 +1,19 @@ -#ifndef __MENU_H_INCLUDED__ -#define __MENU_H_INCLUDED__ - -#include - -#include "texture.h" -#include "audio.h" - -extern int detail; - -extern Texture *tuxtexture; - -void initMenu(void); -void calculateMenu(int framecount); -void drawMenu(int framecount); -void menuRestart(void); - -#endif - +#ifndef __MENU_H_INCLUDED__ +#define __MENU_H_INCLUDED__ + +#include + +#include "texture.h" +#include "audio.h" + +extern int detail; + +extern Texture *tuxtexture; + +void initMenu(void); +void calculateMenu(int framecount); +void drawMenu(int framecount); +void menuRestart(void); + +#endif + diff --git a/src/mesh.cpp b/src/mesh.cpp index 6f30542..ad1f087 100644 --- a/src/mesh.cpp +++ b/src/mesh.cpp @@ -1,379 +1,379 @@ -#include "main.h" - -#include "mesh.h" -#include "vector.h" -#include "sphere.h" -#include "collision.h" -#include "audio.h" - -#include - -#include "glapi.h" - -Vertex::Vertex(void){ - vectorSet(position, 0, 0, 0); - vectorSet(normal, 0, 0, 0); -} - -Vertex::Vertex(float x, float y, float z){ - vectorSet(position, x, y, z); - vectorSet(normal, x, y, z); - vectorNormalize(normal); -} - -Vertex::Vertex(float x, float y, float z, float nx, float ny, float nz){ - vectorSet(position, x, y, z); - vectorSet(normal, nx, ny, nz); -} - -void Vertex::setTexCoords(float u, float v){ - this->texcoords[0] = u; - this->texcoords[1] = v; -} - -Polygon::Polygon(void){ - vertexcount = 0; - edgecount = 0; - smooth = false; - realsmooth = false; -} - - - -Mesh::Mesh(void){ - vertexcount = 0; - polygoncount = 0; - edgecount = 0; -} - -Mesh::~Mesh(void){ - delete [] polygons; - delete [] vertices; -} - -void Mesh::createPlanes(void){ - int i; - for (i = 0; i < polygoncount; i++){ - class Polygon *polygon = &this->polygons[i]; - if (polygon->vertexcount >= 3){ - float v1[3], v2[3]; - vectorSub(v1, polygon->vertices[1]->position, - polygon->vertices[0]->position); - vectorSub(v2, polygon->vertices[2]->position, - polygon->vertices[0]->position); - vectorCross(polygon->planenormal, v1, v2); - vectorNormalize(polygon->planenormal); - - polygon->planedistance = -vectorDot(polygon->vertices[0]->position, polygon->planenormal); - } - } -} - -void Mesh::createVertexnormals(void){ - int i, j, ii; - bool connect; - float normal[3]; - for (i = 0; i < vertexcount; i++){ - bool found = false; - vectorSet(normal, 0, 0, 0); - for (j = 0; j < polygoncount; j++){ - connect = false; - class Polygon *polygon = &polygons[j]; - for (ii = 0;ii < polygon->vertexcount; ii++){ - if (polygons[j].vertices[ii] == &(vertices[i])){ - connect = true; - } - } - if (connect){ - vectorAdd(normal, polygon->planenormal); - found = true; - } - } - if (found){ - vectorNormalize(vertices[i].normal, normal); - } - } - for (j = 0; j < polygoncount; j++){ - class Polygon *polygon = &polygons[j]; - if (!polygon->realsmooth) polygon->smooth = true; - } -} - -void Mesh::createEdges(void){ - int maxedgecount = 0; - int i; - for (i = 0; i < polygoncount; i++){ - class Polygon *polygon = &polygons[i]; - maxedgecount += polygon->vertexcount; - } - - edgecount = 0; - int j, k; - Edge *edges = new Edge[maxedgecount]; - for (i = 0; i < polygoncount; i++){ - class Polygon *polygon = &polygons[i]; - polygon->edges = new Edge *[polygon->vertexcount]; - for (j = 1; j <= polygon->vertexcount; j++){ - Vertex *v1 = polygon->vertices[j-1]; - Vertex *v2 = polygon->vertices[j%polygon->vertexcount]; - - bool found = false; - for (k = 0; k < edgecount; k++){ - if (edges[k].v2 == v1 && edges[k].v1 == v2){ - found = true; - edges[k].p2 = polygon; - break; - } - } - - if (!found){ - edges[edgecount].v1 = v1; - edges[edgecount].v2 = v2; - edges[edgecount].p1 = polygon; - edges[edgecount].p2 = NULL; - edgecount++; - } - } - } - - this->edges = new Edge[edgecount]; - //printf("%i\n", edgecount); - for (i = 0; i < edgecount; i++){ - this->edges[i].v1 = edges[i].v1; - this->edges[i].v2 = edges[i].v2; - this->edges[i].p1 = edges[i].p1; - this->edges[i].p2 = edges[i].p2; - - class Polygon *p; - p = edges[i].p1; - p->edges[p->edgecount++] = &this->edges[i]; - p = edges[i].p2; - p->edges[p->edgecount++] = &this->edges[i]; - //printf("%p, %p\n", edges[i].p1, edges[i].p2); - } - - delete[] edges; -} - - -float Mesh::calculateScale(float targetLength, int axis){ - - float min = 0.0; - float max = 0.0; - - for (int i=0; i < this->vertexcount; i++){ - if (this->vertices->position[axis] > max){ - max = this->vertices->position[axis]; - } - if (this->vertices->position[axis] < min){ - min = this->vertices->position[axis]; - } - } - return fabs(targetLength / (max - min)); -} - -/* ei toimi kunnolla kaikille objekteille (kädet ok, jalat ja torso ei) */ -void Mesh::scale(float targetLength, int axis){ - float newscale = this->calculateScale(targetLength, axis); - this->scale(newscale); -} - -/* ei toimi kunnolla kaikille objekteille (kädet ok, jalat ja torso ei)*/ -void Mesh::scale(float scale){ - for (int i=0; i < this->vertexcount; i++){ - this->vertices->position[0] *= scale; - this->vertices->position[1] *= scale; - this->vertices->position[2] *= scale; - } - this->createVertexnormals(); - this->createPlanes(); -} - -MeshObject::MeshObject(Mesh *mesh){ - this->mesh = mesh; - this->appearance = new MeshAppearance(mesh); - this->geometry = new MeshShape(this); -} - - - -MeshAppearance::MeshAppearance(Mesh *mesh){ - this->mesh = mesh; -} - - - -void MeshAppearance::draw(void){ - //glDisable(GL_CULL_FACE); - glColor4fv(this->material.getColor()); - this->material.enable(); - - int i, j; - - for (i = 0; i < mesh->polygoncount; i++){ - class Polygon *polygon = &mesh->polygons[i]; - - glBegin(GL_TRIANGLE_FAN); - - if (!polygon->smooth) glNormal3fv(polygon->planenormal); - - for (j = 0; j < polygon->vertexcount; j++){ - Vertex *vertex = polygon->vertices[j]; - - if (polygon->smooth) glNormal3fv(vertex->normal); - glVertex3fv(vertex->position); - - } - - - glEnd(); - } - - - glDisable(GL_DEPTH); - glDisable(GL_LIGHTING); - glLineWidth(5.0); - glBegin(GL_LINES); - for (i = 0; i < mesh->edgecount; i++){ - glColor3f(0, 0, 0); - glVertex3fv(mesh->edges[i].v1->position); - glVertex3fv(mesh->edges[i].v2->position); - } - - glEnd(); - glEnable(GL_LIGHTING); - glEnable(GL_DEPTH); - - - this->material.disable(); - //glEnable(GL_CULL_FACE); -} - - - - - - -MeshShape::MeshShape(MeshObject *object) : Shape(object){ - mesh = object->mesh; -} - -MeshShape::MeshShape(Object *object, Mesh *mesh) : Shape(object){ - this->mesh = mesh; -} - -bool MeshShape::checkCollision(Object *target){ - return target->geometry->checkCollisionPeer(this); -} - -float MeshShape::calculateMomentOfInertia(float *rotationvector){ - if (vectorDot(rotationvector, rotationvector) < EPSILON) return 0; - int i; - float j = 0; - for (i = 0; i < mesh->vertexcount; i++){ - float proj[3]; - vectorProject(proj, mesh->vertices[i].position, rotationvector); - vectorSub(proj, mesh->vertices[i].position, proj); - //float r = vectorLength(proj); - float r2 = vectorDot(proj, proj); - j += r2; - } - return j / i; -} - -bool MeshShape::checkCollisionPeer(SphereShape *target){ - float position[3] = {0, 0, 0}; - target->object->transformPoint(position, position); - object->unTransformPoint(position, position); - - float normal[3]; - float contactpoint[3]; - float r = target->getRadius(); - - if (checkSphereMeshCollision(position, r, mesh, normal, contactpoint)){ - vectorScale(normal, -1); - object->transformVector(normal, normal); - object->transformPoint(contactpoint, contactpoint); - - addCollision(object, target->object, normal, contactpoint); - - //vectorAdd(contactnormal, normal); - - return true; - } - - return false; -} - -//extern Sound *shotsound; - -bool MeshShape::checkCollisionPeer(MeshShape *target){ - float normal[3]; - float contactpoint[3]; - - bool collided = false; - - int i; - - Mesh *sourcemesh, *targetmesh; - - sourcemesh = this->mesh; - targetmesh = target->mesh; - for (i = 0; i < sourcemesh->vertexcount; i++){ - Vertex *vertex = &sourcemesh->vertices[i]; - float vertexposition[3]; - object->transformPoint(vertexposition, vertex->position); - target->object->unTransformPoint(vertexposition, vertexposition); - - if (checkPointMeshCollision(vertexposition, targetmesh, normal, contactpoint)){ - target->object->transformVector(normal, normal); - target->object->transformPoint(contactpoint, contactpoint); - - if (vectorIsZero(contactpoint)){ - vectorSet(contactpoint, 0, 0, 0); - } - addCollision(object, target->object, normal, contactpoint); - collided = true; - } - } - - sourcemesh = target->mesh; - targetmesh = this->mesh; - for (i = 0; i < sourcemesh->vertexcount; i++){ - Vertex *vertex = &sourcemesh->vertices[i]; - float vertexposition[3]; - target->object->transformPoint(vertexposition, vertex->position); - object->unTransformPoint(vertexposition, vertexposition); - - if (checkPointMeshCollision(vertexposition, targetmesh, normal, contactpoint)){ - object->transformVector(normal, normal); - object->transformPoint(contactpoint, contactpoint); - - addCollision(target->object, object, normal, contactpoint); - collided = true; - } - } - - sourcemesh = this->mesh; - targetmesh = target->mesh; - for (i = 0; i < sourcemesh->edgecount; i++){ - Edge *edge = &sourcemesh->edges[i]; - float v1[3], v2[3]; - object->transformPoint(v1, edge->v1->position); - target->object->unTransformPoint(v1, v1); - - object->transformPoint(v2, edge->v2->position); - target->object->unTransformPoint(v2, v2); - - if (checkEdgeMeshCollision(v1, v2, targetmesh, normal, contactpoint)){ - target->object->transformVector(normal, normal); - target->object->transformPoint(contactpoint, contactpoint); - - addCollision(object, target->object, normal, contactpoint); - collided = true; - } - } - - return collided; -} - +#include "main.h" + +#include "mesh.h" +#include "vector.h" +#include "sphere.h" +#include "collision.h" +#include "audio.h" + +#include + +#include "glapi.h" + +Vertex::Vertex(void){ + vectorSet(position, 0, 0, 0); + vectorSet(normal, 0, 0, 0); +} + +Vertex::Vertex(float x, float y, float z){ + vectorSet(position, x, y, z); + vectorSet(normal, x, y, z); + vectorNormalize(normal); +} + +Vertex::Vertex(float x, float y, float z, float nx, float ny, float nz){ + vectorSet(position, x, y, z); + vectorSet(normal, nx, ny, nz); +} + +void Vertex::setTexCoords(float u, float v){ + this->texcoords[0] = u; + this->texcoords[1] = v; +} + +Polygon::Polygon(void){ + vertexcount = 0; + edgecount = 0; + smooth = false; + realsmooth = false; +} + + + +Mesh::Mesh(void){ + vertexcount = 0; + polygoncount = 0; + edgecount = 0; +} + +Mesh::~Mesh(void){ + delete [] polygons; + delete [] vertices; +} + +void Mesh::createPlanes(void){ + int i; + for (i = 0; i < polygoncount; i++){ + class Polygon *polygon = &this->polygons[i]; + if (polygon->vertexcount >= 3){ + float v1[3], v2[3]; + vectorSub(v1, polygon->vertices[1]->position, + polygon->vertices[0]->position); + vectorSub(v2, polygon->vertices[2]->position, + polygon->vertices[0]->position); + vectorCross(polygon->planenormal, v1, v2); + vectorNormalize(polygon->planenormal); + + polygon->planedistance = -vectorDot(polygon->vertices[0]->position, polygon->planenormal); + } + } +} + +void Mesh::createVertexnormals(void){ + int i, j, ii; + bool connect; + float normal[3]; + for (i = 0; i < vertexcount; i++){ + bool found = false; + vectorSet(normal, 0, 0, 0); + for (j = 0; j < polygoncount; j++){ + connect = false; + class Polygon *polygon = &polygons[j]; + for (ii = 0;ii < polygon->vertexcount; ii++){ + if (polygons[j].vertices[ii] == &(vertices[i])){ + connect = true; + } + } + if (connect){ + vectorAdd(normal, polygon->planenormal); + found = true; + } + } + if (found){ + vectorNormalize(vertices[i].normal, normal); + } + } + for (j = 0; j < polygoncount; j++){ + class Polygon *polygon = &polygons[j]; + if (!polygon->realsmooth) polygon->smooth = true; + } +} + +void Mesh::createEdges(void){ + int maxedgecount = 0; + int i; + for (i = 0; i < polygoncount; i++){ + class Polygon *polygon = &polygons[i]; + maxedgecount += polygon->vertexcount; + } + + edgecount = 0; + int j, k; + Edge *edges = new Edge[maxedgecount]; + for (i = 0; i < polygoncount; i++){ + class Polygon *polygon = &polygons[i]; + polygon->edges = new Edge *[polygon->vertexcount]; + for (j = 1; j <= polygon->vertexcount; j++){ + Vertex *v1 = polygon->vertices[j-1]; + Vertex *v2 = polygon->vertices[j%polygon->vertexcount]; + + bool found = false; + for (k = 0; k < edgecount; k++){ + if (edges[k].v2 == v1 && edges[k].v1 == v2){ + found = true; + edges[k].p2 = polygon; + break; + } + } + + if (!found){ + edges[edgecount].v1 = v1; + edges[edgecount].v2 = v2; + edges[edgecount].p1 = polygon; + edges[edgecount].p2 = NULL; + edgecount++; + } + } + } + + this->edges = new Edge[edgecount]; + //printf("%i\n", edgecount); + for (i = 0; i < edgecount; i++){ + this->edges[i].v1 = edges[i].v1; + this->edges[i].v2 = edges[i].v2; + this->edges[i].p1 = edges[i].p1; + this->edges[i].p2 = edges[i].p2; + + class Polygon *p; + p = edges[i].p1; + p->edges[p->edgecount++] = &this->edges[i]; + p = edges[i].p2; + p->edges[p->edgecount++] = &this->edges[i]; + //printf("%p, %p\n", edges[i].p1, edges[i].p2); + } + + delete[] edges; +} + + +float Mesh::calculateScale(float targetLength, int axis){ + + float min = 0.0; + float max = 0.0; + + for (int i=0; i < this->vertexcount; i++){ + if (this->vertices->position[axis] > max){ + max = this->vertices->position[axis]; + } + if (this->vertices->position[axis] < min){ + min = this->vertices->position[axis]; + } + } + return fabs(targetLength / (max - min)); +} + +/* ei toimi kunnolla kaikille objekteille (kädet ok, jalat ja torso ei) */ +void Mesh::scale(float targetLength, int axis){ + float newscale = this->calculateScale(targetLength, axis); + this->scale(newscale); +} + +/* ei toimi kunnolla kaikille objekteille (kädet ok, jalat ja torso ei)*/ +void Mesh::scale(float scale){ + for (int i=0; i < this->vertexcount; i++){ + this->vertices->position[0] *= scale; + this->vertices->position[1] *= scale; + this->vertices->position[2] *= scale; + } + this->createVertexnormals(); + this->createPlanes(); +} + +MeshObject::MeshObject(Mesh *mesh){ + this->mesh = mesh; + this->appearance = new MeshAppearance(mesh); + this->geometry = new MeshShape(this); +} + + + +MeshAppearance::MeshAppearance(Mesh *mesh){ + this->mesh = mesh; +} + + + +void MeshAppearance::draw(void){ + //glDisable(GL_CULL_FACE); + glColor4fv(this->material.getColor()); + this->material.enable(); + + int i, j; + + for (i = 0; i < mesh->polygoncount; i++){ + class Polygon *polygon = &mesh->polygons[i]; + + glBegin(GL_TRIANGLE_FAN); + + if (!polygon->smooth) glNormal3fv(polygon->planenormal); + + for (j = 0; j < polygon->vertexcount; j++){ + Vertex *vertex = polygon->vertices[j]; + + if (polygon->smooth) glNormal3fv(vertex->normal); + glVertex3fv(vertex->position); + + } + + + glEnd(); + } + + + glDisable(GL_DEPTH); + glDisable(GL_LIGHTING); + glLineWidth(5.0); + glBegin(GL_LINES); + for (i = 0; i < mesh->edgecount; i++){ + glColor3f(0, 0, 0); + glVertex3fv(mesh->edges[i].v1->position); + glVertex3fv(mesh->edges[i].v2->position); + } + + glEnd(); + glEnable(GL_LIGHTING); + glEnable(GL_DEPTH); + + + this->material.disable(); + //glEnable(GL_CULL_FACE); +} + + + + + + +MeshShape::MeshShape(MeshObject *object) : Shape(object){ + mesh = object->mesh; +} + +MeshShape::MeshShape(Object *object, Mesh *mesh) : Shape(object){ + this->mesh = mesh; +} + +bool MeshShape::checkCollision(Object *target){ + return target->geometry->checkCollisionPeer(this); +} + +float MeshShape::calculateMomentOfInertia(float *rotationvector){ + if (vectorDot(rotationvector, rotationvector) < EPSILON) return 0; + int i; + float j = 0; + for (i = 0; i < mesh->vertexcount; i++){ + float proj[3]; + vectorProject(proj, mesh->vertices[i].position, rotationvector); + vectorSub(proj, mesh->vertices[i].position, proj); + //float r = vectorLength(proj); + float r2 = vectorDot(proj, proj); + j += r2; + } + return j / i; +} + +bool MeshShape::checkCollisionPeer(SphereShape *target){ + float position[3] = {0, 0, 0}; + target->object->transformPoint(position, position); + object->unTransformPoint(position, position); + + float normal[3]; + float contactpoint[3]; + float r = target->getRadius(); + + if (checkSphereMeshCollision(position, r, mesh, normal, contactpoint)){ + vectorScale(normal, -1); + object->transformVector(normal, normal); + object->transformPoint(contactpoint, contactpoint); + + addCollision(object, target->object, normal, contactpoint); + + //vectorAdd(contactnormal, normal); + + return true; + } + + return false; +} + +//extern Sound *shotsound; + +bool MeshShape::checkCollisionPeer(MeshShape *target){ + float normal[3]; + float contactpoint[3]; + + bool collided = false; + + int i; + + Mesh *sourcemesh, *targetmesh; + + sourcemesh = this->mesh; + targetmesh = target->mesh; + for (i = 0; i < sourcemesh->vertexcount; i++){ + Vertex *vertex = &sourcemesh->vertices[i]; + float vertexposition[3]; + object->transformPoint(vertexposition, vertex->position); + target->object->unTransformPoint(vertexposition, vertexposition); + + if (checkPointMeshCollision(vertexposition, targetmesh, normal, contactpoint)){ + target->object->transformVector(normal, normal); + target->object->transformPoint(contactpoint, contactpoint); + + if (vectorIsZero(contactpoint)){ + vectorSet(contactpoint, 0, 0, 0); + } + addCollision(object, target->object, normal, contactpoint); + collided = true; + } + } + + sourcemesh = target->mesh; + targetmesh = this->mesh; + for (i = 0; i < sourcemesh->vertexcount; i++){ + Vertex *vertex = &sourcemesh->vertices[i]; + float vertexposition[3]; + target->object->transformPoint(vertexposition, vertex->position); + object->unTransformPoint(vertexposition, vertexposition); + + if (checkPointMeshCollision(vertexposition, targetmesh, normal, contactpoint)){ + object->transformVector(normal, normal); + object->transformPoint(contactpoint, contactpoint); + + addCollision(target->object, object, normal, contactpoint); + collided = true; + } + } + + sourcemesh = this->mesh; + targetmesh = target->mesh; + for (i = 0; i < sourcemesh->edgecount; i++){ + Edge *edge = &sourcemesh->edges[i]; + float v1[3], v2[3]; + object->transformPoint(v1, edge->v1->position); + target->object->unTransformPoint(v1, v1); + + object->transformPoint(v2, edge->v2->position); + target->object->unTransformPoint(v2, v2); + + if (checkEdgeMeshCollision(v1, v2, targetmesh, normal, contactpoint)){ + target->object->transformVector(normal, normal); + target->object->transformPoint(contactpoint, contactpoint); + + addCollision(object, target->object, normal, contactpoint); + collided = true; + } + } + + return collided; +} + diff --git a/src/mesh.h b/src/mesh.h index 7750fd2..45c3bdb 100644 --- a/src/mesh.h +++ b/src/mesh.h @@ -1,121 +1,121 @@ -#ifndef __MESH_H_INCLUDED__ -#define __MESH_H_INCLUDED__ - -#include "object.h" - - -#define X_AXIS 0 -#define Y_AXIS 1 -#define Z_AXIS 2 - - -class Vertex{ -public: - float position[3]; - float oldposition[3]; - float normal[3]; - float texcoords[2]; - - Vertex(void); - Vertex(float x, float y, float z); - Vertex(float x, float y, float z, float nx, float ny, float nz); - - void setTexCoords(float u, float v); -}; - - -class Edge; - -class Polygon{ -public: - float planenormal[3]; - float planedistance; - bool smooth; - bool realsmooth; - - int vertexcount; - Vertex **vertices; - int edgecount; - Edge **edges; - - Polygon(void); -}; - - - -class Edge{ -public: - Vertex *v1, *v2; - class Polygon *p1, *p2; -}; - - - -class Mesh{ -public: - int vertexcount; - Vertex *vertices; - - int polygoncount; - class Polygon *polygons; - - Edge *edges; - int edgecount; - - - Mesh(void); - ~Mesh(void); - - void createPlanes(void); - void createVertexnormals(void); - void createEdges(void); - float calculateScale(float targetLength, int axis); - void scale(float targetLength, int axis); - void scale(float scale); -}; - - - -class MeshObject : public Object{ -public: - Mesh *mesh; - - MeshObject(Mesh *mesh); -}; - - - -class MeshAppearance : public Appearance{ -private: - Mesh *mesh; - -public: - MeshAppearance(Mesh *mesh); - - void draw(void); -}; - - - -//Geometry of sphere - -class MeshShape : public Shape{ -private: - Mesh *mesh; - -public: - MeshShape(MeshObject *meshobject); - MeshShape(Object *object, Mesh *mesh); - - float calculateMomentOfInertia(float *rotationvector); - - bool checkCollision(Object *target); - - bool checkCollisionPeer(SphereShape *target); - bool checkCollisionPeer(MeshShape *target); - - friend class SphereShape; -}; - -#endif - +#ifndef __MESH_H_INCLUDED__ +#define __MESH_H_INCLUDED__ + +#include "object.h" + + +#define X_AXIS 0 +#define Y_AXIS 1 +#define Z_AXIS 2 + + +class Vertex{ +public: + float position[3]; + float oldposition[3]; + float normal[3]; + float texcoords[2]; + + Vertex(void); + Vertex(float x, float y, float z); + Vertex(float x, float y, float z, float nx, float ny, float nz); + + void setTexCoords(float u, float v); +}; + + +class Edge; + +class Polygon{ +public: + float planenormal[3]; + float planedistance; + bool smooth; + bool realsmooth; + + int vertexcount; + Vertex **vertices; + int edgecount; + Edge **edges; + + Polygon(void); +}; + + + +class Edge{ +public: + Vertex *v1, *v2; + class Polygon *p1, *p2; +}; + + + +class Mesh{ +public: + int vertexcount; + Vertex *vertices; + + int polygoncount; + class Polygon *polygons; + + Edge *edges; + int edgecount; + + + Mesh(void); + ~Mesh(void); + + void createPlanes(void); + void createVertexnormals(void); + void createEdges(void); + float calculateScale(float targetLength, int axis); + void scale(float targetLength, int axis); + void scale(float scale); +}; + + + +class MeshObject : public Object{ +public: + Mesh *mesh; + + MeshObject(Mesh *mesh); +}; + + + +class MeshAppearance : public Appearance{ +private: + Mesh *mesh; + +public: + MeshAppearance(Mesh *mesh); + + void draw(void); +}; + + + +//Geometry of sphere + +class MeshShape : public Shape{ +private: + Mesh *mesh; + +public: + MeshShape(MeshObject *meshobject); + MeshShape(Object *object, Mesh *mesh); + + float calculateMomentOfInertia(float *rotationvector); + + bool checkCollision(Object *target); + + bool checkCollisionPeer(SphereShape *target); + bool checkCollisionPeer(MeshShape *target); + + friend class SphereShape; +}; + +#endif + diff --git a/src/object.cpp b/src/object.cpp index f26f0a2..e2be412 100644 --- a/src/object.cpp +++ b/src/object.cpp @@ -1,213 +1,213 @@ -#include "main.h" - -#include - -#include "object.h" -#include "vector.h" -#include "collision.h" -#include "utils.h" -#include "fight.h" -#include "glapi.h" - -Object::Object(void){ - appearance = NULL; - geometry = NULL; - invmass = 0.0; - setPosition(0, 0, 0); - vectorSet(momentum, 0, 0, 0); - - invmomentofinertia = 0.0; - matrixIdentity(rotation); - vectorSet(angularmomentum, 0, 0, 0); - - setCollisionGroup(COLLISIONGROUP_NONE); - gravity = false; -} - -void Object::prepare(void){ - if (appearance != NULL) appearance->prepare(); -} - -#define DT 0.01 - -void Object::move(void){ - moveStep(DT); -} - -void Object::moveStep(float dt){ - if (invmass == 0) return; - - - if (vectorDot(momentum, momentum) > 1.0e+5) vectorSet(momentum, 0, 0, 0); - if (vectorDot(angularmomentum, angularmomentum) > 1.0e+5) vectorSet(angularmomentum, 0, 0, 0); - calculateStateVariables(); - - - float velocitydt[3]; - vectorScale(velocitydt, velocity, dt); - vectorAdd(position, velocitydt); - - float rotationdt[9]; - if (vectorIsZero(angularmomentum)){ - matrixIdentity(rotationdt); - } else{ - float angularvelocitydt[3]; - vectorScale(angularvelocitydt, angularvelocity, dt); - matrixCreateRotation(rotationdt, angularvelocitydt); - } - matrixMultiply(rotation, rotation, rotationdt); - - vectorScale(angularmomentum, 0.99); -} - -void Object::calculateStateVariables(void){ - getVelocity(velocity); - - if (vectorIsZero(angularmomentum)){ - invmomentofinertia = 0; - } else{ - invmomentofinertia = invmass * 1.0 / geometry->calculateMomentOfInertia(angularmomentum); - } - - vectorScale(angularvelocity, angularmomentum, invmomentofinertia); -} - -void Object::setPosition(float x, float y, float z){ - position[0] = x; - position[1] = y; - position[2] = z; -} - -void Object::getPosition(float *position){ - vectorCopy(position, this->position); -} - -void Object::getVelocity(float *velocity){ - vectorCopy(velocity, momentum); - vectorScale(velocity, invmass); -} - -void Object::getVelocity(float *velocity, float *point){ - getVelocity(velocity); - - float tangentialvelocity[3]; - getTangentialVelocity(tangentialvelocity, point); - //float tv[3]; - //transformVector(tv, tangentialvelocity); - vectorAdd(velocity, tangentialvelocity); -} - -void Object::getTangentialVelocity(float *target, float *point){ - if (vectorIsZero(angularmomentum)){ - vectorSet(target, 0, 0, 0); - return; - } - - vectorCross(target, angularmomentum, point); - vectorScale(target, invmomentofinertia); -} - -void Object::getMomentum(float *momentum){ - vectorCopy(momentum, this->momentum); -} - -void Object::setMass(float mass){ - if (mass == 0) this->invmass = 0; - else this->invmass = 1.0 / mass; -} - -float Object::getMass(void){ - if (invmass == 0) return 0; - return 1.0 / invmass; -} - -void Object::setCollisionGroup(int group){ - this->collisiongroup = group; -} - -int Object::getCollisionGroup(void){ - return collisiongroup; -} - -void Object::addImpulse(float *impulse, float *contactpoint){ - if (invmass == 0) return; - float angularimpulse[3]; - vectorCross(angularimpulse, contactpoint, impulse); - vectorAdd(angularmomentum, angularimpulse); - - vectorAdd(momentum, impulse); - - float t1[3], t2[3]; - vectorAdd(t1, contactpoint, position); - vectorNormalize(t2, impulse); - vectorAdd(t2, t1); - - //addGraphicsVector(t1, t2, vectorLength(impulse)); -} - -void Object::addExternalForce(float *force){ - float impulse[3]; - vectorScale(impulse, force, DT); - - float contact[3] = {0, 0, 0}; - this->addImpulse(impulse, contact); -} - -void Object::transformPoint(float *newpoint, float *oldpoint){ - vectorMatrixMultiply(newpoint, oldpoint, rotation); - vectorAdd(newpoint, position); -} - -void Object::unTransformPoint(float *newpoint, float *oldpoint){ - vectorSub(newpoint, oldpoint, position); - float rotmat[9]; - matrixTranspose(rotmat, rotation); - vectorMatrixMultiply(newpoint, newpoint, rotmat); -} - -void Object::transformVector(float *newvector, float *oldvector){ - vectorMatrixMultiply(newvector, oldvector, rotation); -} - -void Object::unTransformVector(float *newvector, float *oldvector){ - float rotmat[9]; - matrixTranspose(rotmat, rotation); - vectorMatrixMultiply(newvector, oldvector, rotmat); -} - - -void Object::hitForce(float speed, float *speed2, Object *source){ - float tolerance = 1.0; - if (speed > tolerance){ - Sound *sound; - if (rand()&1) sound = softhitsound1; - else sound = softhitsound2; - float volume = (speed-tolerance)*2; - if (volume > 1) volume = 1; - sound->setVolume(volume); - sound->play(30 + random(70)); - } -} - - - - -void Object::setGravity(bool enabled){ - gravity = enabled; -} - -void Object::draw(void){ - glPushMatrix(); - glTranslatef(position[0], position[1], position[2]); - - GLfloat glmatrix[16] = { - rotation[0], rotation[1], rotation[2], 0, - rotation[3], rotation[4], rotation[5], 0, - rotation[6], rotation[7], rotation[8], 0, - 0 , 0 , 0 , 1}; - glMultMatrixf(glmatrix); - - if (appearance != NULL) appearance->draw(); - - glPopMatrix(); -} +#include "main.h" + +#include + +#include "object.h" +#include "vector.h" +#include "collision.h" +#include "utils.h" +#include "fight.h" +#include "glapi.h" + +Object::Object(void){ + appearance = NULL; + geometry = NULL; + invmass = 0.0; + setPosition(0, 0, 0); + vectorSet(momentum, 0, 0, 0); + + invmomentofinertia = 0.0; + matrixIdentity(rotation); + vectorSet(angularmomentum, 0, 0, 0); + + setCollisionGroup(COLLISIONGROUP_NONE); + gravity = false; +} + +void Object::prepare(void){ + if (appearance != NULL) appearance->prepare(); +} + +#define DT 0.01 + +void Object::move(void){ + moveStep(DT); +} + +void Object::moveStep(float dt){ + if (invmass == 0) return; + + + if (vectorDot(momentum, momentum) > 1.0e+5) vectorSet(momentum, 0, 0, 0); + if (vectorDot(angularmomentum, angularmomentum) > 1.0e+5) vectorSet(angularmomentum, 0, 0, 0); + calculateStateVariables(); + + + float velocitydt[3]; + vectorScale(velocitydt, velocity, dt); + vectorAdd(position, velocitydt); + + float rotationdt[9]; + if (vectorIsZero(angularmomentum)){ + matrixIdentity(rotationdt); + } else{ + float angularvelocitydt[3]; + vectorScale(angularvelocitydt, angularvelocity, dt); + matrixCreateRotation(rotationdt, angularvelocitydt); + } + matrixMultiply(rotation, rotation, rotationdt); + + vectorScale(angularmomentum, 0.99); +} + +void Object::calculateStateVariables(void){ + getVelocity(velocity); + + if (vectorIsZero(angularmomentum)){ + invmomentofinertia = 0; + } else{ + invmomentofinertia = invmass * 1.0 / geometry->calculateMomentOfInertia(angularmomentum); + } + + vectorScale(angularvelocity, angularmomentum, invmomentofinertia); +} + +void Object::setPosition(float x, float y, float z){ + position[0] = x; + position[1] = y; + position[2] = z; +} + +void Object::getPosition(float *position){ + vectorCopy(position, this->position); +} + +void Object::getVelocity(float *velocity){ + vectorCopy(velocity, momentum); + vectorScale(velocity, invmass); +} + +void Object::getVelocity(float *velocity, float *point){ + getVelocity(velocity); + + float tangentialvelocity[3]; + getTangentialVelocity(tangentialvelocity, point); + //float tv[3]; + //transformVector(tv, tangentialvelocity); + vectorAdd(velocity, tangentialvelocity); +} + +void Object::getTangentialVelocity(float *target, float *point){ + if (vectorIsZero(angularmomentum)){ + vectorSet(target, 0, 0, 0); + return; + } + + vectorCross(target, angularmomentum, point); + vectorScale(target, invmomentofinertia); +} + +void Object::getMomentum(float *momentum){ + vectorCopy(momentum, this->momentum); +} + +void Object::setMass(float mass){ + if (mass == 0) this->invmass = 0; + else this->invmass = 1.0 / mass; +} + +float Object::getMass(void){ + if (invmass == 0) return 0; + return 1.0 / invmass; +} + +void Object::setCollisionGroup(int group){ + this->collisiongroup = group; +} + +int Object::getCollisionGroup(void){ + return collisiongroup; +} + +void Object::addImpulse(float *impulse, float *contactpoint){ + if (invmass == 0) return; + float angularimpulse[3]; + vectorCross(angularimpulse, contactpoint, impulse); + vectorAdd(angularmomentum, angularimpulse); + + vectorAdd(momentum, impulse); + + float t1[3], t2[3]; + vectorAdd(t1, contactpoint, position); + vectorNormalize(t2, impulse); + vectorAdd(t2, t1); + + //addGraphicsVector(t1, t2, vectorLength(impulse)); +} + +void Object::addExternalForce(float *force){ + float impulse[3]; + vectorScale(impulse, force, DT); + + float contact[3] = {0, 0, 0}; + this->addImpulse(impulse, contact); +} + +void Object::transformPoint(float *newpoint, float *oldpoint){ + vectorMatrixMultiply(newpoint, oldpoint, rotation); + vectorAdd(newpoint, position); +} + +void Object::unTransformPoint(float *newpoint, float *oldpoint){ + vectorSub(newpoint, oldpoint, position); + float rotmat[9]; + matrixTranspose(rotmat, rotation); + vectorMatrixMultiply(newpoint, newpoint, rotmat); +} + +void Object::transformVector(float *newvector, float *oldvector){ + vectorMatrixMultiply(newvector, oldvector, rotation); +} + +void Object::unTransformVector(float *newvector, float *oldvector){ + float rotmat[9]; + matrixTranspose(rotmat, rotation); + vectorMatrixMultiply(newvector, oldvector, rotmat); +} + + +void Object::hitForce(float speed, float *speed2, Object *source){ + float tolerance = 1.0; + if (speed > tolerance){ + Sound *sound; + if (rand()&1) sound = softhitsound1; + else sound = softhitsound2; + float volume = (speed-tolerance)*2; + if (volume > 1) volume = 1; + sound->setVolume(volume); + sound->play(30 + random(70)); + } +} + + + + +void Object::setGravity(bool enabled){ + gravity = enabled; +} + +void Object::draw(void){ + glPushMatrix(); + glTranslatef(position[0], position[1], position[2]); + + GLfloat glmatrix[16] = { + rotation[0], rotation[1], rotation[2], 0, + rotation[3], rotation[4], rotation[5], 0, + rotation[6], rotation[7], rotation[8], 0, + 0 , 0 , 0 , 1}; + glMultMatrixf(glmatrix); + + if (appearance != NULL) appearance->draw(); + + glPopMatrix(); +} diff --git a/src/object.h b/src/object.h index 31f95be..ea2d3b2 100644 --- a/src/object.h +++ b/src/object.h @@ -1,146 +1,146 @@ -#ifndef __OBJECT_H_INCLUDED__ -#define __OBJECT_H_INCLUDED__ - -class Object; - -#define EPSILON 1.0e-20 - -#include - -#include "shape.h" -#include "appearance.h" - -struct objectlist{ - Object *object; - objectlist *next; -}; - -class Object{ -public: - float invmass; - - /* Linear movement: - * position <-> paikka (x) - * velocity <-> nopeus (v) - * momentum <-> liikemäärä (p) - * force <-> voima (F) - * x' = v - * p' = F - * p = mv - * F = ma - * v' = a - */ - - float position[3]; - //derivative: velocity = momentum / mass - - float momentum[3];//, oldmomentum[3]; - //derivative: force - - //float force[3]; //Temporary properties - //float externalforce[3]; - - - /* Angular movement: - * rotation <-> orientaatio (R) - * angular velocity <-> kulmanopeus (w) - * angular momentum <-> pyörimisliikemäärä, vääntömomentti (L) - * torque <-> voiman momentti (M,T) - * moment of inertia <-> hitausmomentti (J,I) - * angular acceleration <-> kulmakiihtyvyys (a) - * L = J*w - * R' = Star(L) * R - * T = J*a - * w' = a - * L' = T - */ - - float invmomentofinertia; - - float rotation[9]; - //derivative: StarOperation(angularvelocity) * rotation - - float angularmomentum[3]; - //angular momentum = angular velocity * moment of inertia - //derivative: torque = angular acceleration * moment of inertia - - //float torque[3]; //Temporary property - - - void moveStep(float dt); - //void applyForces(float dt); - - void calculateStateVariables(void); - - int collisiongroup; - - void addImpulse(float *impulse, float *contactpoint); - - Appearance *appearance; - Shape *geometry; - - bool gravity; - - - - Object(void); - - virtual void prepare(void); - virtual void move(void); - virtual void draw(void); - - void setPosition(float x, float y, float z); - void getPosition(float *position); - - //Gets velocity from object and return it in "velocity" - void getVelocity(float *velocity); - - //Gets velocity from object for point "point" with - //tangential speed and return it in "velocity" - void getVelocity(float *velocity, float *point); - - void getTangentialVelocity(float *target, float *point); - - void getMomentum(float *momentum); - //void getForce(float *force); - void setMass(float mass); - float getMass(void); - void setCollisionGroup(int group); - int getCollisionGroup(void); - - void transformPoint(float *newpoint, float *oldpoint); - void unTransformPoint(float *newpoint, float *oldpoint); - void transformVector(float *newvector, float *oldvector); - void unTransformVector(float *newvector, float *oldvector); - - void addExternalForce(float *force); - - void setGravity(bool enabled); - - - - virtual void hitForce(float speed, float *speed2, Object *source); - - - - - - - - - friend class ObjectLink; - //friend void collide(Object *source, Object *target, float *normal, float *contactpoint); - friend bool checkCollisions(Object *object, float *contactnormal); - - - - - - - //Temporary state variables - float velocity[3]; - float angularvelocity[3]; -}; - -#endif - +#ifndef __OBJECT_H_INCLUDED__ +#define __OBJECT_H_INCLUDED__ + +class Object; + +#define EPSILON 1.0e-20 + +#include + +#include "shape.h" +#include "appearance.h" + +struct objectlist{ + Object *object; + objectlist *next; +}; + +class Object{ +public: + float invmass; + + /* Linear movement: + * position <-> paikka (x) + * velocity <-> nopeus (v) + * momentum <-> liikemäärä (p) + * force <-> voima (F) + * x' = v + * p' = F + * p = mv + * F = ma + * v' = a + */ + + float position[3]; + //derivative: velocity = momentum / mass + + float momentum[3];//, oldmomentum[3]; + //derivative: force + + //float force[3]; //Temporary properties + //float externalforce[3]; + + + /* Angular movement: + * rotation <-> orientaatio (R) + * angular velocity <-> kulmanopeus (w) + * angular momentum <-> pyörimisliikemäärä, vääntömomentti (L) + * torque <-> voiman momentti (M,T) + * moment of inertia <-> hitausmomentti (J,I) + * angular acceleration <-> kulmakiihtyvyys (a) + * L = J*w + * R' = Star(L) * R + * T = J*a + * w' = a + * L' = T + */ + + float invmomentofinertia; + + float rotation[9]; + //derivative: StarOperation(angularvelocity) * rotation + + float angularmomentum[3]; + //angular momentum = angular velocity * moment of inertia + //derivative: torque = angular acceleration * moment of inertia + + //float torque[3]; //Temporary property + + + void moveStep(float dt); + //void applyForces(float dt); + + void calculateStateVariables(void); + + int collisiongroup; + + void addImpulse(float *impulse, float *contactpoint); + + Appearance *appearance; + Shape *geometry; + + bool gravity; + + + + Object(void); + + virtual void prepare(void); + virtual void move(void); + virtual void draw(void); + + void setPosition(float x, float y, float z); + void getPosition(float *position); + + //Gets velocity from object and return it in "velocity" + void getVelocity(float *velocity); + + //Gets velocity from object for point "point" with + //tangential speed and return it in "velocity" + void getVelocity(float *velocity, float *point); + + void getTangentialVelocity(float *target, float *point); + + void getMomentum(float *momentum); + //void getForce(float *force); + void setMass(float mass); + float getMass(void); + void setCollisionGroup(int group); + int getCollisionGroup(void); + + void transformPoint(float *newpoint, float *oldpoint); + void unTransformPoint(float *newpoint, float *oldpoint); + void transformVector(float *newvector, float *oldvector); + void unTransformVector(float *newvector, float *oldvector); + + void addExternalForce(float *force); + + void setGravity(bool enabled); + + + + virtual void hitForce(float speed, float *speed2, Object *source); + + + + + + + + + friend class ObjectLink; + //friend void collide(Object *source, Object *target, float *normal, float *contactpoint); + friend bool checkCollisions(Object *object, float *contactnormal); + + + + + + + //Temporary state variables + float velocity[3]; + float angularvelocity[3]; +}; + +#endif + diff --git a/src/objectfactory.cpp b/src/objectfactory.cpp index 51c81f7..de77d2d 100644 --- a/src/objectfactory.cpp +++ b/src/objectfactory.cpp @@ -1,324 +1,324 @@ -#include "main.h" - -#include -#include -#include - -#include "object.h" -#include "mesh.h" -#include "vector.h" -#include "utils.h" -#include "3dutils.h" -#include "objectfactory.h" -#include "glapi.h" - - -MeshObject *createPyramid(float width, float height){ - Mesh *mesh = new Mesh(); - mesh->vertexcount = 5; - mesh->vertices = new Vertex[5]; - vectorSet(mesh->vertices[0].position, width, 0, 0); - vectorSet(mesh->vertices[0].normal, 1, 0, 0); - vectorSet(mesh->vertices[1].position, -width, 0, 0); - vectorSet(mesh->vertices[1].normal, -1, 0, 0); - vectorSet(mesh->vertices[2].position, 0, 0, width); - vectorSet(mesh->vertices[2].normal, 0, 0, 1); - vectorSet(mesh->vertices[3].position, 0, 0, -width); - vectorSet(mesh->vertices[3].normal, 0, 0, -1); - vectorSet(mesh->vertices[4].position, 0, height, 0); - vectorSet(mesh->vertices[4].normal, 0, 1, 0); - - mesh->polygoncount = 5; - mesh->polygons = new class Polygon[5]; - - mesh->polygons[0].vertexcount = 3; - mesh->polygons[0].vertices = new Vertex *[3]; - mesh->polygons[0].vertices[0] = &mesh->vertices[4]; - mesh->polygons[0].vertices[1] = &mesh->vertices[0]; - mesh->polygons[0].vertices[2] = &mesh->vertices[3]; - - mesh->polygons[1].vertexcount = 3; - mesh->polygons[1].vertices = new Vertex *[3]; - mesh->polygons[1].vertices[0] = &mesh->vertices[4]; - mesh->polygons[1].vertices[1] = &mesh->vertices[3]; - mesh->polygons[1].vertices[2] = &mesh->vertices[1]; - - mesh->polygons[2].vertexcount = 3; - mesh->polygons[2].vertices = new Vertex *[3]; - mesh->polygons[2].vertices[0] = &mesh->vertices[4]; - mesh->polygons[2].vertices[1] = &mesh->vertices[1]; - mesh->polygons[2].vertices[2] = &mesh->vertices[2]; - - mesh->polygons[3].vertexcount = 3; - mesh->polygons[3].vertices = new Vertex *[3]; - mesh->polygons[3].vertices[0] = &mesh->vertices[4]; - mesh->polygons[3].vertices[1] = &mesh->vertices[2]; - mesh->polygons[3].vertices[2] = &mesh->vertices[0]; - - mesh->polygons[4].vertexcount = 4; - mesh->polygons[4].vertices = new Vertex *[4]; - mesh->polygons[4].vertices[0] = &mesh->vertices[0]; - mesh->polygons[4].vertices[1] = &mesh->vertices[2]; - mesh->polygons[4].vertices[2] = &mesh->vertices[1]; - mesh->polygons[4].vertices[3] = &mesh->vertices[3]; - - mesh->polygons[0].smooth = false; - mesh->polygons[1].smooth = false; - mesh->polygons[2].smooth = false; - mesh->polygons[3].smooth = false; - mesh->polygons[4].smooth = false; - - mesh->createPlanes(); - - MeshObject *object = new MeshObject(mesh); - return object; -} - -MeshObject *createSpherePool(float width, float height){ - int grid = 16; - - Mesh *mesh = new Mesh(); - mesh->vertexcount = (grid+1)*(grid+1); - mesh->vertices = new Vertex[mesh->vertexcount]; - - int x, z; - for (z = 0; z < grid; z++){ - float pz = (2.0*z/(grid-1) - 1)*width; - for (x = 0; x < grid; x++){ - float px = (2.0*x/(grid-1) - 1)*width; - - //float py = randomf(1); - float l = sqrt(pz*pz + px*px)*1; - if (l > width) l = width; - l = l/width; - //l = l*l; - float py = height*(sin(PI*(1.5+l*2))+1)/2; - vectorSet(mesh->vertices[z * grid + x].position, px, py, pz); - } - } - - mesh->polygoncount = (grid-1)*(grid-1); - mesh->polygons = new class Polygon[mesh->polygoncount]; - for (z = 0; z < grid-1; z++){ - for (x = 0; x < grid-1; x++){ - class Polygon *poly = &mesh->polygons[z * (grid-1) + x]; - poly->vertexcount = 4; - poly->vertices = new Vertex *[4]; - - poly->vertices[0] = &mesh->vertices[z * grid + x + 1]; - poly->vertices[1] = &mesh->vertices[z * grid + x ]; - poly->vertices[2] = &mesh->vertices[(z + 1) * grid + x]; - poly->vertices[3] = &mesh->vertices[(z + 1) * grid + x + 1]; - - poly->smooth = true; - } - } - - - mesh->createPlanes(); - mesh->createVertexnormals(); - - MeshObject *object = new MeshObject(mesh); - return object; -} - -Mesh *createBox(float x1, float x2, float y1, float y2, float z1, float z2){ - Mesh *mesh = new Mesh(); - mesh->vertexcount = 8; - mesh->vertices = new Vertex[8]; - vectorSet(mesh->vertices[0].position, x1, y1, z1); - vectorSet(mesh->vertices[1].position, x2, y1, z1); - vectorSet(mesh->vertices[2].position, x1, y2, z1); - vectorSet(mesh->vertices[3].position, x2, y2, z1); - vectorSet(mesh->vertices[4].position, x1, y1, z2); - vectorSet(mesh->vertices[5].position, x2, y1, z2); - vectorSet(mesh->vertices[6].position, x1, y2, z2); - vectorSet(mesh->vertices[7].position, x2, y2, z2); - - mesh->polygoncount = 6; - mesh->polygons = new class Polygon[6]; - - //Back - mesh->polygons[0].vertexcount = 4; - mesh->polygons[0].vertices = new Vertex *[4]; - mesh->polygons[0].vertices[0] = &mesh->vertices[0]; - mesh->polygons[0].vertices[1] = &mesh->vertices[2]; - mesh->polygons[0].vertices[2] = &mesh->vertices[3]; - mesh->polygons[0].vertices[3] = &mesh->vertices[1]; - - //Front - mesh->polygons[1].vertexcount = 4; - mesh->polygons[1].vertices = new Vertex *[4]; - mesh->polygons[1].vertices[0] = &mesh->vertices[4]; - mesh->polygons[1].vertices[1] = &mesh->vertices[5]; - mesh->polygons[1].vertices[2] = &mesh->vertices[7]; - mesh->polygons[1].vertices[3] = &mesh->vertices[6]; - - //Left - mesh->polygons[2].vertexcount = 4; - mesh->polygons[2].vertices = new Vertex *[4]; - mesh->polygons[2].vertices[0] = &mesh->vertices[0]; - mesh->polygons[2].vertices[1] = &mesh->vertices[4]; - mesh->polygons[2].vertices[2] = &mesh->vertices[6]; - mesh->polygons[2].vertices[3] = &mesh->vertices[2]; - - //Right - mesh->polygons[3].vertexcount = 4; - mesh->polygons[3].vertices = new Vertex *[4]; - mesh->polygons[3].vertices[0] = &mesh->vertices[1]; - mesh->polygons[3].vertices[1] = &mesh->vertices[3]; - mesh->polygons[3].vertices[2] = &mesh->vertices[7]; - mesh->polygons[3].vertices[3] = &mesh->vertices[5]; - - //Top - mesh->polygons[4].vertexcount = 4; - mesh->polygons[4].vertices = new Vertex *[4]; - mesh->polygons[4].vertices[0] = &mesh->vertices[2]; - mesh->polygons[4].vertices[1] = &mesh->vertices[6]; - mesh->polygons[4].vertices[2] = &mesh->vertices[7]; - mesh->polygons[4].vertices[3] = &mesh->vertices[3]; - - //Bottom - mesh->polygons[5].vertexcount = 4; - mesh->polygons[5].vertices = new Vertex *[4]; - mesh->polygons[5].vertices[0] = &mesh->vertices[0]; - mesh->polygons[5].vertices[1] = &mesh->vertices[1]; - mesh->polygons[5].vertices[2] = &mesh->vertices[5]; - mesh->polygons[5].vertices[3] = &mesh->vertices[4]; - - mesh->createPlanes(); - mesh->createEdges(); - //mesh->createVertexnormals(); - - return mesh; -} - - -float getValueFromString(char* data){ - while(*data==' ') data++; - char* enddata=data; - //char oldchar; - do{ - enddata++; - if ((*enddata<'0' || *enddata>'9') && (*enddata!='.')) *enddata=0; - } while(*enddata!=0); - float ret=atof(data); - *enddata=' '; - return ret; -} - -char* findStringEnd(char* data, char* findstring){ - return strstr(data,findstring)+strlen(findstring); -} - -Mesh* loadAscModel(char *filename, float scale){ - float zeroOffset[3] = {0.0, 0.0, 0.0}; - return loadAscModel(filename, scale, (float*)zeroOffset); -} - -Mesh* loadAscModel(char *filename, float scale, float* offset){ - - Mesh* target = new Mesh(); - - - FILE* file; - float x, y, z; - - if ((file=fopen(filename,"rt"))==NULL){ - printf("Unable to open file %s\n",filename); - return NULL; - } - fseek(file,0,SEEK_END); - int size=ftell(file); - fseek(file,0,SEEK_SET); - char* data=(char*)malloc(size*sizeof(char)); - fread(data,size,1,file); - fclose(file); - char* vert=findStringEnd(data,"Vertices:"); - target->vertexcount=getValueFromString(vert); - char* face=findStringEnd(data,"Faces:"); - target->polygoncount=getValueFromString(face); - target->vertices = new Vertex[target->vertexcount]; - target->polygons = new class Polygon[target->polygoncount]; - - - int i; - - vert=findStringEnd(data,"Vertex list:"); - - for (i=0;ivertexcount;i++){ - vert=findStringEnd(vert,"Vertex"); - vert=findStringEnd(vert,"X:"); - x = getValueFromString(vert)*scale; - vert=findStringEnd(vert,"Y:"); - y = getValueFromString(vert)*scale; - vert=findStringEnd(vert,"Z:"); - z = getValueFromString(vert)*scale; - vectorSet(target->vertices[i].position, x + offset[0], y + offset[1] , z + offset[2]); - //recycle variables for texture coordinates - vert = findStringEnd(vert, "U:"); - x = getValueFromString(vert); - vert = findStringEnd(vert, "V:"); - y = getValueFromString(vert); - target->vertices[i].setTexCoords(x, y); - } - int vnum; - face=findStringEnd(data,"Face list:"); - - - for (i=0;ipolygoncount;i++){ - face=findStringEnd(face,"Face"); - face=findStringEnd(face,"A:"); - vnum=getValueFromString(face); - target->polygons[i].vertexcount = 3; - target->polygons[i].vertices = new Vertex *[3]; - target->polygons[i].vertices[0]=&(target->vertices[vnum]); - target->polygons[i].vertices[0]->setTexCoords(target->vertices[vnum].texcoords[0], - target->vertices[vnum].texcoords[1]); - face=findStringEnd(face,"B:"); - vnum=getValueFromString(face); - target->polygons[i].vertices[1]=&(target->vertices[vnum]); - target->polygons[i].vertices[1]->setTexCoords(target->vertices[vnum].texcoords[0], - target->vertices[vnum].texcoords[1]); - face=findStringEnd(face,"C:"); - vnum=getValueFromString(face); - target->polygons[i].vertices[2]=&(target->vertices[vnum]); - target->polygons[i].vertices[2]->setTexCoords(target->vertices[vnum].texcoords[0], - target->vertices[vnum].texcoords[1]); - char *face2=findStringEnd(face,"Nosmooth"); - char *face3=findStringEnd(face,"Smoothing"); - if (face2 > face && face2 < face3) target->polygons[i].realsmooth = true; - } - free(data); - data = NULL; - //target->createEdges(); - target->createPlanes(); - target->createVertexnormals(); - //return new MeshObject(target); - return target; -} - -void drawTrophy(void){ - point2d points[14]; - - int width = 3; - - int i = 0; - - points[i].x = 0.0; points[i].y = 0.0; i++; - points[i].x = width; points[i].y = 0.0; i++; - points[i].x = width-2; points[i].y = 2.0; i++; - points[i].x = width-2; points[i].y = 3.0; i++; - points[i].x = width-1; points[i].y = 4.0; i++; - points[i].x = width-2; points[i].y = 5.0; i++; - points[i].x = width-2; points[i].y = 6.0; i++; - points[i].x = width-1; points[i].y = 8.0; i++; - points[i].x = width; points[i].y = 9.0; i++; - points[i].x = width+1; points[i].y = 11.0; i++; - points[i].x = width+2; points[i].y = 15.0; i++; - points[i].x = width+3; points[i].y = 21.0; i++; - points[i].x = width+2; points[i].y = 21.0; i++; - points[i].x = 0.0; points[i].y = 8.0; i++; - - createLathedSurface(points, NULL, i, i*5, i*10); -} +#include "main.h" + +#include +#include +#include + +#include "object.h" +#include "mesh.h" +#include "vector.h" +#include "utils.h" +#include "3dutils.h" +#include "objectfactory.h" +#include "glapi.h" + + +MeshObject *createPyramid(float width, float height){ + Mesh *mesh = new Mesh(); + mesh->vertexcount = 5; + mesh->vertices = new Vertex[5]; + vectorSet(mesh->vertices[0].position, width, 0, 0); + vectorSet(mesh->vertices[0].normal, 1, 0, 0); + vectorSet(mesh->vertices[1].position, -width, 0, 0); + vectorSet(mesh->vertices[1].normal, -1, 0, 0); + vectorSet(mesh->vertices[2].position, 0, 0, width); + vectorSet(mesh->vertices[2].normal, 0, 0, 1); + vectorSet(mesh->vertices[3].position, 0, 0, -width); + vectorSet(mesh->vertices[3].normal, 0, 0, -1); + vectorSet(mesh->vertices[4].position, 0, height, 0); + vectorSet(mesh->vertices[4].normal, 0, 1, 0); + + mesh->polygoncount = 5; + mesh->polygons = new class Polygon[5]; + + mesh->polygons[0].vertexcount = 3; + mesh->polygons[0].vertices = new Vertex *[3]; + mesh->polygons[0].vertices[0] = &mesh->vertices[4]; + mesh->polygons[0].vertices[1] = &mesh->vertices[0]; + mesh->polygons[0].vertices[2] = &mesh->vertices[3]; + + mesh->polygons[1].vertexcount = 3; + mesh->polygons[1].vertices = new Vertex *[3]; + mesh->polygons[1].vertices[0] = &mesh->vertices[4]; + mesh->polygons[1].vertices[1] = &mesh->vertices[3]; + mesh->polygons[1].vertices[2] = &mesh->vertices[1]; + + mesh->polygons[2].vertexcount = 3; + mesh->polygons[2].vertices = new Vertex *[3]; + mesh->polygons[2].vertices[0] = &mesh->vertices[4]; + mesh->polygons[2].vertices[1] = &mesh->vertices[1]; + mesh->polygons[2].vertices[2] = &mesh->vertices[2]; + + mesh->polygons[3].vertexcount = 3; + mesh->polygons[3].vertices = new Vertex *[3]; + mesh->polygons[3].vertices[0] = &mesh->vertices[4]; + mesh->polygons[3].vertices[1] = &mesh->vertices[2]; + mesh->polygons[3].vertices[2] = &mesh->vertices[0]; + + mesh->polygons[4].vertexcount = 4; + mesh->polygons[4].vertices = new Vertex *[4]; + mesh->polygons[4].vertices[0] = &mesh->vertices[0]; + mesh->polygons[4].vertices[1] = &mesh->vertices[2]; + mesh->polygons[4].vertices[2] = &mesh->vertices[1]; + mesh->polygons[4].vertices[3] = &mesh->vertices[3]; + + mesh->polygons[0].smooth = false; + mesh->polygons[1].smooth = false; + mesh->polygons[2].smooth = false; + mesh->polygons[3].smooth = false; + mesh->polygons[4].smooth = false; + + mesh->createPlanes(); + + MeshObject *object = new MeshObject(mesh); + return object; +} + +MeshObject *createSpherePool(float width, float height){ + int grid = 16; + + Mesh *mesh = new Mesh(); + mesh->vertexcount = (grid+1)*(grid+1); + mesh->vertices = new Vertex[mesh->vertexcount]; + + int x, z; + for (z = 0; z < grid; z++){ + float pz = (2.0*z/(grid-1) - 1)*width; + for (x = 0; x < grid; x++){ + float px = (2.0*x/(grid-1) - 1)*width; + + //float py = randomf(1); + float l = sqrt(pz*pz + px*px)*1; + if (l > width) l = width; + l = l/width; + //l = l*l; + float py = height*(sin(PI*(1.5+l*2))+1)/2; + vectorSet(mesh->vertices[z * grid + x].position, px, py, pz); + } + } + + mesh->polygoncount = (grid-1)*(grid-1); + mesh->polygons = new class Polygon[mesh->polygoncount]; + for (z = 0; z < grid-1; z++){ + for (x = 0; x < grid-1; x++){ + class Polygon *poly = &mesh->polygons[z * (grid-1) + x]; + poly->vertexcount = 4; + poly->vertices = new Vertex *[4]; + + poly->vertices[0] = &mesh->vertices[z * grid + x + 1]; + poly->vertices[1] = &mesh->vertices[z * grid + x ]; + poly->vertices[2] = &mesh->vertices[(z + 1) * grid + x]; + poly->vertices[3] = &mesh->vertices[(z + 1) * grid + x + 1]; + + poly->smooth = true; + } + } + + + mesh->createPlanes(); + mesh->createVertexnormals(); + + MeshObject *object = new MeshObject(mesh); + return object; +} + +Mesh *createBox(float x1, float x2, float y1, float y2, float z1, float z2){ + Mesh *mesh = new Mesh(); + mesh->vertexcount = 8; + mesh->vertices = new Vertex[8]; + vectorSet(mesh->vertices[0].position, x1, y1, z1); + vectorSet(mesh->vertices[1].position, x2, y1, z1); + vectorSet(mesh->vertices[2].position, x1, y2, z1); + vectorSet(mesh->vertices[3].position, x2, y2, z1); + vectorSet(mesh->vertices[4].position, x1, y1, z2); + vectorSet(mesh->vertices[5].position, x2, y1, z2); + vectorSet(mesh->vertices[6].position, x1, y2, z2); + vectorSet(mesh->vertices[7].position, x2, y2, z2); + + mesh->polygoncount = 6; + mesh->polygons = new class Polygon[6]; + + //Back + mesh->polygons[0].vertexcount = 4; + mesh->polygons[0].vertices = new Vertex *[4]; + mesh->polygons[0].vertices[0] = &mesh->vertices[0]; + mesh->polygons[0].vertices[1] = &mesh->vertices[2]; + mesh->polygons[0].vertices[2] = &mesh->vertices[3]; + mesh->polygons[0].vertices[3] = &mesh->vertices[1]; + + //Front + mesh->polygons[1].vertexcount = 4; + mesh->polygons[1].vertices = new Vertex *[4]; + mesh->polygons[1].vertices[0] = &mesh->vertices[4]; + mesh->polygons[1].vertices[1] = &mesh->vertices[5]; + mesh->polygons[1].vertices[2] = &mesh->vertices[7]; + mesh->polygons[1].vertices[3] = &mesh->vertices[6]; + + //Left + mesh->polygons[2].vertexcount = 4; + mesh->polygons[2].vertices = new Vertex *[4]; + mesh->polygons[2].vertices[0] = &mesh->vertices[0]; + mesh->polygons[2].vertices[1] = &mesh->vertices[4]; + mesh->polygons[2].vertices[2] = &mesh->vertices[6]; + mesh->polygons[2].vertices[3] = &mesh->vertices[2]; + + //Right + mesh->polygons[3].vertexcount = 4; + mesh->polygons[3].vertices = new Vertex *[4]; + mesh->polygons[3].vertices[0] = &mesh->vertices[1]; + mesh->polygons[3].vertices[1] = &mesh->vertices[3]; + mesh->polygons[3].vertices[2] = &mesh->vertices[7]; + mesh->polygons[3].vertices[3] = &mesh->vertices[5]; + + //Top + mesh->polygons[4].vertexcount = 4; + mesh->polygons[4].vertices = new Vertex *[4]; + mesh->polygons[4].vertices[0] = &mesh->vertices[2]; + mesh->polygons[4].vertices[1] = &mesh->vertices[6]; + mesh->polygons[4].vertices[2] = &mesh->vertices[7]; + mesh->polygons[4].vertices[3] = &mesh->vertices[3]; + + //Bottom + mesh->polygons[5].vertexcount = 4; + mesh->polygons[5].vertices = new Vertex *[4]; + mesh->polygons[5].vertices[0] = &mesh->vertices[0]; + mesh->polygons[5].vertices[1] = &mesh->vertices[1]; + mesh->polygons[5].vertices[2] = &mesh->vertices[5]; + mesh->polygons[5].vertices[3] = &mesh->vertices[4]; + + mesh->createPlanes(); + mesh->createEdges(); + //mesh->createVertexnormals(); + + return mesh; +} + + +float getValueFromString(char* data){ + while(*data==' ') data++; + char* enddata=data; + //char oldchar; + do{ + enddata++; + if ((*enddata<'0' || *enddata>'9') && (*enddata!='.')) *enddata=0; + } while(*enddata!=0); + float ret=atof(data); + *enddata=' '; + return ret; +} + +char* findStringEnd(char* data, char* findstring){ + return strstr(data,findstring)+strlen(findstring); +} + +Mesh* loadAscModel(char *filename, float scale){ + float zeroOffset[3] = {0.0, 0.0, 0.0}; + return loadAscModel(filename, scale, (float*)zeroOffset); +} + +Mesh* loadAscModel(char *filename, float scale, float* offset){ + + Mesh* target = new Mesh(); + + + FILE* file; + float x, y, z; + + if ((file=fopen(filename,"rt"))==NULL){ + printf("Unable to open file %s\n",filename); + return NULL; + } + fseek(file,0,SEEK_END); + int size=ftell(file); + fseek(file,0,SEEK_SET); + char* data=(char*)malloc(size*sizeof(char)); + fread(data,size,1,file); + fclose(file); + char* vert=findStringEnd(data,"Vertices:"); + target->vertexcount=getValueFromString(vert); + char* face=findStringEnd(data,"Faces:"); + target->polygoncount=getValueFromString(face); + target->vertices = new Vertex[target->vertexcount]; + target->polygons = new class Polygon[target->polygoncount]; + + + int i; + + vert=findStringEnd(data,"Vertex list:"); + + for (i=0;ivertexcount;i++){ + vert=findStringEnd(vert,"Vertex"); + vert=findStringEnd(vert,"X:"); + x = getValueFromString(vert)*scale; + vert=findStringEnd(vert,"Y:"); + y = getValueFromString(vert)*scale; + vert=findStringEnd(vert,"Z:"); + z = getValueFromString(vert)*scale; + vectorSet(target->vertices[i].position, x + offset[0], y + offset[1] , z + offset[2]); + //recycle variables for texture coordinates + vert = findStringEnd(vert, "U:"); + x = getValueFromString(vert); + vert = findStringEnd(vert, "V:"); + y = getValueFromString(vert); + target->vertices[i].setTexCoords(x, y); + } + int vnum; + face=findStringEnd(data,"Face list:"); + + + for (i=0;ipolygoncount;i++){ + face=findStringEnd(face,"Face"); + face=findStringEnd(face,"A:"); + vnum=getValueFromString(face); + target->polygons[i].vertexcount = 3; + target->polygons[i].vertices = new Vertex *[3]; + target->polygons[i].vertices[0]=&(target->vertices[vnum]); + target->polygons[i].vertices[0]->setTexCoords(target->vertices[vnum].texcoords[0], + target->vertices[vnum].texcoords[1]); + face=findStringEnd(face,"B:"); + vnum=getValueFromString(face); + target->polygons[i].vertices[1]=&(target->vertices[vnum]); + target->polygons[i].vertices[1]->setTexCoords(target->vertices[vnum].texcoords[0], + target->vertices[vnum].texcoords[1]); + face=findStringEnd(face,"C:"); + vnum=getValueFromString(face); + target->polygons[i].vertices[2]=&(target->vertices[vnum]); + target->polygons[i].vertices[2]->setTexCoords(target->vertices[vnum].texcoords[0], + target->vertices[vnum].texcoords[1]); + char *face2=findStringEnd(face,"Nosmooth"); + char *face3=findStringEnd(face,"Smoothing"); + if (face2 > face && face2 < face3) target->polygons[i].realsmooth = true; + } + free(data); + data = NULL; + //target->createEdges(); + target->createPlanes(); + target->createVertexnormals(); + //return new MeshObject(target); + return target; +} + +void drawTrophy(void){ + point2d points[14]; + + int width = 3; + + int i = 0; + + points[i].x = 0.0; points[i].y = 0.0; i++; + points[i].x = width; points[i].y = 0.0; i++; + points[i].x = width-2; points[i].y = 2.0; i++; + points[i].x = width-2; points[i].y = 3.0; i++; + points[i].x = width-1; points[i].y = 4.0; i++; + points[i].x = width-2; points[i].y = 5.0; i++; + points[i].x = width-2; points[i].y = 6.0; i++; + points[i].x = width-1; points[i].y = 8.0; i++; + points[i].x = width; points[i].y = 9.0; i++; + points[i].x = width+1; points[i].y = 11.0; i++; + points[i].x = width+2; points[i].y = 15.0; i++; + points[i].x = width+3; points[i].y = 21.0; i++; + points[i].x = width+2; points[i].y = 21.0; i++; + points[i].x = 0.0; points[i].y = 8.0; i++; + + createLathedSurface(points, NULL, i, i*5, i*10); +} diff --git a/src/objectfactory.h b/src/objectfactory.h index 6d943fc..1c230f0 100644 --- a/src/objectfactory.h +++ b/src/objectfactory.h @@ -1,16 +1,16 @@ -#ifndef __OBJECTFACTORY_H_INCLUDED__ -#define __OBJECTFACTORY_H_INCLUDED__ - -#include "mesh.h" - -MeshObject* createPyramid(float width, float height); -MeshObject* createSpherePool(float width, float height); - - -Mesh* createBox(float x1, float x2, float y1, float y2, float z1, float z2); -Mesh* loadAscModel(char* filename, float scale, float* offset); -Mesh* loadAscModel(char* filename, float scale); -void drawTrophy(void); - -#endif - +#ifndef __OBJECTFACTORY_H_INCLUDED__ +#define __OBJECTFACTORY_H_INCLUDED__ + +#include "mesh.h" + +MeshObject* createPyramid(float width, float height); +MeshObject* createSpherePool(float width, float height); + + +Mesh* createBox(float x1, float x2, float y1, float y2, float z1, float z2); +Mesh* loadAscModel(char* filename, float scale, float* offset); +Mesh* loadAscModel(char* filename, float scale); +void drawTrophy(void); + +#endif + diff --git a/src/particle.cpp b/src/particle.cpp index b15d754..45024dd 100644 --- a/src/particle.cpp +++ b/src/particle.cpp @@ -1,151 +1,151 @@ -#include "main.h" - -#include - -#include "particle.h" -#include "vector.h" -#include "utils.h" -#include "world.h" -#include "objectfactory.h" -#include "collision.h" -#include "glapi.h" - - -Particle::Particle(World *world, Mesh *mesh) : MeshObject(mesh){ - this->world = world; -} - -Contact *contact = new Contact(); - -int bloodcount; - -void Particle::move(void){ - /*if (position[1] + momentum[1] < 0.5){ - currentparticle->velocity.x*=0.8; - currentparticle->velocity.y=fabs(currentparticle->velocity.y)*0.8; - currentparticle->velocity.z*=0.8; - currentparticle->bounces++; - } - currentparticle->position.x+=currentparticle->velocity.x; - currentparticle->position.y+=currentparticle->velocity.y; - currentparticle->position.z+=currentparticle->velocity.z; - currentparticle->angle.x+=currentparticle->velocity.x*50; - currentparticle->angle.y+=currentparticle->velocity.y*50; - currentparticle->angle.z+=currentparticle->velocity.z*50; - currentparticle->velocity.y-=0.003; - if (currentparticle->bounces==3) dieParticle(currentparticle);*/ - momentum[1] -= 0.02; - int i; - vectorSet(contact->normal, 0, 1, 0); - contact->object2 = NULL; - bool die = false; - for (i = 0; i < mesh->vertexcount; i++){ - float point[3]; - transformPoint(point, mesh->vertices[i].position); - if (point[1] < 0){ - contact->object1 = this; - vectorCopy(contact->position, point); - handleCollision(contact); - /*float impulse[3]; - getMomentum(impulse); - impulse[0] = 0; - impulse[1] = fabs(impulse[1]); - impulse[2] = 0; - vectorScale(impulse, 1.1); - addImpulse(impulse, point); - position[1] -= point[1]; - momentum[1] = impulse[1]*0.5;*/ - } - } - /*if (vectorLength(momentum) < 0.5) die = true; - if (die) removeBlood(id);*/ - lifetime++; - Object::move(); - - if (lifetime > 300) removeBlood(id); -} - -void Particle::hitForce(float speed, Object *source){ - /*bounces++; - if (bounces == 2){ - removeBlood(id); - }*/ -} - -void Particle::create(float *position, float *velocity){ - vectorCopy(this->position, position); - vectorCopy(this->momentum, velocity); - float rotate[3] = {randomf(2)-1, randomf(2)-1, randomf(2)-1}; - vectorCopy(this->angularmomentum, rotate); - bounces = 0; - lifetime = 0; - world->addParticle(this); -} - -void Particle::destroy(void){ - world->removeParticle(this); -} - - -Particle **bloodparticles; - -BloodAppearance::BloodAppearance(int *lifetime) : BasicBlockAppearance(1, 1, 1){ - this->lifetime = lifetime; - usematerial = false; -} - -void BloodAppearance::draw(void){ - glPushMatrix(); - - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); - - float alpha = 1-*lifetime*0.003; - if (alpha < 0) alpha = 0; - - glColor4f(1, 0, 0, alpha);//1.0/(1+*lifetime*0.004)); - - glScalef(0.5, 0.5, 0.5); - BasicBlockAppearance::draw(); - - glDisable(GL_BLEND); - - glPopMatrix(); -} - -World *bloodworld; - -void initBloods(World *world){ - bloodcount = 0; - bloodparticles = new Particle *[MAXBLOOD]; - int i; - Mesh *bloodmesh = createBox(-0.5, 0.5, -0.5*BLOCKHEIGHT, 0.5*BLOCKHEIGHT, -0.5, 0.5); - for (i = 0; i < MAXBLOOD; i++){ - bloodparticles[i] = new Particle(world, bloodmesh); - bloodparticles[i]->appearance = new BloodAppearance(&(bloodparticles[i]->lifetime)); - bloodparticles[i]->setMass(1); - bloodparticles[i]->prepare(); - //bloodparticles[i]->setGravity(true); - //bloodparticles[i]->setCollisionGroup(COLLISIONGROUP_PARTICLE); - //bloodparticles[i]->id = i; - } - bloodworld = world; -} - -void createBlood(float *position, float *velocity){ - if (bloodcount < MAXBLOOD){ - Particle *currentparticle = bloodparticles[bloodcount]; - currentparticle->create(position, velocity); - currentparticle->id = bloodcount; - bloodcount++; - } -} - -void removeBlood(int id){ - Particle *particle = bloodparticles[id]; - particle->destroy(); - bloodparticles[id] = bloodparticles[bloodcount-1]; - bloodparticles[id]->id = id; - bloodparticles[bloodcount-1] = particle; - bloodcount--; -} +#include "main.h" + +#include + +#include "particle.h" +#include "vector.h" +#include "utils.h" +#include "world.h" +#include "objectfactory.h" +#include "collision.h" +#include "glapi.h" + + +Particle::Particle(World *world, Mesh *mesh) : MeshObject(mesh){ + this->world = world; +} + +Contact *contact = new Contact(); + +int bloodcount; + +void Particle::move(void){ + /*if (position[1] + momentum[1] < 0.5){ + currentparticle->velocity.x*=0.8; + currentparticle->velocity.y=fabs(currentparticle->velocity.y)*0.8; + currentparticle->velocity.z*=0.8; + currentparticle->bounces++; + } + currentparticle->position.x+=currentparticle->velocity.x; + currentparticle->position.y+=currentparticle->velocity.y; + currentparticle->position.z+=currentparticle->velocity.z; + currentparticle->angle.x+=currentparticle->velocity.x*50; + currentparticle->angle.y+=currentparticle->velocity.y*50; + currentparticle->angle.z+=currentparticle->velocity.z*50; + currentparticle->velocity.y-=0.003; + if (currentparticle->bounces==3) dieParticle(currentparticle);*/ + momentum[1] -= 0.02; + int i; + vectorSet(contact->normal, 0, 1, 0); + contact->object2 = NULL; + bool die = false; + for (i = 0; i < mesh->vertexcount; i++){ + float point[3]; + transformPoint(point, mesh->vertices[i].position); + if (point[1] < 0){ + contact->object1 = this; + vectorCopy(contact->position, point); + handleCollision(contact); + /*float impulse[3]; + getMomentum(impulse); + impulse[0] = 0; + impulse[1] = fabs(impulse[1]); + impulse[2] = 0; + vectorScale(impulse, 1.1); + addImpulse(impulse, point); + position[1] -= point[1]; + momentum[1] = impulse[1]*0.5;*/ + } + } + /*if (vectorLength(momentum) < 0.5) die = true; + if (die) removeBlood(id);*/ + lifetime++; + Object::move(); + + if (lifetime > 300) removeBlood(id); +} + +void Particle::hitForce(float speed, Object *source){ + /*bounces++; + if (bounces == 2){ + removeBlood(id); + }*/ +} + +void Particle::create(float *position, float *velocity){ + vectorCopy(this->position, position); + vectorCopy(this->momentum, velocity); + float rotate[3] = {randomf(2)-1, randomf(2)-1, randomf(2)-1}; + vectorCopy(this->angularmomentum, rotate); + bounces = 0; + lifetime = 0; + world->addParticle(this); +} + +void Particle::destroy(void){ + world->removeParticle(this); +} + + +Particle **bloodparticles; + +BloodAppearance::BloodAppearance(int *lifetime) : BasicBlockAppearance(1, 1, 1){ + this->lifetime = lifetime; + usematerial = false; +} + +void BloodAppearance::draw(void){ + glPushMatrix(); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); + + float alpha = 1-*lifetime*0.003; + if (alpha < 0) alpha = 0; + + glColor4f(1, 0, 0, alpha);//1.0/(1+*lifetime*0.004)); + + glScalef(0.5, 0.5, 0.5); + BasicBlockAppearance::draw(); + + glDisable(GL_BLEND); + + glPopMatrix(); +} + +World *bloodworld; + +void initBloods(World *world){ + bloodcount = 0; + bloodparticles = new Particle *[MAXBLOOD]; + int i; + Mesh *bloodmesh = createBox(-0.5, 0.5, -0.5*BLOCKHEIGHT, 0.5*BLOCKHEIGHT, -0.5, 0.5); + for (i = 0; i < MAXBLOOD; i++){ + bloodparticles[i] = new Particle(world, bloodmesh); + bloodparticles[i]->appearance = new BloodAppearance(&(bloodparticles[i]->lifetime)); + bloodparticles[i]->setMass(1); + bloodparticles[i]->prepare(); + //bloodparticles[i]->setGravity(true); + //bloodparticles[i]->setCollisionGroup(COLLISIONGROUP_PARTICLE); + //bloodparticles[i]->id = i; + } + bloodworld = world; +} + +void createBlood(float *position, float *velocity){ + if (bloodcount < MAXBLOOD){ + Particle *currentparticle = bloodparticles[bloodcount]; + currentparticle->create(position, velocity); + currentparticle->id = bloodcount; + bloodcount++; + } +} + +void removeBlood(int id){ + Particle *particle = bloodparticles[id]; + particle->destroy(); + bloodparticles[id] = bloodparticles[bloodcount-1]; + bloodparticles[id]->id = id; + bloodparticles[bloodcount-1] = particle; + bloodcount--; +} diff --git a/src/particle.h b/src/particle.h index 66ce42a..373fab7 100644 --- a/src/particle.h +++ b/src/particle.h @@ -1,56 +1,56 @@ -#ifndef __PARTICLE_H_INCLUDED__ -#define __PARTICLE_H_INCLUDED__ - -class Particle; -class BloodAppearance; - -#include "object.h" -#include "legoblocks.h" -#include "world.h" - -class Particle : public MeshObject{ -private: - int bounces; - bool enabled; - - World *world; - - bool alive; - -public: - int lifetime; - int id; - - Particle(World *world, Mesh *mesh); - - void move(void); - - void hitForce(float speed, Object *source); - - - void create(float *position, float *velocity); - void destroy(void); -}; - - - - -#define MAXBLOOD 500 - - -class BloodAppearance : public BasicBlockAppearance{ -private: - int *lifetime; - -public: - BloodAppearance(int *lifetime); - - void draw(void); -}; - -void initBloods(World *world); -void createBlood(float *position, float *velocity); -void removeBlood(int id); - -#endif - +#ifndef __PARTICLE_H_INCLUDED__ +#define __PARTICLE_H_INCLUDED__ + +class Particle; +class BloodAppearance; + +#include "object.h" +#include "legoblocks.h" +#include "world.h" + +class Particle : public MeshObject{ +private: + int bounces; + bool enabled; + + World *world; + + bool alive; + +public: + int lifetime; + int id; + + Particle(World *world, Mesh *mesh); + + void move(void); + + void hitForce(float speed, Object *source); + + + void create(float *position, float *velocity); + void destroy(void); +}; + + + + +#define MAXBLOOD 500 + + +class BloodAppearance : public BasicBlockAppearance{ +private: + int *lifetime; + +public: + BloodAppearance(int *lifetime); + + void draw(void); +}; + +void initBloods(World *world); +void createBlood(float *position, float *velocity); +void removeBlood(int id); + +#endif + diff --git a/src/run.cpp b/src/run.cpp index dcfc697..8350c33 100644 --- a/src/run.cpp +++ b/src/run.cpp @@ -1,213 +1,213 @@ -#include "main.h" - -#include - -#include "run.h" -#include "fight.h" -#include "menu.h" -#include "end.h" -#include "graphics.h" -#include "3dutils.h" -#include "audio.h" -#include "font.h" -#include "legoblocks.h" -#include "glapi.h" - -int gamemode; - -bool changed; - -bool gameinitialized = false; - -void initFontTexture(void); - -void initScenes(void){ - knobgllist = glGenLists(1); - setDetail(detail); - - - //Simple loading-screen - enable2D(); - - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - SDL_GL_SwapBuffers(); - - initFontTexture(); - - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - print(0.08, 0.4, "Loading...", 0.2); - SDL_GL_SwapBuffers(); - - disable2D(); - - - - SKYBOX = -1; - initTextures(); - initFight(); - initMenu(); - initEnd(); - changeGameMode(MENUMODE); - //changeGameMode(ENDMODE); - gameinitialized = true; -} - -void changeGameMode(int newmode){ - gamemode = newmode; - changed = true; -} - -void calculateFrame(int framecount){ - switch(gamemode){ - case MENUMODE: - calculateMenu(framecount); - break; - case FIGHTMODE: - calculateFight(framecount); - break; - case ENDMODE: - calculateEnd(framecount); - break; - } - updateAudio(); - changed = false; -} - -void drawFrame(int framecount){ - if (changed) calculateFrame(framecount); - - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glMatrixMode(GL_MODELVIEW); - - switch(gamemode){ - case MENUMODE: - drawMenu(framecount); - break; - case FIGHTMODE: - drawFight(framecount); - break; - case ENDMODE: - drawEnd(framecount); - break; - } - - SDL_GL_SwapBuffers(); -} - -/*int SKY_FRONT_ID; -int SKY_BACK_ID; -int SKY_LEFT_ID; -int SKY_RIGHT_ID; -int SKY_TOP_ID; -int SKY_BOTTOM_ID;*/ - -bool texturesloaded = false; - -Texture *flaretexture; -Texture *skyfronttexture; -Texture *skybacktexture; -Texture *skylefttexture; -Texture *skyrighttexture; -Texture *skytoptexture; -Texture *skybottomtexture; -Texture *damageHead; -Texture *damageTorso; -Texture *damageHand; -Texture *damageLeg; -Texture *tuxtexture; -Texture *faceTexture; - -void initFontTexture(void){ - if (!texturesloaded){ - float trans[3] = {1, 0, 0}; - fonttexture = new Texture(); - fonttexture->loadImage(DATAPATH"font.png", trans); - } else{ - fonttexture->reload(); - } -} - -void initTextures(void){ - /*SKY_FRONT_ID = DRUID.loadTexture(SKYFRONT); - SKY_BACK_ID = DRUID.loadTexture(SKYBACK); - SKY_LEFT_ID = DRUID.loadTexture(SKYLEFT); - SKY_RIGHT_ID = DRUID.loadTexture(SKYRIGHT); - SKY_TOP_ID = DRUID.loadTexture(SKYTOP); - SKY_BOTTOM_ID = DRUID.loadTexture(SKYBOTTOM);*/ - - if (!texturesloaded){ - skyfronttexture = new Texture(); - skyfronttexture->loadImage(SKYFRONT); - skybacktexture = new Texture(); - skybacktexture->loadImage(SKYBACK); - skylefttexture = new Texture(); - skylefttexture->loadImage(SKYLEFT); - skyrighttexture = new Texture(); - skyrighttexture->loadImage(SKYRIGHT); - skytoptexture = new Texture(); - skytoptexture->loadImage(SKYTOP); - skybottomtexture = new Texture(); - skybottomtexture->loadImage(SKYBOTTOM); - - - float something[3] = {1, 0, 0.5}; - damageHead = new Texture(); - damageHead->loadImage(DAMAGEHEAD, something); - damageTorso = new Texture(); - damageTorso->loadImage(DAMAGETORSO, something); - damageHand = new Texture(); - damageHand->loadImage(DAMAGEHAND, something); - damageLeg = new Texture(); - damageLeg->loadImage(DAMAGELEG, something); - faceTexture = new Texture(); - something[2] = 1; - faceTexture->loadImage(FACE, something); - - float zeros[3] = {0, 0, 0}; - flaretexture = new Texture(); - flaretexture->loadImage(DATAPATH"flare.png", zeros); - - - float pink[3] = {1, 0, 1}; - tuxtexture = new Texture(); - tuxtexture->loadImage(DATAPATH"tux.png", pink); - } else{ - skyfronttexture->reload(); - skybacktexture->reload(); - skylefttexture->reload(); - skyrighttexture->reload(); - skytoptexture->reload(); - skybottomtexture->reload(); - - damageHead->reload(); - damageTorso->reload(); - damageHand->reload(); - damageLeg->reload(); - - flaretexture->reload(); - - tuxtexture->reload(); - } - texturesloaded = true; -} - -void setDetail(int detail){ - switch(detail){ - case 0: - knobdetail = 0; - break; - case 1: - knobdetail = 5; - break; - case 2: - knobdetail = 8; - break; - case 3: - knobdetail = 16; - break; - } - initKnob(); -} - - +#include "main.h" + +#include + +#include "run.h" +#include "fight.h" +#include "menu.h" +#include "end.h" +#include "graphics.h" +#include "3dutils.h" +#include "audio.h" +#include "font.h" +#include "legoblocks.h" +#include "glapi.h" + +int gamemode; + +bool changed; + +bool gameinitialized = false; + +void initFontTexture(void); + +void initScenes(void){ + knobgllist = glGenLists(1); + setDetail(detail); + + + //Simple loading-screen + enable2D(); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + SDL_GL_SwapBuffers(); + + initFontTexture(); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + print(0.08, 0.4, "Loading...", 0.2); + SDL_GL_SwapBuffers(); + + disable2D(); + + + + SKYBOX = -1; + initTextures(); + initFight(); + initMenu(); + initEnd(); + changeGameMode(MENUMODE); + //changeGameMode(ENDMODE); + gameinitialized = true; +} + +void changeGameMode(int newmode){ + gamemode = newmode; + changed = true; +} + +void calculateFrame(int framecount){ + switch(gamemode){ + case MENUMODE: + calculateMenu(framecount); + break; + case FIGHTMODE: + calculateFight(framecount); + break; + case ENDMODE: + calculateEnd(framecount); + break; + } + updateAudio(); + changed = false; +} + +void drawFrame(int framecount){ + if (changed) calculateFrame(framecount); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glMatrixMode(GL_MODELVIEW); + + switch(gamemode){ + case MENUMODE: + drawMenu(framecount); + break; + case FIGHTMODE: + drawFight(framecount); + break; + case ENDMODE: + drawEnd(framecount); + break; + } + + SDL_GL_SwapBuffers(); +} + +/*int SKY_FRONT_ID; +int SKY_BACK_ID; +int SKY_LEFT_ID; +int SKY_RIGHT_ID; +int SKY_TOP_ID; +int SKY_BOTTOM_ID;*/ + +bool texturesloaded = false; + +Texture *flaretexture; +Texture *skyfronttexture; +Texture *skybacktexture; +Texture *skylefttexture; +Texture *skyrighttexture; +Texture *skytoptexture; +Texture *skybottomtexture; +Texture *damageHead; +Texture *damageTorso; +Texture *damageHand; +Texture *damageLeg; +Texture *tuxtexture; +Texture *faceTexture; + +void initFontTexture(void){ + if (!texturesloaded){ + float trans[3] = {1, 0, 0}; + fonttexture = new Texture(); + fonttexture->loadImage(DATAPATH"font.png", trans); + } else{ + fonttexture->reload(); + } +} + +void initTextures(void){ + /*SKY_FRONT_ID = DRUID.loadTexture(SKYFRONT); + SKY_BACK_ID = DRUID.loadTexture(SKYBACK); + SKY_LEFT_ID = DRUID.loadTexture(SKYLEFT); + SKY_RIGHT_ID = DRUID.loadTexture(SKYRIGHT); + SKY_TOP_ID = DRUID.loadTexture(SKYTOP); + SKY_BOTTOM_ID = DRUID.loadTexture(SKYBOTTOM);*/ + + if (!texturesloaded){ + skyfronttexture = new Texture(); + skyfronttexture->loadImage(SKYFRONT); + skybacktexture = new Texture(); + skybacktexture->loadImage(SKYBACK); + skylefttexture = new Texture(); + skylefttexture->loadImage(SKYLEFT); + skyrighttexture = new Texture(); + skyrighttexture->loadImage(SKYRIGHT); + skytoptexture = new Texture(); + skytoptexture->loadImage(SKYTOP); + skybottomtexture = new Texture(); + skybottomtexture->loadImage(SKYBOTTOM); + + + float something[3] = {1, 0, 0.5}; + damageHead = new Texture(); + damageHead->loadImage(DAMAGEHEAD, something); + damageTorso = new Texture(); + damageTorso->loadImage(DAMAGETORSO, something); + damageHand = new Texture(); + damageHand->loadImage(DAMAGEHAND, something); + damageLeg = new Texture(); + damageLeg->loadImage(DAMAGELEG, something); + faceTexture = new Texture(); + something[2] = 1; + faceTexture->loadImage(FACE, something); + + float zeros[3] = {0, 0, 0}; + flaretexture = new Texture(); + flaretexture->loadImage(DATAPATH"flare.png", zeros); + + + float pink[3] = {1, 0, 1}; + tuxtexture = new Texture(); + tuxtexture->loadImage(DATAPATH"tux.png", pink); + } else{ + skyfronttexture->reload(); + skybacktexture->reload(); + skylefttexture->reload(); + skyrighttexture->reload(); + skytoptexture->reload(); + skybottomtexture->reload(); + + damageHead->reload(); + damageTorso->reload(); + damageHand->reload(); + damageLeg->reload(); + + flaretexture->reload(); + + tuxtexture->reload(); + } + texturesloaded = true; +} + +void setDetail(int detail){ + switch(detail){ + case 0: + knobdetail = 0; + break; + case 1: + knobdetail = 5; + break; + case 2: + knobdetail = 8; + break; + case 3: + knobdetail = 16; + break; + } + initKnob(); +} + + diff --git a/src/run.h b/src/run.h index da160b7..78ff8a1 100644 --- a/src/run.h +++ b/src/run.h @@ -1,16 +1,16 @@ -#ifndef __RUN_H_INCLUDED__ -#define __RUN_H_INCLUDED__ - -#define MENUMODE 1 -#define FIGHTMODE 2 -#define ENDMODE 3 - -void initScenes(void); -void changeGameMode(int newmode); -void calculateFrame(int framecount); -void drawFrame(int framecount); -void initTextures(void); -void setDetail(int detail); - -#endif - +#ifndef __RUN_H_INCLUDED__ +#define __RUN_H_INCLUDED__ + +#define MENUMODE 1 +#define FIGHTMODE 2 +#define ENDMODE 3 + +void initScenes(void); +void changeGameMode(int newmode); +void calculateFrame(int framecount); +void drawFrame(int framecount); +void initTextures(void); +void setDetail(int detail); + +#endif + diff --git a/src/shape.cpp b/src/shape.cpp index 04cb975..8081f29 100644 --- a/src/shape.cpp +++ b/src/shape.cpp @@ -1,18 +1,18 @@ -#include "shape.h" - -Shape::Shape(Object *object){ - this->object = object; -} - -bool Shape::checkCollision(Object *target){ - return false; -} -bool Shape::checkCollisionPeer(Shape *target){ - return false; -} -bool Shape::checkCollisionPeer(SphereShape *target){ - return false; -} -bool Shape::checkCollisionPeer(MeshShape *target){ - return false; -} +#include "shape.h" + +Shape::Shape(Object *object){ + this->object = object; +} + +bool Shape::checkCollision(Object *target){ + return false; +} +bool Shape::checkCollisionPeer(Shape *target){ + return false; +} +bool Shape::checkCollisionPeer(SphereShape *target){ + return false; +} +bool Shape::checkCollisionPeer(MeshShape *target){ + return false; +} diff --git a/src/shape.h b/src/shape.h index 05619d1..f56eb0b 100644 --- a/src/shape.h +++ b/src/shape.h @@ -1,31 +1,31 @@ -#ifndef __SHAPE_H_INCLUDED__ -#define __SHAPE_H_INCLUDED__ - -class Shape; -class SphereShape; -class MeshShape; - -#include "object.h" - -/* - * Abstract class for object geometry - */ -class Shape{ -protected: - Object *object; - -public: - Shape(Object *object); - - - virtual float calculateMomentOfInertia(float *rotationvector) = 0; - - virtual bool checkCollision(Object *target); - - virtual bool checkCollisionPeer(Shape *target); - virtual bool checkCollisionPeer(SphereShape *target); - virtual bool checkCollisionPeer(MeshShape *target); -}; - -#endif - +#ifndef __SHAPE_H_INCLUDED__ +#define __SHAPE_H_INCLUDED__ + +class Shape; +class SphereShape; +class MeshShape; + +#include "object.h" + +/* + * Abstract class for object geometry + */ +class Shape{ +protected: + Object *object; + +public: + Shape(Object *object); + + + virtual float calculateMomentOfInertia(float *rotationvector) = 0; + + virtual bool checkCollision(Object *target); + + virtual bool checkCollisionPeer(Shape *target); + virtual bool checkCollisionPeer(SphereShape *target); + virtual bool checkCollisionPeer(MeshShape *target); +}; + +#endif + diff --git a/src/sphere.cpp b/src/sphere.cpp index 6656471..f1af957 100644 --- a/src/sphere.cpp +++ b/src/sphere.cpp @@ -1,263 +1,263 @@ -#include "main.h" - -#include - -#include "sphere.h" -#include "utils.h" -#include "3dutils.h" -#include "audio.h" -#include "vector.h" -#include "collision.h" -#include "glapi.h" - - -Sphere::Sphere(void){ - appearance = new SphereAppearance(); - Object::appearance = appearance; - geometry = new SphereShape(this); - Object::geometry = geometry; -} - -void Sphere::setRadius(float r){ - if (r < 0) r = -r; - this->r = r; - appearance->setRadius(r); - geometry->setRadius(r); -} - -SphereAppearance::SphereAppearance(void){ - setRadius(1); -} - -void SphereAppearance::setRadius(float r){ - if (r < 0) r = -r; - this->r = r; -} - -void Sphere::setColor(float red, float green, float blue){ - appearance->getMaterial()->setColor(red, green, blue, 1); -} - -void SphereAppearance::draw(void){ - material.enable(); - createSphere(r); -} - - - - -SphereShape::SphereShape(Object *sphere) : Shape(sphere){ - setRadius(1); -} - -void SphereShape::setRadius(float r){ - this->r = r; -} - -float SphereShape::getRadius(void){ - return r; -} - -bool SphereShape::checkCollision(Object *target){ - return target->geometry->checkCollisionPeer(this); -} - -float SphereShape::calculateMomentOfInertia(float *rotationvector){ - return 2.0/3.0*r*r; -} - -/*bool SphereShape::checkCollisionPeer(PlaneShape *target){ - float sourceposition[3], targetposition[3]; - object->getPosition(sourceposition); - target->object->getPosition(targetposition); - float height = target->height + targetposition[1]; - - if (sourceposition[1] - r < height){ - //shotsound->play(); - float normal[3] = {0, 1, 0}; - - float contactpoint[3] = {0, target->height, 0}; - collide(object, target->object, normal, contactpoint); - return true; - } - - return false; -}*/ - -bool SphereShape::checkCollisionPeer(SphereShape *target){ - /*float sourceposition[3], targetposition[3]; - object->getPosition(sourceposition); - target->object->getPosition(targetposition); - float impact[3]; - vectorSub(impact, sourceposition, targetposition);*/ - float impact[3] = {0, 0, 0}; - object->transformPoint(impact, impact); - target->object->unTransformPoint(impact, impact); - float distance2 = vectorDot(impact, impact); - - if (distance2 < (r + target->r)*(r + target->r)){ - /*float temp[3], temp2[3], temp3[3]; - object->getMomentum(temp2); - target->object->getMomentum(temp3); - vectorSub(temp, temp2, temp3); - shotsound->setVolume(1.0-1/(1+vectorLength(temp)*0.5)); - shotsound->play();*/ - float normal[3]; - vectorNormalize(normal, impact); - - float contactpoint[3]; - vectorScale(contactpoint, normal, target->r); - - target->object->transformVector(normal, normal); - target->object->transformPoint(contactpoint, contactpoint); - - addCollision(object, target->object, normal, contactpoint); - - //vectorAdd(contactnormal, normal); - - return true; - } - - return false; -} - -bool between(float x, float x1, float x2){ - if ((x >= x1 && x <=x2) || (x >= x2 && x <=x1)) return true; - return false; -} - -/*bool SphereShape::checkCollisionPeer(BoxShape *target){ - float sourceposition[3], targetposition[3]; - object->getPosition(sourceposition); - target->object->getPosition(targetposition); - float x1 = target->x1 + targetposition[0]; - float x2 = target->x2 + targetposition[0]; - float y1 = target->y1 + targetposition[1]; - float y2 = target->y2 + targetposition[1]; - float z1 = target->z1 + targetposition[2]; - float z2 = target->z2 + targetposition[2]; - float points[3][2] = {{x1, x2}, {y1, y2}, {z1, z2}}; - float p[2], op1[2], op2[2]; - float c, oc1, oc2; - int i; - float normal[3]; - float *normal2[3]; - //Faces - for (i = 0; i < 3; i++){ - p[0] = points[i][0]; - p[1] = points[i][1]; - op1[0] = points[(i+1)%3][0]; - op1[1] = points[(i+1)%3][1]; - op2[0] = points[(i+2)%3][0]; - op2[1] = points[(i+2)%3][1]; - c = sourceposition[i]; - oc1 = sourceposition[(i+1)%3]; - oc2 = sourceposition[(i+2)%3]; - normal2[0] = &normal[i]; - normal2[1] = &normal[(i+1)%3]; - normal2[2] = &normal[(i+2)%3]; - - if (between(oc1, op1[0], op1[1]) && - between(oc2, op2[0], op2[1])){ - if (c < p[0] && c+r > p[0]){ - *normal2[0] = -1; - *normal2[1] = 0; - *normal2[2] = 0; - collide(object, target->object, normal); - return true; - } - if (c > p[1] && c-r < p[1]){ - *normal2[0] = 1; - *normal2[1] = 0; - *normal2[2] = 0; - collide(object, target->object, normal); - return true; - } - } - } - - //Edges - for (i = 0; i < 3; i++){ - p[0] = points[i][0]; - p[1] = points[i][1]; - op1[0] = points[(i+1)%3][0]; - op1[1] = points[(i+1)%3][1]; - op2[0] = points[(i+2)%3][0]; - op2[1] = points[(i+2)%3][1]; - c = sourceposition[i]; - oc1 = sourceposition[(i+1)%3]; - oc2 = sourceposition[(i+2)%3]; - normal2[0] = &normal[i]; - normal2[1] = &normal[(i+1)%3]; - normal2[2] = &normal[(i+2)%3]; - float edges[4][2] = { - {p[0], op1[0]}, - {p[1], op1[0]}, - {p[0], op1[1]}, - {p[1], op1[1]}}; - - if (between(oc2, op2[0], op2[1])){ - int j; - for (j = 0; j < 4; j++){ - float diff[2] = {c - edges[j][0], oc1 - edges[j][1]}; - if (diff[0]*diff[0] + diff[1]*diff[1] < r*r){ - *normal2[0] = diff[0]; - *normal2[1] = diff[1]; - *normal2[2] = 0; - vectorNormalize(normal); - collide(object, target->object, normal); - return true; - } - } - } - } - - //Corners - float corners[8][3] = { - {x1, y1, z1}, - {x1, y1, z2}, - {x1, y2, z1}, - {x1, y2, z2}, - {x2, y1, z1}, - {x2, y1, z2}, - {x2, y2, z1}, - {x2, y2, z2}}; - for (i = 0; i < 8; i++){ - float *corner = corners[i]; - float difference[3]; - vectorSub(difference, sourceposition, corner); - float length2 = vectorDot(difference, difference); - if (length2 < r*r){ - float normal[3]; - vectorNormalize(normal, difference); - collide(object, target->object, normal); - return true; - } - } - - return false; -}*/ - - - -bool SphereShape::checkCollisionPeer(MeshShape *target){ - float position[3] = {0, 0, 0}; - object->transformPoint(position, position); - target->object->unTransformPoint(position, position); - Mesh *mesh = target->mesh; - - float normal[3]; - float contactpoint[3]; - - if (checkSphereMeshCollision(position, r, mesh, normal, contactpoint)){ - target->object->transformVector(normal, normal); - target->object->transformPoint(contactpoint, contactpoint); - - addCollision(object, target->object, normal, contactpoint); - - //vectorAdd(contactnormal, normal); - - return true; - } - return false; -} +#include "main.h" + +#include + +#include "sphere.h" +#include "utils.h" +#include "3dutils.h" +#include "audio.h" +#include "vector.h" +#include "collision.h" +#include "glapi.h" + + +Sphere::Sphere(void){ + appearance = new SphereAppearance(); + Object::appearance = appearance; + geometry = new SphereShape(this); + Object::geometry = geometry; +} + +void Sphere::setRadius(float r){ + if (r < 0) r = -r; + this->r = r; + appearance->setRadius(r); + geometry->setRadius(r); +} + +SphereAppearance::SphereAppearance(void){ + setRadius(1); +} + +void SphereAppearance::setRadius(float r){ + if (r < 0) r = -r; + this->r = r; +} + +void Sphere::setColor(float red, float green, float blue){ + appearance->getMaterial()->setColor(red, green, blue, 1); +} + +void SphereAppearance::draw(void){ + material.enable(); + createSphere(r); +} + + + + +SphereShape::SphereShape(Object *sphere) : Shape(sphere){ + setRadius(1); +} + +void SphereShape::setRadius(float r){ + this->r = r; +} + +float SphereShape::getRadius(void){ + return r; +} + +bool SphereShape::checkCollision(Object *target){ + return target->geometry->checkCollisionPeer(this); +} + +float SphereShape::calculateMomentOfInertia(float *rotationvector){ + return 2.0/3.0*r*r; +} + +/*bool SphereShape::checkCollisionPeer(PlaneShape *target){ + float sourceposition[3], targetposition[3]; + object->getPosition(sourceposition); + target->object->getPosition(targetposition); + float height = target->height + targetposition[1]; + + if (sourceposition[1] - r < height){ + //shotsound->play(); + float normal[3] = {0, 1, 0}; + + float contactpoint[3] = {0, target->height, 0}; + collide(object, target->object, normal, contactpoint); + return true; + } + + return false; +}*/ + +bool SphereShape::checkCollisionPeer(SphereShape *target){ + /*float sourceposition[3], targetposition[3]; + object->getPosition(sourceposition); + target->object->getPosition(targetposition); + float impact[3]; + vectorSub(impact, sourceposition, targetposition);*/ + float impact[3] = {0, 0, 0}; + object->transformPoint(impact, impact); + target->object->unTransformPoint(impact, impact); + float distance2 = vectorDot(impact, impact); + + if (distance2 < (r + target->r)*(r + target->r)){ + /*float temp[3], temp2[3], temp3[3]; + object->getMomentum(temp2); + target->object->getMomentum(temp3); + vectorSub(temp, temp2, temp3); + shotsound->setVolume(1.0-1/(1+vectorLength(temp)*0.5)); + shotsound->play();*/ + float normal[3]; + vectorNormalize(normal, impact); + + float contactpoint[3]; + vectorScale(contactpoint, normal, target->r); + + target->object->transformVector(normal, normal); + target->object->transformPoint(contactpoint, contactpoint); + + addCollision(object, target->object, normal, contactpoint); + + //vectorAdd(contactnormal, normal); + + return true; + } + + return false; +} + +bool between(float x, float x1, float x2){ + if ((x >= x1 && x <=x2) || (x >= x2 && x <=x1)) return true; + return false; +} + +/*bool SphereShape::checkCollisionPeer(BoxShape *target){ + float sourceposition[3], targetposition[3]; + object->getPosition(sourceposition); + target->object->getPosition(targetposition); + float x1 = target->x1 + targetposition[0]; + float x2 = target->x2 + targetposition[0]; + float y1 = target->y1 + targetposition[1]; + float y2 = target->y2 + targetposition[1]; + float z1 = target->z1 + targetposition[2]; + float z2 = target->z2 + targetposition[2]; + float points[3][2] = {{x1, x2}, {y1, y2}, {z1, z2}}; + float p[2], op1[2], op2[2]; + float c, oc1, oc2; + int i; + float normal[3]; + float *normal2[3]; + //Faces + for (i = 0; i < 3; i++){ + p[0] = points[i][0]; + p[1] = points[i][1]; + op1[0] = points[(i+1)%3][0]; + op1[1] = points[(i+1)%3][1]; + op2[0] = points[(i+2)%3][0]; + op2[1] = points[(i+2)%3][1]; + c = sourceposition[i]; + oc1 = sourceposition[(i+1)%3]; + oc2 = sourceposition[(i+2)%3]; + normal2[0] = &normal[i]; + normal2[1] = &normal[(i+1)%3]; + normal2[2] = &normal[(i+2)%3]; + + if (between(oc1, op1[0], op1[1]) && + between(oc2, op2[0], op2[1])){ + if (c < p[0] && c+r > p[0]){ + *normal2[0] = -1; + *normal2[1] = 0; + *normal2[2] = 0; + collide(object, target->object, normal); + return true; + } + if (c > p[1] && c-r < p[1]){ + *normal2[0] = 1; + *normal2[1] = 0; + *normal2[2] = 0; + collide(object, target->object, normal); + return true; + } + } + } + + //Edges + for (i = 0; i < 3; i++){ + p[0] = points[i][0]; + p[1] = points[i][1]; + op1[0] = points[(i+1)%3][0]; + op1[1] = points[(i+1)%3][1]; + op2[0] = points[(i+2)%3][0]; + op2[1] = points[(i+2)%3][1]; + c = sourceposition[i]; + oc1 = sourceposition[(i+1)%3]; + oc2 = sourceposition[(i+2)%3]; + normal2[0] = &normal[i]; + normal2[1] = &normal[(i+1)%3]; + normal2[2] = &normal[(i+2)%3]; + float edges[4][2] = { + {p[0], op1[0]}, + {p[1], op1[0]}, + {p[0], op1[1]}, + {p[1], op1[1]}}; + + if (between(oc2, op2[0], op2[1])){ + int j; + for (j = 0; j < 4; j++){ + float diff[2] = {c - edges[j][0], oc1 - edges[j][1]}; + if (diff[0]*diff[0] + diff[1]*diff[1] < r*r){ + *normal2[0] = diff[0]; + *normal2[1] = diff[1]; + *normal2[2] = 0; + vectorNormalize(normal); + collide(object, target->object, normal); + return true; + } + } + } + } + + //Corners + float corners[8][3] = { + {x1, y1, z1}, + {x1, y1, z2}, + {x1, y2, z1}, + {x1, y2, z2}, + {x2, y1, z1}, + {x2, y1, z2}, + {x2, y2, z1}, + {x2, y2, z2}}; + for (i = 0; i < 8; i++){ + float *corner = corners[i]; + float difference[3]; + vectorSub(difference, sourceposition, corner); + float length2 = vectorDot(difference, difference); + if (length2 < r*r){ + float normal[3]; + vectorNormalize(normal, difference); + collide(object, target->object, normal); + return true; + } + } + + return false; +}*/ + + + +bool SphereShape::checkCollisionPeer(MeshShape *target){ + float position[3] = {0, 0, 0}; + object->transformPoint(position, position); + target->object->unTransformPoint(position, position); + Mesh *mesh = target->mesh; + + float normal[3]; + float contactpoint[3]; + + if (checkSphereMeshCollision(position, r, mesh, normal, contactpoint)){ + target->object->transformVector(normal, normal); + target->object->transformPoint(contactpoint, contactpoint); + + addCollision(object, target->object, normal, contactpoint); + + //vectorAdd(contactnormal, normal); + + return true; + } + return false; +} diff --git a/src/sphere.h b/src/sphere.h index 7b33114..82b6905 100644 --- a/src/sphere.h +++ b/src/sphere.h @@ -1,67 +1,67 @@ -#ifndef __SPHERE_H_INCLUDED__ -#define __SPHERE_H_INCLUDED__ - -#include "object.h" -#include "material.h" -#include "mesh.h" - - -class SphereAppearance; - -//Object for sphere - -class Sphere : public Object{ -private: - float r; - SphereAppearance *appearance; - SphereShape *geometry; - -public: - Sphere(void); - - void setRadius(float r); - void setColor(float red, float green, float blue); -}; - - - -//Appearance of sphere - -class SphereAppearance : public Appearance{ -private: - float r; - -public: - SphereAppearance(void); - - void setRadius(float r); - void draw(void); -}; - - - -//Geometry of sphere - -class SphereShape : public Shape{ -private: - float r; - -public: - SphereShape(Object *sphere); - - void setRadius(float r); - float getRadius(void); - - float calculateMomentOfInertia(float *rotationvector); - - bool checkCollision(Object *target); - - bool checkCollisionPeer(SphereShape *target); - bool checkCollisionPeer(MeshShape *target); - - friend class Sphere; - friend class MeshShape; -}; - -#endif - +#ifndef __SPHERE_H_INCLUDED__ +#define __SPHERE_H_INCLUDED__ + +#include "object.h" +#include "material.h" +#include "mesh.h" + + +class SphereAppearance; + +//Object for sphere + +class Sphere : public Object{ +private: + float r; + SphereAppearance *appearance; + SphereShape *geometry; + +public: + Sphere(void); + + void setRadius(float r); + void setColor(float red, float green, float blue); +}; + + + +//Appearance of sphere + +class SphereAppearance : public Appearance{ +private: + float r; + +public: + SphereAppearance(void); + + void setRadius(float r); + void draw(void); +}; + + + +//Geometry of sphere + +class SphereShape : public Shape{ +private: + float r; + +public: + SphereShape(Object *sphere); + + void setRadius(float r); + float getRadius(void); + + float calculateMomentOfInertia(float *rotationvector); + + bool checkCollision(Object *target); + + bool checkCollisionPeer(SphereShape *target); + bool checkCollisionPeer(MeshShape *target); + + friend class Sphere; + friend class MeshShape; +}; + +#endif + diff --git a/src/texture.cpp b/src/texture.cpp index e835106..d20aa70 100644 --- a/src/texture.cpp +++ b/src/texture.cpp @@ -1,97 +1,97 @@ -#include "texture.h" -#include "graphics.h" - -Texture::Texture(void){ - this->textureId = -1; - this->enabled = false; -} - -Texture::~Texture(void){ - if (textureId != -1){ - DRUID.freeTexture(textureId); - textureId = -1; - enabled = false; - } -} - -Texture::Texture(int id){ - if (id > -1){ - this->textureId = id; - this->enabled = false; - } - else{ - this->textureId = -1; - this->enabled = false; - } -} - -bool Texture::loadImage(char* path){ - format = GL_RGB; - - texture = IMG_Load(path); - - //texture = SDL_DisplayFormatAlpha(texture); - - this->textureId = DRUID.loadTexture(texture, -1); - //this->textureId = DRUID.loadTexture(path, -1); - this->enable(); - return this->isValidId(); -} - -bool Texture::loadImage(char* path, float *trans){ - format = GL_RGBA; - - texture = IMG_Load(path); - - Uint32 colorKey = SDL_MapRGB(texture->format, - (Uint8)(trans[0] * 255), - (Uint8)(trans[1] * 255), - (Uint8)(trans[2] * 255)); - //SDL_SetAlpha(texture, 0, SDL_ALPHA_OPAQUE); - - SDL_SetColorKey(texture, SDL_SRCCOLORKEY, colorKey); - - //SDL_Surface* alphaSurface = SDL_DisplayFormatAlpha(texture); - texture = SDL_DisplayFormatAlpha(texture); - - this->textureId = DRUID.loadTexture(texture, -1, format); - this->enable(); - return this->isValidId(); -} - -void Texture::reload(void){ - this->textureId = DRUID.loadTexture(texture, -1, format); - this->enable(); -} - -void Texture::disable(void){ - this->enabled = false; - glDisable(GL_TEXTURE_2D); -} - -void Texture::enable(void){ - if (textureId > -1){ - this->enabled = true; - glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, textureId); - } -} - -bool Texture::isEnabled(void){ - return this->enabled; -} - -int Texture::getId(void){ - return this->textureId; -} - -void Texture::setId(int id){ - if (id > -1){ - this->textureId = id; - this->enable(); - } -} - -bool Texture::isValidId(void){ - return (this->textureId > -1); -} +#include "texture.h" +#include "graphics.h" + +Texture::Texture(void){ + this->textureId = -1; + this->enabled = false; +} + +Texture::~Texture(void){ + if (textureId != -1){ + DRUID.freeTexture(textureId); + textureId = -1; + enabled = false; + } +} + +Texture::Texture(int id){ + if (id > -1){ + this->textureId = id; + this->enabled = false; + } + else{ + this->textureId = -1; + this->enabled = false; + } +} + +bool Texture::loadImage(char* path){ + format = GL_RGB; + + texture = IMG_Load(path); + + //texture = SDL_DisplayFormatAlpha(texture); + + this->textureId = DRUID.loadTexture(texture, -1); + //this->textureId = DRUID.loadTexture(path, -1); + this->enable(); + return this->isValidId(); +} + +bool Texture::loadImage(char* path, float *trans){ + format = GL_RGBA; + + texture = IMG_Load(path); + + Uint32 colorKey = SDL_MapRGB(texture->format, + (Uint8)(trans[0] * 255), + (Uint8)(trans[1] * 255), + (Uint8)(trans[2] * 255)); + //SDL_SetAlpha(texture, 0, SDL_ALPHA_OPAQUE); + + SDL_SetColorKey(texture, SDL_SRCCOLORKEY, colorKey); + + //SDL_Surface* alphaSurface = SDL_DisplayFormatAlpha(texture); + texture = SDL_DisplayFormatAlpha(texture); + + this->textureId = DRUID.loadTexture(texture, -1, format); + this->enable(); + return this->isValidId(); +} + +void Texture::reload(void){ + this->textureId = DRUID.loadTexture(texture, -1, format); + this->enable(); +} + +void Texture::disable(void){ + this->enabled = false; + glDisable(GL_TEXTURE_2D); +} + +void Texture::enable(void){ + if (textureId > -1){ + this->enabled = true; + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, textureId); + } +} + +bool Texture::isEnabled(void){ + return this->enabled; +} + +int Texture::getId(void){ + return this->textureId; +} + +void Texture::setId(int id){ + if (id > -1){ + this->textureId = id; + this->enable(); + } +} + +bool Texture::isValidId(void){ + return (this->textureId > -1); +} diff --git a/src/texture.h b/src/texture.h index 0ca77ac..517e104 100644 --- a/src/texture.h +++ b/src/texture.h @@ -1,38 +1,38 @@ -#ifndef __TEXTURE_H_INCLUDED__ -#define __TEXTURE_H_INCLUDED__ - -#include -#include "main.h" -class Texture{ - -public: - - Texture(void); - Texture(int id); - ~Texture(void); - - bool loadImage(char* path); - bool loadImage(char* path, float *trans); - void enable(void); - void disable(void); - bool isEnabled(void); - int getId(void); - void setId(int id); - bool isValidId(void); - void reload(void); - - //int* getOGLTexture(void); - //int* getModifiableOGLTexture(void); - -private: - - int textureId; - //int* modTexture; - bool enabled; - - SDL_Surface *texture; - int format; -}; - -#endif - +#ifndef __TEXTURE_H_INCLUDED__ +#define __TEXTURE_H_INCLUDED__ + +#include +#include "main.h" +class Texture{ + +public: + + Texture(void); + Texture(int id); + ~Texture(void); + + bool loadImage(char* path); + bool loadImage(char* path, float *trans); + void enable(void); + void disable(void); + bool isEnabled(void); + int getId(void); + void setId(int id); + bool isValidId(void); + void reload(void); + + //int* getOGLTexture(void); + //int* getModifiableOGLTexture(void); + +private: + + int textureId; + //int* modTexture; + bool enabled; + + SDL_Surface *texture; + int format; +}; + +#endif + diff --git a/src/utils.cpp b/src/utils.cpp index 123e840..a6d2f05 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -1,39 +1,39 @@ -#include - -void swapInt(int *a, int *b){ - int temp = *a; - *a = *b; - *b = temp; -} - -void swapFloat(float *a, float *b){ - float temp = *a; - *a = *b; - *b = temp; -} - -int random(int x){ - return rand() * x / RAND_MAX; -} - -float randomf(float x){ - return rand() * x / RAND_MAX; -} - -int smod(int val, int mod){ - if (val>=0) return val%mod; - int temp=-val/mod+1; - return (val+temp*mod)%mod; -} - -double sdes(double val){ - if (val>=0) return val-(int)(val); - return val-(int)(val)+1; -} - -double sfmod(double val, double mod){ - val-=(int)(val/mod)*mod; - if (val<0) val+=mod; - return val; -} - +#include + +void swapInt(int *a, int *b){ + int temp = *a; + *a = *b; + *b = temp; +} + +void swapFloat(float *a, float *b){ + float temp = *a; + *a = *b; + *b = temp; +} + +int random(int x){ + return rand() * x / RAND_MAX; +} + +float randomf(float x){ + return rand() * x / RAND_MAX; +} + +int smod(int val, int mod){ + if (val>=0) return val%mod; + int temp=-val/mod+1; + return (val+temp*mod)%mod; +} + +double sdes(double val){ + if (val>=0) return val-(int)(val); + return val-(int)(val)+1; +} + +double sfmod(double val, double mod){ + val-=(int)(val/mod)*mod; + if (val<0) val+=mod; + return val; +} + diff --git a/src/utils.h b/src/utils.h index 9d849a6..7fe97a7 100644 --- a/src/utils.h +++ b/src/utils.h @@ -1,16 +1,16 @@ -#ifndef __UTILS_H_INCLUDED__ -#define __UTILS_H_INCLUDED__ - - -#define PI 3.14159265358979323846 - -void swapInt(int *a, int *b); -void swapFloat(float *a, float *b); -int random(int x); -float randomf(float x); -int smod(int val, int mod); -double sdes(double val); -double sfmod(double val, double mod); - -#endif - +#ifndef __UTILS_H_INCLUDED__ +#define __UTILS_H_INCLUDED__ + + +#define PI 3.14159265358979323846 + +void swapInt(int *a, int *b); +void swapFloat(float *a, float *b); +int random(int x); +float randomf(float x); +int smod(int val, int mod); +double sdes(double val); +double sfmod(double val, double mod); + +#endif + diff --git a/src/vector.cpp b/src/vector.cpp index 7544c8e..87326b6 100644 --- a/src/vector.cpp +++ b/src/vector.cpp @@ -1,274 +1,274 @@ -#include - -#include "main.h" -#include "vector.h" -#include "utils.h" - -void vectorSet(float *target, float x, float y, float z){ - target[0] = x; - target[1] = y; - target[2] = z; -} - -void vectorCopy(float *target, float *source){ - target[0] = source[0]; - target[1] = source[1]; - target[2] = source[2]; -} - -void vectorAdd(float *target, float *source1, float *source2){ - target[0] = source1[0] + source2[0]; - target[1] = source1[1] + source2[1]; - target[2] = source1[2] + source2[2]; -} - -void vectorAdd(float *target, float *source){ - target[0] += source[0]; - target[1] += source[1]; - target[2] += source[2]; -} - -void vectorSub(float *target, float *source1, float *source2){ - target[0] = source1[0] - source2[0]; - target[1] = source1[1] - source2[1]; - target[2] = source1[2] - source2[2]; -} - -void vectorSub(float *target, float *source){ - target[0] -= source[0]; - target[1] -= source[1]; - target[2] -= source[2]; -} - -void vectorNegative(float *target, float *source){ - target[0] = -source[0]; - target[1] = -source[1]; - target[2] = -source[2]; -} - -void vectorNegative(float *target){ - target[0] = -target[0]; - target[1] = -target[1]; - target[2] = -target[2]; -} - -void vectorScale(float *target, float *source, float scale){ - target[0] = source[0] * scale; - target[1] = source[1] * scale; - target[2] = source[2] * scale; -} - -void vectorScale(float *target, float scale){ - target[0] *= scale; - target[1] *= scale; - target[2] *= scale; -} - -float vectorDot(float *source1, float *source2){ - return source1[0]*source2[0] + source1[1]*source2[1] + source1[2]*source2[2]; -} - -float vectorNormalizedDot(float *source1, float *source2){ - return vectorDot(source1, source2) / (vectorLength(source1) * vectorLength(source2)); -} - -float vectorLength(float *source){ - return sqrtf(vectorDot(source, source)); -} - -void vectorCross(float *target, float *source1, float *source2){ - target[0] = source1[1]*source2[2] - source1[2]*source2[1]; - target[1] = source1[2]*source2[0] - source1[0]*source2[2]; - target[2] = source1[0]*source2[1] - source1[1]*source2[0]; -} - -void vectorNormalize(float *target, float *source){ - vectorScale(target, source, 1.0/vectorLength(source)); -} - -void vectorNormalize(float *target){ - vectorScale(target, 1.0/vectorLength(target)); -} - -void vectorReflect(float *target, float *source, float *normal){ - vectorCopy(target, normal); - vectorScale(target, -vectorDot(source, normal)*2); - vectorAdd(target, source); -} - -void vectorProject(float *target, float *source1, float *source2){ - vectorScale(target, source2, vectorDot(source1, source2) / vectorDot(source2, source2)); -} - -bool vectorIsZero(float *vector){ - if (vector[0] == 0 && vector[1] == 0 && vector[2] == 0) return true; - //if (vectorDot(vector, vector) < 0.00001) return true; - else return false; -} - -void vectorSaturate(float *target, float *source, float min, float max){ - float len = vectorLength(source); - if (len < min){ - len = min; - } else if (len > max){ - len = max; - } else{ - if (target != source) vectorCopy(target, source); - return; - } - vectorNormalize(target, source); - vectorScale(target, len); -} - -void vectorSaturate(float *vector, float min, float max){ - vectorSaturate(vector, vector, min, max); -} - -void vectorMatrixMultiply(float *target, float *source, float *matrix){ - float source2[3]; - if (source == target){ - vectorCopy(source2, source); - source = source2; - } - int x; - for (x = 0; x < 3; x++){ - target[x] = source[0]*matrix[0+x] + - source[1]*matrix[3+x] + - source[2]*matrix[6+x]; - } -} - - - -void matrixSet(float *matrix, - float x1, float y1, float z1, - float x2, float y2, float z2, - float x3, float y3, float z3){ - matrix[0] = x1; - matrix[1] = y1; - matrix[2] = z1; - matrix[3] = x2; - matrix[4] = y2; - matrix[5] = z2; - matrix[6] = x3; - matrix[7] = y3; - matrix[8] = z3; -} - -void matrixSet(float *matrix, float *r1, float *r2, float *r3){ - vectorCopy(&matrix[0], r1); - vectorCopy(&matrix[3], r2); - vectorCopy(&matrix[6], r3); -} - -void matrixCopy(float *target, float *source){ - target[0] = source[0]; - target[1] = source[1]; - target[2] = source[2]; - target[3] = source[3]; - target[4] = source[4]; - target[5] = source[5]; - target[6] = source[6]; - target[7] = source[7]; - target[8] = source[8]; -} - -void matrixIdentity(float *matrix){ - matrixSet(matrix, 1, 0, 0, 0, 1, 0, 0, 0, 1); -} - -void matrixAdd(float *target, float *source1, float *source2){ - target[0] = source1[0] + source2[0]; - target[1] = source1[1] + source2[1]; - target[2] = source1[2] + source2[2]; - target[3] = source1[3] + source2[3]; - target[4] = source1[4] + source2[4]; - target[5] = source1[5] + source2[5]; - target[6] = source1[6] + source2[6]; - target[7] = source1[7] + source2[7]; - target[8] = source1[8] + source2[8]; -} - -void matrixAdd(float *target, float *source){ - target[0] += source[0]; - target[1] += source[1]; - target[2] += source[2]; - target[3] += source[3]; - target[4] += source[4]; - target[5] += source[5]; - target[6] += source[6]; - target[7] += source[7]; - target[8] += source[8]; -} - -void matrixMultiply(float *target, float *source1, float *source2){ - float target2[9]; - float *oldtarget = target; - bool copy = false; - if (source1 == target || source2 == target){ - copy = true; - target = target2; - } - int x, y; - for (y = 0; y < 3; y++){ - for (x = 0; x < 3; x++){ - *target = source1[y*3+0]*source2[x] + - source1[y*3+1]*source2[3+x] + - source1[y*3+2]*source2[6+x]; - target++; - } - } - if (copy){ - matrixCopy(oldtarget, target2); - } -} - -/*void matrixMultiply(float *target, float *source){ - matrixMultiply(target, source, source); -}*/ - -/*void matrixRotate(float *matrix, float *vector){ - float rotmat[9]; - createRotationMatrix(rotmat, vector); - matrixMultiply(matrix, matrix, rotmat); -}*/ - -void matrixCreateRotation(float *matrix, float *vector){ - float angle = vectorLength(vector); - float n[3]; - vectorNormalize(n, vector); - - float c = cos(angle); - float s = sin(angle); - float t = 1 - c; - - float x = n[0]; - float y = n[1]; - float z = n[2]; - - matrixSet(matrix, - t*x*x + c, t*y*x + s*z, t*z*x - s*y, - t*x*y - s*z, t*y*y + c, t*z*y + s*x, - t*x*z + s*y, t*y*z - s*x, t*z*z + c); - -} - -void matrixTranspose(float *target, float *source){ - target[0] = source[0]; target[1] = source[3]; target[2] = source[6]; - target[3] = source[1]; target[4] = source[4]; target[5] = source[7]; - target[6] = source[2]; target[7] = source[5]; target[8] = source[8]; -} - - -/*void rotatePointAroundVector(float *target, float *point, float *vector){ - float angle = vectorLength(vector); - float n[3]; - vectorNormalize(n, vector); - - float c = cos(angle); - float s = sin(angle); - float t = 1 - c; - - //r' = r*c + n*(n . r)*t + (r x n)*s -}*/ - +#include + +#include "main.h" +#include "vector.h" +#include "utils.h" + +void vectorSet(float *target, float x, float y, float z){ + target[0] = x; + target[1] = y; + target[2] = z; +} + +void vectorCopy(float *target, float *source){ + target[0] = source[0]; + target[1] = source[1]; + target[2] = source[2]; +} + +void vectorAdd(float *target, float *source1, float *source2){ + target[0] = source1[0] + source2[0]; + target[1] = source1[1] + source2[1]; + target[2] = source1[2] + source2[2]; +} + +void vectorAdd(float *target, float *source){ + target[0] += source[0]; + target[1] += source[1]; + target[2] += source[2]; +} + +void vectorSub(float *target, float *source1, float *source2){ + target[0] = source1[0] - source2[0]; + target[1] = source1[1] - source2[1]; + target[2] = source1[2] - source2[2]; +} + +void vectorSub(float *target, float *source){ + target[0] -= source[0]; + target[1] -= source[1]; + target[2] -= source[2]; +} + +void vectorNegative(float *target, float *source){ + target[0] = -source[0]; + target[1] = -source[1]; + target[2] = -source[2]; +} + +void vectorNegative(float *target){ + target[0] = -target[0]; + target[1] = -target[1]; + target[2] = -target[2]; +} + +void vectorScale(float *target, float *source, float scale){ + target[0] = source[0] * scale; + target[1] = source[1] * scale; + target[2] = source[2] * scale; +} + +void vectorScale(float *target, float scale){ + target[0] *= scale; + target[1] *= scale; + target[2] *= scale; +} + +float vectorDot(float *source1, float *source2){ + return source1[0]*source2[0] + source1[1]*source2[1] + source1[2]*source2[2]; +} + +float vectorNormalizedDot(float *source1, float *source2){ + return vectorDot(source1, source2) / (vectorLength(source1) * vectorLength(source2)); +} + +float vectorLength(float *source){ + return sqrtf(vectorDot(source, source)); +} + +void vectorCross(float *target, float *source1, float *source2){ + target[0] = source1[1]*source2[2] - source1[2]*source2[1]; + target[1] = source1[2]*source2[0] - source1[0]*source2[2]; + target[2] = source1[0]*source2[1] - source1[1]*source2[0]; +} + +void vectorNormalize(float *target, float *source){ + vectorScale(target, source, 1.0/vectorLength(source)); +} + +void vectorNormalize(float *target){ + vectorScale(target, 1.0/vectorLength(target)); +} + +void vectorReflect(float *target, float *source, float *normal){ + vectorCopy(target, normal); + vectorScale(target, -vectorDot(source, normal)*2); + vectorAdd(target, source); +} + +void vectorProject(float *target, float *source1, float *source2){ + vectorScale(target, source2, vectorDot(source1, source2) / vectorDot(source2, source2)); +} + +bool vectorIsZero(float *vector){ + if (vector[0] == 0 && vector[1] == 0 && vector[2] == 0) return true; + //if (vectorDot(vector, vector) < 0.00001) return true; + else return false; +} + +void vectorSaturate(float *target, float *source, float min, float max){ + float len = vectorLength(source); + if (len < min){ + len = min; + } else if (len > max){ + len = max; + } else{ + if (target != source) vectorCopy(target, source); + return; + } + vectorNormalize(target, source); + vectorScale(target, len); +} + +void vectorSaturate(float *vector, float min, float max){ + vectorSaturate(vector, vector, min, max); +} + +void vectorMatrixMultiply(float *target, float *source, float *matrix){ + float source2[3]; + if (source == target){ + vectorCopy(source2, source); + source = source2; + } + int x; + for (x = 0; x < 3; x++){ + target[x] = source[0]*matrix[0+x] + + source[1]*matrix[3+x] + + source[2]*matrix[6+x]; + } +} + + + +void matrixSet(float *matrix, + float x1, float y1, float z1, + float x2, float y2, float z2, + float x3, float y3, float z3){ + matrix[0] = x1; + matrix[1] = y1; + matrix[2] = z1; + matrix[3] = x2; + matrix[4] = y2; + matrix[5] = z2; + matrix[6] = x3; + matrix[7] = y3; + matrix[8] = z3; +} + +void matrixSet(float *matrix, float *r1, float *r2, float *r3){ + vectorCopy(&matrix[0], r1); + vectorCopy(&matrix[3], r2); + vectorCopy(&matrix[6], r3); +} + +void matrixCopy(float *target, float *source){ + target[0] = source[0]; + target[1] = source[1]; + target[2] = source[2]; + target[3] = source[3]; + target[4] = source[4]; + target[5] = source[5]; + target[6] = source[6]; + target[7] = source[7]; + target[8] = source[8]; +} + +void matrixIdentity(float *matrix){ + matrixSet(matrix, 1, 0, 0, 0, 1, 0, 0, 0, 1); +} + +void matrixAdd(float *target, float *source1, float *source2){ + target[0] = source1[0] + source2[0]; + target[1] = source1[1] + source2[1]; + target[2] = source1[2] + source2[2]; + target[3] = source1[3] + source2[3]; + target[4] = source1[4] + source2[4]; + target[5] = source1[5] + source2[5]; + target[6] = source1[6] + source2[6]; + target[7] = source1[7] + source2[7]; + target[8] = source1[8] + source2[8]; +} + +void matrixAdd(float *target, float *source){ + target[0] += source[0]; + target[1] += source[1]; + target[2] += source[2]; + target[3] += source[3]; + target[4] += source[4]; + target[5] += source[5]; + target[6] += source[6]; + target[7] += source[7]; + target[8] += source[8]; +} + +void matrixMultiply(float *target, float *source1, float *source2){ + float target2[9]; + float *oldtarget = target; + bool copy = false; + if (source1 == target || source2 == target){ + copy = true; + target = target2; + } + int x, y; + for (y = 0; y < 3; y++){ + for (x = 0; x < 3; x++){ + *target = source1[y*3+0]*source2[x] + + source1[y*3+1]*source2[3+x] + + source1[y*3+2]*source2[6+x]; + target++; + } + } + if (copy){ + matrixCopy(oldtarget, target2); + } +} + +/*void matrixMultiply(float *target, float *source){ + matrixMultiply(target, source, source); +}*/ + +/*void matrixRotate(float *matrix, float *vector){ + float rotmat[9]; + createRotationMatrix(rotmat, vector); + matrixMultiply(matrix, matrix, rotmat); +}*/ + +void matrixCreateRotation(float *matrix, float *vector){ + float angle = vectorLength(vector); + float n[3]; + vectorNormalize(n, vector); + + float c = cos(angle); + float s = sin(angle); + float t = 1 - c; + + float x = n[0]; + float y = n[1]; + float z = n[2]; + + matrixSet(matrix, + t*x*x + c, t*y*x + s*z, t*z*x - s*y, + t*x*y - s*z, t*y*y + c, t*z*y + s*x, + t*x*z + s*y, t*y*z - s*x, t*z*z + c); + +} + +void matrixTranspose(float *target, float *source){ + target[0] = source[0]; target[1] = source[3]; target[2] = source[6]; + target[3] = source[1]; target[4] = source[4]; target[5] = source[7]; + target[6] = source[2]; target[7] = source[5]; target[8] = source[8]; +} + + +/*void rotatePointAroundVector(float *target, float *point, float *vector){ + float angle = vectorLength(vector); + float n[3]; + vectorNormalize(n, vector); + + float c = cos(angle); + float s = sin(angle); + float t = 1 - c; + + //r' = r*c + n*(n . r)*t + (r x n)*s +}*/ + diff --git a/src/vector.h b/src/vector.h index bc53d1d..77ccfe7 100644 --- a/src/vector.h +++ b/src/vector.h @@ -1,50 +1,50 @@ -#ifndef __VECTOR_H_INCLUDED__ -#define __VECTOR_H_INCLUDED__ - -#include "main.h" - -void vectorSet(float *target, float x, float y, float z); -void vectorCopy(float *target, float *source); -void vectorAdd(float *target, float *source1, float *source2); -void vectorAdd(float *target, float *source); -void vectorSub(float *target, float *source); -void vectorSub(float *target, float *source1, float *source2); -void vectorNegative(float *target, float *source); -void vectorNegative(float *target); -void vectorScale(float *target, float *source, float scale); -void vectorScale(float *target, float scale); -float vectorDot(float *source1, float *source2); -float vectorNormalizedDot(float *source1, float *source2); -float vectorLength(float *source); -void vectorCross(float *target, float *source1, float *source2); -void vectorNormalize(float *target, float *source); -void vectorNormalize(float *target); -void vectorReflect(float *target, float *source, float *normal); -bool vectorIsZero(float *vector); -void vectorSaturate(float *target, float *source, float min, float max); -void vectorSaturate(float *vector, float min, float max); - -//Projects vector source1 onto vector source2 -void vectorProject(float *target, float *source1, float *source2); - -void vectorMatrixMultiply(float *target, float *source, float *matrix); - - - -void matrixSet(float *matrix, - float x1, float y1, float z1, - float x2, float y2, float z2, - float x3, float y3, float z3); -void matrixSet(float *matrix, float *r1, float *r2, float *r3); -void matrixCopy(float *target, float *source); -void matrixIdentity(float *matrix); -void matrixAdd(float *target, float *source1, float *source2); -void matrixAdd(float *target, float *source); -void matrixMultiply(float *target, float *source1, float *source2); -//void matrixMultiply(float *target, float *source); -void matrixRotate(float *matrix, float *vector); -void matrixCreateRotation(float *matrix, float *vector); -void matrixTranspose(float *target, float *source); - -#endif - +#ifndef __VECTOR_H_INCLUDED__ +#define __VECTOR_H_INCLUDED__ + +#include "main.h" + +void vectorSet(float *target, float x, float y, float z); +void vectorCopy(float *target, float *source); +void vectorAdd(float *target, float *source1, float *source2); +void vectorAdd(float *target, float *source); +void vectorSub(float *target, float *source); +void vectorSub(float *target, float *source1, float *source2); +void vectorNegative(float *target, float *source); +void vectorNegative(float *target); +void vectorScale(float *target, float *source, float scale); +void vectorScale(float *target, float scale); +float vectorDot(float *source1, float *source2); +float vectorNormalizedDot(float *source1, float *source2); +float vectorLength(float *source); +void vectorCross(float *target, float *source1, float *source2); +void vectorNormalize(float *target, float *source); +void vectorNormalize(float *target); +void vectorReflect(float *target, float *source, float *normal); +bool vectorIsZero(float *vector); +void vectorSaturate(float *target, float *source, float min, float max); +void vectorSaturate(float *vector, float min, float max); + +//Projects vector source1 onto vector source2 +void vectorProject(float *target, float *source1, float *source2); + +void vectorMatrixMultiply(float *target, float *source, float *matrix); + + + +void matrixSet(float *matrix, + float x1, float y1, float z1, + float x2, float y2, float z2, + float x3, float y3, float z3); +void matrixSet(float *matrix, float *r1, float *r2, float *r3); +void matrixCopy(float *target, float *source); +void matrixIdentity(float *matrix); +void matrixAdd(float *target, float *source1, float *source2); +void matrixAdd(float *target, float *source); +void matrixMultiply(float *target, float *source1, float *source2); +//void matrixMultiply(float *target, float *source); +void matrixRotate(float *matrix, float *vector); +void matrixCreateRotation(float *matrix, float *vector); +void matrixTranspose(float *target, float *source); + +#endif + diff --git a/src/world.cpp b/src/world.cpp index 8b54595..aa0fe25 100644 --- a/src/world.cpp +++ b/src/world.cpp @@ -1,211 +1,211 @@ -#include "world.h" - -#include "object.h" -#include "collision.h" -#include "vector.h" - -World::World(void){ - childlist = NULL; - linklist = NULL; - maxparticles = 500; - particles = new Particle *[maxparticles]; - particlecount = 0; -} - -void World::prepare(void){ - objectlist *node = childlist; - childcount = 0; - while (node != NULL){ - Object *child = node->object; - child->prepare(); - node = node->next; - childcount++; - } - - childs = new Object *[childcount]; - node = childlist; - int i = 0; - while (node != NULL){ - Object *child = node->object; - childs[i] = child; - node = node->next; - i++; - } - - contacts = new Contact[MAXCONTACTS];//childcount*childcount]; -} - -#define GRAVITY 9.81 -//#define GRAVITY 15 - -void World::move(void){ - int i, j; - - - //Gravity - float gravity[3]; - vectorSet(gravity, 0, 0, 0); - for (i = 0; i < childcount; i++){ - Object *object = childs[i]; - if (object->gravity){ - gravity[1] = -object->getMass()*GRAVITY; - object->addExternalForce(gravity); - } - } - - /*for (i = 0; i < particlecount; i++){ - Particle *object = particles[i]; - if (object->gravity){ - gravity[1] = -object->getMass()*GRAVITY; - object->addExternalForce(gravity); - } - }*/ - - - //Collisions - contactcount = 0; - - for (i = 0; i < childcount; i++){ - Object *object1 = childs[i]; - int group1 = object1->getCollisionGroup(); - for (j = i+1; j < childcount; j++){ - Object *object2 = childs[j]; - int group2 = object2->getCollisionGroup(); - - if (isCollisionLink(group1, group2)){ - object2->geometry->checkCollision(object1); - } - } - } - - /*for (i = 0; i < particlecount; i++){ - Particle *object1 = particles[i]; - int group1 = object1->getCollisionGroup(); - for (j = 0; j < childcount; j++){ - Object *object2 = childs[j]; - int group2 = object2->getCollisionGroup(); - - if (isCollisionLink(group1, group2)){ - object2->geometry->checkCollision(object1); - } - } - }*/ - - //printf("Contacts: %i\n", contactcount); - - - bool contactresponse; - - j = 0; - do{ - contactresponse = false; - - //Links between objects - objectlinklist *node = linklist; - while (node != NULL){ - ObjectLink *link = node->link; - if (handleLink(link)) contactresponse = true; - node = node->next; - } - - //Collision contact - for (i = 0; i < contactcount; i++){ - Contact *contact = &contacts[i]; - if (handleCollision(contact)) contactresponse = true; - } - - j++; - } while (contactresponse && j < 10); - - /*j = 0; - do{ - contactresponse = false; - - //Collision contact - for (i = 0; i < contactcount; i++){ - Contact *contact = &contacts[i]; - if (handleCollision(contact)) contactresponse = true; - } - - j++; - } while (contactresponse && j < 10);*/ - - /*j = 0; - do{ - contactresponse = false; - - //Links between objects - objectlinklist *node = linklist; - while (node != NULL){ - ObjectLink *link = node->link; - if (handleLink(link)) contactresponse = true; - node = node->next; - } - - j++; - } while (contactresponse && j < 3);*/ - - - for (i = 0; i < childcount; i++){ - childs[i]->move(); - } - for (i = 0; i < particlecount; i++){ - particles[i]->move(); - } -} - -void World::draw(void){ - int i; - for (i = 0; i < childcount; i++) childs[i]->draw(); - for (i = 0; i < particlecount; i++) particles[i]->draw(); -} - -void World::addChild(Object *child){ - objectlist *node = new objectlist; - node->object = child; - node->next = childlist; - childlist = node; -} - -void World::addParticle(Particle *particle){ - if (particlecount < maxparticles){ - particles[particlecount++] = particle; - } -} - -void World::removeParticle(Particle *particle){ - int i; - for (i = 0; i < particlecount; i++){ - if (particles[i] == particle){ - particles[i] = particles[particlecount-1]; - particlecount--; - break; - } - } -} - -ObjectLink *World::addLink(Object *object1, Object *object2, float *point){ - ObjectLink *link = new ObjectLink(); - link->object1 = object1; - link->object2 = object2; - if (point != NULL){ - object1->unTransformPoint(link->point1, point); - object2->unTransformPoint(link->point2, point); - link->enabled = true; - } else{ - link->enabled = false; - } - objectlinklist *node = new objectlinklist; - node->link = link; - node->next = linklist; - linklist = node; - return link; -} - -void World::renewLink(ObjectLink *link, float *point){ - link->object1->unTransformPoint(link->point1, point); - link->object2->unTransformPoint(link->point2, point); - link->enabled = true; -} - - +#include "world.h" + +#include "object.h" +#include "collision.h" +#include "vector.h" + +World::World(void){ + childlist = NULL; + linklist = NULL; + maxparticles = 500; + particles = new Particle *[maxparticles]; + particlecount = 0; +} + +void World::prepare(void){ + objectlist *node = childlist; + childcount = 0; + while (node != NULL){ + Object *child = node->object; + child->prepare(); + node = node->next; + childcount++; + } + + childs = new Object *[childcount]; + node = childlist; + int i = 0; + while (node != NULL){ + Object *child = node->object; + childs[i] = child; + node = node->next; + i++; + } + + contacts = new Contact[MAXCONTACTS];//childcount*childcount]; +} + +#define GRAVITY 9.81 +//#define GRAVITY 15 + +void World::move(void){ + int i, j; + + + //Gravity + float gravity[3]; + vectorSet(gravity, 0, 0, 0); + for (i = 0; i < childcount; i++){ + Object *object = childs[i]; + if (object->gravity){ + gravity[1] = -object->getMass()*GRAVITY; + object->addExternalForce(gravity); + } + } + + /*for (i = 0; i < particlecount; i++){ + Particle *object = particles[i]; + if (object->gravity){ + gravity[1] = -object->getMass()*GRAVITY; + object->addExternalForce(gravity); + } + }*/ + + + //Collisions + contactcount = 0; + + for (i = 0; i < childcount; i++){ + Object *object1 = childs[i]; + int group1 = object1->getCollisionGroup(); + for (j = i+1; j < childcount; j++){ + Object *object2 = childs[j]; + int group2 = object2->getCollisionGroup(); + + if (isCollisionLink(group1, group2)){ + object2->geometry->checkCollision(object1); + } + } + } + + /*for (i = 0; i < particlecount; i++){ + Particle *object1 = particles[i]; + int group1 = object1->getCollisionGroup(); + for (j = 0; j < childcount; j++){ + Object *object2 = childs[j]; + int group2 = object2->getCollisionGroup(); + + if (isCollisionLink(group1, group2)){ + object2->geometry->checkCollision(object1); + } + } + }*/ + + //printf("Contacts: %i\n", contactcount); + + + bool contactresponse; + + j = 0; + do{ + contactresponse = false; + + //Links between objects + objectlinklist *node = linklist; + while (node != NULL){ + ObjectLink *link = node->link; + if (handleLink(link)) contactresponse = true; + node = node->next; + } + + //Collision contact + for (i = 0; i < contactcount; i++){ + Contact *contact = &contacts[i]; + if (handleCollision(contact)) contactresponse = true; + } + + j++; + } while (contactresponse && j < 10); + + /*j = 0; + do{ + contactresponse = false; + + //Collision contact + for (i = 0; i < contactcount; i++){ + Contact *contact = &contacts[i]; + if (handleCollision(contact)) contactresponse = true; + } + + j++; + } while (contactresponse && j < 10);*/ + + /*j = 0; + do{ + contactresponse = false; + + //Links between objects + objectlinklist *node = linklist; + while (node != NULL){ + ObjectLink *link = node->link; + if (handleLink(link)) contactresponse = true; + node = node->next; + } + + j++; + } while (contactresponse && j < 3);*/ + + + for (i = 0; i < childcount; i++){ + childs[i]->move(); + } + for (i = 0; i < particlecount; i++){ + particles[i]->move(); + } +} + +void World::draw(void){ + int i; + for (i = 0; i < childcount; i++) childs[i]->draw(); + for (i = 0; i < particlecount; i++) particles[i]->draw(); +} + +void World::addChild(Object *child){ + objectlist *node = new objectlist; + node->object = child; + node->next = childlist; + childlist = node; +} + +void World::addParticle(Particle *particle){ + if (particlecount < maxparticles){ + particles[particlecount++] = particle; + } +} + +void World::removeParticle(Particle *particle){ + int i; + for (i = 0; i < particlecount; i++){ + if (particles[i] == particle){ + particles[i] = particles[particlecount-1]; + particlecount--; + break; + } + } +} + +ObjectLink *World::addLink(Object *object1, Object *object2, float *point){ + ObjectLink *link = new ObjectLink(); + link->object1 = object1; + link->object2 = object2; + if (point != NULL){ + object1->unTransformPoint(link->point1, point); + object2->unTransformPoint(link->point2, point); + link->enabled = true; + } else{ + link->enabled = false; + } + objectlinklist *node = new objectlinklist; + node->link = link; + node->next = linklist; + linklist = node; + return link; +} + +void World::renewLink(ObjectLink *link, float *point){ + link->object1->unTransformPoint(link->point1, point); + link->object2->unTransformPoint(link->point2, point); + link->enabled = true; +} + + diff --git a/src/world.h b/src/world.h index f657587..dc6a672 100644 --- a/src/world.h +++ b/src/world.h @@ -1,56 +1,56 @@ -#ifndef __WORLD_H_INCLUDED__ -#define __WORLD_H_INCLUDED__ - -class World; -class ObjectLink; - -#include "object.h" -#include "particle.h" - -class ObjectLink{ -public: - Object *object1, *object2; - float point1[3], point2[3]; - bool enabled; -}; - -struct objectlinklist{ - ObjectLink *link; - objectlinklist *next; -}; - -#define MAXCONTACTS 100 - -class World{ -private: - objectlist *childlist; - - int childcount; - Object **childs; - - - int particlecount; - int maxparticles; - Particle **particles; - - - objectlinklist *linklist; -public: - World(void); - - void prepare(void); - void move(void); - void draw(void); - - void addChild(Object *child); - - void addParticle(Particle *particle); - void removeParticle(Particle *particle); - - //Point is world-relative - ObjectLink *addLink(Object *object1, Object *object2, float *point); - void renewLink(ObjectLink *link, float *point); -}; - -#endif - +#ifndef __WORLD_H_INCLUDED__ +#define __WORLD_H_INCLUDED__ + +class World; +class ObjectLink; + +#include "object.h" +#include "particle.h" + +class ObjectLink{ +public: + Object *object1, *object2; + float point1[3], point2[3]; + bool enabled; +}; + +struct objectlinklist{ + ObjectLink *link; + objectlinklist *next; +}; + +#define MAXCONTACTS 100 + +class World{ +private: + objectlist *childlist; + + int childcount; + Object **childs; + + + int particlecount; + int maxparticles; + Particle **particles; + + + objectlinklist *linklist; +public: + World(void); + + void prepare(void); + void move(void); + void draw(void); + + void addChild(Object *child); + + void addParticle(Particle *particle); + void removeParticle(Particle *particle); + + //Point is world-relative + ObjectLink *addLink(Object *object1, Object *object2, float *point); + void renewLink(ObjectLink *link, float *point); +}; + +#endif +