/* 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() { data->finalize(); this->updateBase(); this->extractMountPoints(); } 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::const_iterator groupIt = this->data->getGroups().begin(); for( ; groupIt != this->data->getGroups().end(); groupIt++) { //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) continue; PRINTF(0)("Found a MountPoint: %s\n", groupName.c_str()); // now check if it is a mount point identifier if( (*groupIt)._faces.size() != 6) { PRINTF(1)("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()); } // now extract the direction from the length: std::vector::const_iterator faceIt = (*groupIt)._faces.begin(); for( ; faceIt < (*groupIt)._faces.end(); faceIt++) { // now go through all modelfaceelements std::vector::const_iterator faceElementIt = (*faceIt)._elements.begin(); for( ; faceElementIt < (*faceIt)._elements.end(); faceElementIt++) { int vert = (*faceElementIt).vertexNumber; vertices.push_back(Vector(this->data->getVertices()[vert*3], this->data->getVertices()[vert*3 + 1], this->data->getVertices()[vert*3 + 2])); } } // vertex with the max surrounding faces is the up-point (pyramid like object) std::vector::const_iterator it = vertices.begin(); Vector tmpPoint; int tmpCount; Vector up; int maxCount = 0; for( ; it < vertices.end(); it++) { tmpCount = 0; tmpPoint = (*it); // std::vector::const_iterator it2 = vertices.begin(); for( ; it2 < vertices.end(); it2++) if( tmpPoint == *it2) tmpCount++; // if this is the vertex with the most surrounding vertices if( tmpCount > maxCount) { up = tmpPoint; maxCount = tmpCount; } } // now get the longest side of the first face, this will be the forward vector Vector forward; Vector side1 = vertices[0] - vertices[1]; Vector side2 = vertices[1] - vertices[2]; Vector side3 = vertices[2] - vertices[3]; if( fabs(side1.len()) > fabs(side2.len()) && fabs(side1.len()) > fabs(side3.len())) forward = side1; else if( fabs(side2.len()) > fabs(side1.len()) && fabs(side2.len()) > fabs(side3.len())) forward = side2; else if( fabs(side3.len()) > fabs(side1.len()) && fabs(side3.len()) > fabs(side2.len())) forward = side3; // now get the center of the object Vector center; it = vertices.begin(); for( ; it < vertices.end(); it++) center += (*it); // scale center /= vertices.size(); PRINTF(0)("Up Point\n"); up.debug(); PRINTF(0)("Center\n"); center.debug(); PRINTF(0)("Forward\n"); forward.debug(); // now add the mount point this->addMountPoint( up, forward, center, groupName); } } /** * @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); }