/* orxonox - the future of 3D-vertical-scrollers Copyright (C) 2004 orx This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. ### File Specific: main-programmer: Benjamin Grauer co-programmer: ... */ #define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_MODEL #include "primitive_model.h" #include "vector.h" #include "debug.h" /** * Creates a 3D-Model of Primitive-Type type if you want to just display a Cube/Sphere/Cylinder/... without any material. @todo implement Cube/Sphere/Cylinder/... */ PrimitiveModel::PrimitiveModel(PRIMITIVE type, float size, unsigned int detail) { switch (type) { default: case PRIM_CUBE: this->cubeModel(); break; case PRIM_SPHERE: this->sphereModel(size, detail); break; case PRIM_CYLINDER: this->cylinderModel(); break; case PRIM_CONE: this->coneModel(size, detail); break; case PRIM_PLANE: this->planeModel(size, detail); break; } this->finalize(); } /** * standard deconstructor */ PrimitiveModel::~PrimitiveModel () { // delete what has to be deleted here } /** * Builds a Sphere into the Model. * @param size The diameter of the Sphere. * @param detail The detail of the Sphere. */ void PrimitiveModel::sphereModel(float size, unsigned int detail) { if (detail <= 0) detail = 1; size /= 2.0; // detail = 2; // make it even float df = (float)detail; // defining the Vertices for (float i = 0; i < df *2.0; i+=1.0) { float vi = i/df * PI; for (float j = -df / 2.0 +1.0; j <= df / 2.0; j+=1.0 *df/(df+1.0)) { float vj = j/df *PI; this->addVertexNormal(cos(vi) * cos(vj), sin(vj), sin(vi) * cos(vj)); this->addVertex(size * cos(vi) * cos(vj), size * sin(vj), size * sin(vi) * cos(vj)); this->addVertexTexture( i / (df *2.0), (j-1.0)/(df)+.5); } } this->addVertex(0, -size, 0); this->addVertexNormal(0, -1, 0); this->addVertexTexture(0,0); this->addVertex(0, size, 0); this->addVertexNormal(0, 1, 0); this->addVertexTexture(0 ,1); // defining the binding Faces. int v1, v2, v3, v4; for (unsigned int i = 0; i <= detail * 2 -1; i++) { for (unsigned int j = 0; j <= detail; j++) { v1 = i*detail + j-1; v4 = i*detail + j; if (i == detail*2 -1) { v2 = j-1; v3 = j; } else { v2 = (i+1)*detail + j-1; v3 = (i+1)*detail + j; } if (j == 0) { v1 = this->getVertexCount() - 2; this->addFace(3, VERTEX_TEXCOORD_NORMAL, v1, v1, v1, v3, v3, v3, v4, v4, v4); } else if (j == detail) { v3 = this->getVertexCount()-1; this->addFace(3, VERTEX_TEXCOORD_NORMAL, v1, v1, v1, v2, v2, v2, v3, v3, v3); } else this->addFace(4, VERTEX_TEXCOORD_NORMAL, v1, v1, v1, v2, v2, v2, v3, v3, v3, v4, v4, v4); } } } /** * Creates a Cylinder. */ void PrimitiveModel::cylinderModel(float size, unsigned int detail) { // check if devision by zero if (detail <= 3) detail = 3; unsigned int count = 0; // defining Points of the Cylinder. for (float phi = 0.0; phi < 2.0*PI; phi += 2.0*PI/(float)detail) { this->addVertex(size*cos(phi), size*sin(phi), -size); this->addVertex(size*cos(phi), size*sin(phi), size); count ++; } this->addVertex(0, 0, -size); this->addVertex(0, 0, size); if (count != detail) { PRINTF(1)("calculation error, count should be %d but is %d.\n", detail, count); } // adding Faces for (unsigned int i = 0; i < detail-1; i++) { int p1, p2, p3, p4; p1 = 2*i; p2 = 2*i+1; p3 = 2*i+3; p4 = 2*i+2; // something is wrong here this->addFace(4, VERTEX_ONLY, p1, p2, p3, p4); this->addFace(3, VERTEX_ONLY, p4, p1, 2*detail); this->addFace(3, VERTEX_ONLY, p2, p3, 2*detail+1); } // caps this->addFace(4, VERTEX_ONLY, 2*detail-2, 2*detail-1, 1, 0); this->addFace(3, VERTEX_ONLY, 0, 2*detail-2, 2*detail); this->addFace(3, VERTEX_ONLY, 2*detail-1, 1, 2*detail+1); } /** * creates a cone inside of this Model * @param size The size of the cone * @param detail the Detail-level of this cone */ void PrimitiveModel::coneModel(float size, unsigned int detail) { this->addVertex(0,-size,0); this->addVertex(0,size,0); if (detail <= 0) detail = 1; float df = (float)detail; // defining the Vertices for (float i = 0; i < df; i+=1.0) { float vi = i/df *2.0*PI; this->addVertex(size* sin(vi), -size, size* cos(vi)); } //defining Faces for (unsigned int i = 0; i < detail; i++) { unsigned int v1, v2; v1 = i+2; if (i+1 == detail) v2 = 2; else v2 = i+3; this->addFace(3, VERTEX_ONLY, 0, v1, v2); this->addFace(3, VERTEX_ONLY, 1, v1, v2); } } /** * creates a Plane inside of this Model * @param size The size of this plane * @param detail the Detail-level of this plane. */ void PrimitiveModel::planeModel(float size, unsigned int detail) { //defining vertices for (unsigned int i = 0; i < detail; i++) for (unsigned int j = 0; j < detail; j++) { this->addVertex(((float)i/(float)(detail-1) -.5)*size, 0, ((float)j/(float)(detail-1) -.5)*size); this->addVertexTexture((float)i/(float)(detail-1), (float)j/(float)(detail-1)); } //defining Faces int v1, v2, v3, v4; for (unsigned int i = 0; i < detail-1; i++) for (unsigned int j = 0; j < detail-1; j++) { v1 = i*detail + j; v2 = (i+1)*detail + j; v3 = (i+1)*detail + (j+1); v4 = i*detail + (j+1); this->addFace(4, VERTEX_TEXCOORD, v1, v1, v2, v2, v3, v3, v4, v4); } }