522 lines
13 KiB
C++
522 lines
13 KiB
C++
/*
|
|
* $Id: legoblocks.cpp,v 1.20 2002/07/22 11:44:37 jkaarlas Exp $
|
|
*
|
|
*
|
|
* $Log: legoblocks.cpp,v $
|
|
* Revision 1.20 2002/07/22 11:44:37 jkaarlas
|
|
* naama
|
|
*
|
|
* Revision 1.19 2002/07/18 23:05:31 msell
|
|
* Partikkelit ja kakkospelaajan liike
|
|
*
|
|
* Revision 1.18 2002/07/17 20:32:47 msell
|
|
* Detail-optio toimii
|
|
*
|
|
* Revision 1.17 2002/07/16 17:16:34 msell
|
|
* Fontit ja valikot
|
|
*
|
|
* Revision 1.16 2002/07/16 00:42:43 msell
|
|
* Uusia skyboxeja ja areenan säätöä
|
|
*
|
|
* Revision 1.15 2002/07/15 20:32:35 msell
|
|
* Uudet valot ja ulkoasun parantelua
|
|
*
|
|
* Revision 1.14 2002/07/15 15:22:08 msell
|
|
* Parantelua
|
|
*
|
|
* Revision 1.13 2002/07/14 21:40:43 msell
|
|
* Conflictit pois, liikkumiset (hyppy, kävely, lyönti), uusi areena
|
|
*
|
|
* Revision 1.12 2002/06/30 16:05:04 msell
|
|
* Törmäyksien parantelua, transformaatioita mukana
|
|
*
|
|
* Revision 1.11 2002/06/27 00:08:04 msell
|
|
* Kimmotukset palloille myös pyöritettyihin mesheihin
|
|
*
|
|
* Revision 1.10 2002/06/24 14:12:15 msell
|
|
* Nyt toimii sphere -> mesh -törmäykset, ihan tosi
|
|
*
|
|
* Revision 1.9 2002/06/24 04:41:43 jkaarlas
|
|
* tekstuurikoordinaatteja korjattu
|
|
*
|
|
* Revision 1.8 2002/06/20 22:50:12 msell
|
|
* Meshit
|
|
*
|
|
* Revision 1.7 2002/06/20 00:21:01 jkaarlas
|
|
* materiaali- ja tekstuurihommia edistetty
|
|
*
|
|
* Revision 1.6 2002/06/17 19:58:08 msell
|
|
* #includeiden parantelua
|
|
*
|
|
* Revision 1.5 2002/06/15 17:18:37 msell
|
|
* Toimiva törmäystarkastus kiinteille laatikoille
|
|
*
|
|
* Revision 1.4 2002/06/05 18:39:04 msell
|
|
* Jotain pientä
|
|
*
|
|
* Revision 1.3 2002/06/05 15:00:41 msell
|
|
* Palikoihin lisää detailia, facet jaetaan halutun kokosiin osiin
|
|
*
|
|
* Revision 1.2 2002/06/04 16:28:32 msell
|
|
* #pragma once
|
|
*
|
|
* Revision 1.1 2002/06/03 23:06:38 msell
|
|
* no message
|
|
*
|
|
*
|
|
*
|
|
*
|
|
* $Date: 2002/07/22 11:44:37 $
|
|
*
|
|
*/
|
|
|
|
#include "main.h"
|
|
|
|
#include <math.h>
|
|
|
|
#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);
|
|
} |