/* 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 #include "vector.h" #include "debug.h" using namespace std; /** \brief 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 CUBE: this->cubeModel(); break; case SPHERE: this->sphereModel(size, detail); break; case CYLINDER: this->cylinderModel(); break; case CONE: this->coneModel(size, detail); break; case PLANE: this->planeModel(size, detail); break; } this->finalize(); } /** \brief standard deconstructor */ PrimitiveModel::~PrimitiveModel () { // delete what has to be deleted here } /** \brief 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) { int vertexCount = 0; if (detail <= 0) detail = 1; size /= 2; // 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->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); vertexCount++; } } this->addVertex(0, -size, 0); this->addVertex(0, size, 0); // defining the binding Faces. unsigned int v1, v2, v3, v4; for (int i = 0; i <= detail * 2 -1; i++) { for (int j = 0; j <= detail; j++) { v1 = i*detail + j; v4 = i*detail + (j+1); if (i == detail*2 -1) { v2 = j; v3 = j+1; } else { v2 = (i+1)*detail + j; v3 = (i+1)*detail + (j+1); } if (j == 0) { v1 = vertexCount+1; this->addFace(3, VERTEX_TEXCOORD, v1, v1, v3, v3, v4, v4); } else if (j == detail) { v3 = vertexCount+2; this->addFace(3, VERTEX_TEXCOORD, v1, v1, v2, v2, v3, v3); } else this->addFace(4, VERTEX_TEXCOORD, v1, v1, v2, v2, v3, v3, v4, v4); } } } /** \brief Creates a Cylinder. */ void PrimitiveModel::cylinderModel(float size, unsigned int detail) { // check if devision by zero if (detail <= 3) detail = 3; 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 (int i = 0; i < detail-1; i++) { int p1, p2, p3, p4; p1 = 2*i+1; p2 = 2*i+2; p3 = 2*i+4; p4 = 2*i+3; // something is wrong here this->addFace(4, VERTEX_ONLY, p1, p2, p3, p4); this->addFace(3, VERTEX_ONLY, p4, p1, 2*detail+1); this->addFace(3, VERTEX_ONLY, p2, p3, 2*detail+2); } // caps this->addFace(4, VERTEX_ONLY, 2*detail-1, 2*detail, 2, 1); this->addFace(3, VERTEX_ONLY, 1, 2*detail-1, 2*detail+1); this->addFace(3, VERTEX_ONLY, 2*detail, 2, 2*detail+2); } /** \brief 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 (int i = 0; i < detail; i++) { unsigned int v1, v2; v1 = i+3; if (i == detail -1) v2 = 3; else v2 = i+4; this->addFace(3, VERTEX_ONLY, 1, v1, v2); this->addFace(3, VERTEX_ONLY, 2, v1, v2); } } /** \brief 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 (int i = 0; i < detail; i++) for (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 unsigned int v1, v2, v3, v4; for (int i = 0; i < detail-1; i++) for (int j = 1; j < detail; 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); } }