/* 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: ... 2005-07-06: (Patrick) added new function buildTriangleList() */ #define DEBUG_SPECIAL_MODULE DEBUG_MODULE_IMPORTER #include "static_model.h" #include "debug.h" #include ///////////// /// MODEL /// ///////////// ObjectListDefinition(StaticModel); /** * @brief Creates a 3D-Model. * * assigns it a Name and a Type */ StaticModel::StaticModel(const std::string& modelName) : data(new StaticModelData(modelName)) { this->registerObject(this, StaticModel::_objectList); PRINTF(4)("new 3D-Model is being created\n"); this->setName(modelName); } StaticModel::StaticModel(const StaticModel& staticModel) : data(staticModel.data) { this->registerObject(this, StaticModel::_objectList); this->setName(staticModel.getName()); this->updateBase(); } /** * @brief deletes an Model. * * Looks if any from model allocated space is still in use, and if so deleted it. */ StaticModel::~StaticModel() { PRINTF(4)("Deleting Model "); // mark this stuff as beeing deleted this->pModelInfo.pVertices = NULL; this->pModelInfo.pNormals = NULL; this->pModelInfo.pTexCoor = NULL; this->pModelInfo.pTriangles = NULL; } StaticModel& StaticModel::operator=(const StaticModel& model) { this->data = model.data; this->updateBase(); return *this; }; /** * @brief Finalizes an Object. This can be done outside of the Class. */ void StaticModel::finalize() { // this->extractMountPoints(); data->finalize(); this->updateBase(); } void StaticModel::acquireData(const StaticModelData::Pointer& data) { this->data = data; this->updateBase(); } /** * extract the mount points from this file: looking at each group and checking if the group realy is a mountpoint marker * if so get place and orientation */ void StaticModel::extractMountPoints() { // go through all groups and check if they are mounts std::vector::iterator groupIt = this->data->getGroups().begin(); for( ; groupIt != this->data->getGroups().end();) { //PRINTF(0)("Found a MountPoint: %s\n", groupName.c_str()); // get the name of this group and check if it's a mout point identifier std::string groupName = (*groupIt).name; std::vector vertices; // check if the name has a "MP" prefix or else it won't work if( groupName.find("MP.", 0) == std::string::npos){ groupIt++; continue; } PRINTF(5)("Found a MountPoint: %s\n", groupName.c_str()); StaticModelData::Face triangle[3]; // now check if it is a mount point identifier if( (*groupIt)._faces.size() != 11) { PRINTF(4)("the face count of %s is wrong, perhaps you missnamed this object or used the wrong mount point object (got %i faces)\n", groupName.c_str(), (*groupIt)._faces.size()); groupIt++; continue; } // now iterate through all faces std::vector::const_iterator faceIt = (*groupIt)._faces.begin(); for( int i = 0; faceIt < (*groupIt)._faces.end(); faceIt++) { if( (*faceIt)._elements.size() == 3) { triangle[i++] = (*faceIt); } } Vector center; Vector xAxis; Vector yAxis; Vector zAxis; // now process all points for( int i = 0; i < 3; i++) { // convert the float vertices to vectors Vector a( this->data->getVertices()[triangle[i]._elements[0].vertexNumber * 3], this->data->getVertices()[triangle[i]._elements[0].vertexNumber * 3 + 1], this->data->getVertices()[triangle[i]._elements[0].vertexNumber * 3 + 2]); Vector b( this->data->getVertices()[triangle[i]._elements[1].vertexNumber * 3], this->data->getVertices()[triangle[i]._elements[1].vertexNumber * 3 + 1], this->data->getVertices()[triangle[i]._elements[1].vertexNumber * 3 + 2]); Vector c( this->data->getVertices()[triangle[i]._elements[2].vertexNumber * 3], this->data->getVertices()[triangle[i]._elements[2].vertexNumber * 3 + 1], this->data->getVertices()[triangle[i]._elements[2].vertexNumber * 3 + 2]); Vector ab = a - b; Vector ac = a - c; Vector bc = b - c; Vector axis1; Vector axis2; // now find the center point (the one with the 90degree angle) if( fabs(ab.dot( ac)) < 0.0001) { center = a; axis1 = b - a; axis2 = c - a; } else if( fabs(ab.dot(bc)) < 0.0001) { center = b; axis1 = a - b; axis2 = c - b; } else if( fabs(bc.dot(ac)) < 0.0001) { center = c; axis1 = b - c; axis2 = a - c; } // get the longest axis (without defining a max() funciton :D if( xAxis.len() < axis1.len() ) xAxis = axis1; if( xAxis.len() < axis2.len()) xAxis = axis2; // find the 2nd longest axis to be y-axis if( xAxis.len() > axis1.len() && yAxis.len() < axis1.len()) yAxis = axis1; if( xAxis.len() > axis2.len() && yAxis.len() < axis2.len()) yAxis = axis2; // needed... no explanation here.. if( zAxis.len() == 0.) zAxis = yAxis; // find the shortest axis to be z-axis if( yAxis.len() > axis1.len() ) zAxis = axis1; if( yAxis.len() > axis2.len() ) zAxis = axis2; } this->addMountPoint( zAxis, yAxis, center, groupName); // remove the group from the model list (mount points do not need to be drawn) // remoing item iterates greoupIt! this->data->getGroups().erase(groupIt); } } /** * @brief adds a new Face * @param faceElemCount the number of Vertices to add to the Face. * @param type The information Passed with each Vertex */ bool StaticModel::addFace(int faceElemCount, VERTEX_FORMAT type, ...) { va_list itemlist; va_start (itemlist, type); bool retVal = this->data->addFace(faceElemCount, type, itemlist); va_end(itemlist); return retVal; } void StaticModel::updateBase() { // write out the modelInfo data used for the collision detection! this->pModelInfo.pVertices = &this->data->getVertices()[0]; this->pModelInfo.numVertices = this->data->getVertices().size(); this->pModelInfo.pNormals = &this->data->getNormals()[0]; this->pModelInfo.numNormals = this->data->getNormals().size(); this->pModelInfo.pTexCoor = &this->data->getTexCoords()[0]; this->pModelInfo.numTexCoor = this->data->getTexCoords().size(); this->pModelInfo.pTriangles = this->data->getTrianglesExt(); this->pModelInfo.numTriangles = this->data->getTriangles().size(); } /** * Includes a default model * * This will inject a Cube, because this is the most basic model. */ void StaticModel::cubeModel() { this->addVertex (-0.5, -0.5, 0.5); this->addVertex (0.5, -0.5, 0.5); this->addVertex (-0.5, 0.5, 0.5); this->addVertex (0.5, 0.5, 0.5); this->addVertex (-0.5, 0.5, -0.5); this->addVertex (0.5, 0.5, -0.5); this->addVertex (-0.5, -0.5, -0.5); this->addVertex (0.5, -0.5, -0.5); this->addVertexTexture (0.0, 0.0); this->addVertexTexture (1.0, 0.0); this->addVertexTexture (0.0, 1.0); this->addVertexTexture (1.0, 1.0); this->addVertexTexture (0.0, 2.0); this->addVertexTexture (1.0, 2.0); this->addVertexTexture (0.0, 3.0); this->addVertexTexture (1.0, 3.0); this->addVertexTexture (0.0, 4.0); this->addVertexTexture (1.0, 4.0); this->addVertexTexture (2.0, 0.0); this->addVertexTexture (2.0, 1.0); this->addVertexTexture (-1.0, 0.0); this->addVertexTexture (-1.0, 1.0); this->addVertexNormal (0.0, 0.0, 1.0); this->addVertexNormal (0.0, 0.0, 1.0); this->addVertexNormal (0.0, 0.0, 1.0); this->addVertexNormal (0.0, 0.0, 1.0); this->addVertexNormal (0.0, 1.0, 0.0); this->addVertexNormal (0.0, 1.0, 0.0); this->addVertexNormal (0.0, 1.0, 0.0); this->addVertexNormal (0.0, 1.0, 0.0); this->addVertexNormal (0.0, 0.0, -1.0); this->addVertexNormal (0.0, 0.0, -1.0); this->addVertexNormal (0.0, 0.0, -1.0); this->addVertexNormal (0.0, 0.0, -1.0); this->addVertexNormal (0.0, -1.0, 0.0); this->addVertexNormal (0.0, -1.0, 0.0); this->addVertexNormal (0.0, -1.0, 0.0); this->addVertexNormal (0.0, -1.0, 0.0); this->addVertexNormal (1.0, 0.0, 0.0); this->addVertexNormal (1.0, 0.0, 0.0); this->addVertexNormal (1.0, 0.0, 0.0); this->addVertexNormal (1.0, 0.0, 0.0); this->addVertexNormal (-1.0, 0.0, 0.0); this->addVertexNormal (-1.0, 0.0, 0.0); this->addVertexNormal (-1.0, 0.0, 0.0); this->addVertexNormal (-1.0, 0.0, 0.0); this->addFace (4, VERTEX_TEXCOORD_NORMAL, 0,0,0, 1,1,1, 3,3,2, 2,2,3); this->addFace (4, VERTEX_TEXCOORD_NORMAL, 2,2,4, 3,3,5, 5,5,6, 4,4,7); this->addFace (4, VERTEX_TEXCOORD_NORMAL, 4,4,8, 5,5,9, 7,7,10, 6,6,11); this->addFace (4, VERTEX_TEXCOORD_NORMAL, 6,6,12, 7,7,13, 1,9,14, 0,8,15); this->addFace (4, VERTEX_TEXCOORD_NORMAL, 1,1,16, 7,10,17, 5,11,18, 3,3,19); this->addFace (4, VERTEX_TEXCOORD_NORMAL, 6,12,20, 0,0,21, 2,2,22, 4,13,23); }