/* 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: Patrick Boenzli co-programmer: Christian Meyer */ #include #include "world_entity.h" #include "list.h" #include "vector.h" #include "obb_tree.h" using namespace std; /** * Loads the WordEntity-specific Part of any derived Class */ WorldEntity::WorldEntity(const TiXmlElement* root) { this->setClassID(CL_WORLD_ENTITY, "WorldEntity"); this->model = NULL; this->obbTree = NULL; if (root) this->loadParams(root); this->setVisibiliy(true); } /** * standard destructor */ WorldEntity::~WorldEntity () { // if( collisioncluster != NULL) delete collisioncluster; if (this->model) ResourceManager::getInstance()->unload(this->model); if( this->obbTree) delete this->obbTree; } void WorldEntity::loadParams(const TiXmlElement* root) { static_cast(this)->loadParams(root); // Model Loading LoadParam(root, "model", this, &WorldEntity::loadModel) .describe("the fileName of the model, that should be loaded onto this world-entity. (must be relative to the data-dir)") ; } /** * loads a Model onto a WorldEntity * @param fileName the name of the model to load * @param scaling the Scaling of the model */ void WorldEntity::loadModelWithScale(const char* fileName, float scaling) { if (this->model) ResourceManager::getInstance()->unload(this->model, RP_LEVEL); if (fileName != NULL) { PRINTF(4)("fetching %s\n", fileName); if (scaling == 1.0) this->model = (Model*)ResourceManager::getInstance()->load(fileName, OBJ, RP_CAMPAIGN); else this->model = (Model*)ResourceManager::getInstance()->load(fileName, OBJ, RP_CAMPAIGN, &scaling); this->buildObbTree(4); } else this->model = NULL; } /** * builds the obb-tree * @param depth the depth to calculate */ bool WorldEntity::buildObbTree(unsigned int depth) { if (this->obbTree) delete this->obbTree; if (this->model) { PRINTF(4)("creating obb tree\n"); this->obbTree = new OBBTree(depth, (sVec3D*)this->model->getVertexArray(), this->model->getVertexCount()); return true; } else { PRINTF(2)("could not create obb-tree, because no model was loaded yet\n"); this->obbTree = NULL; return false; } } /** * sets the character attributes of a worldentity * @param character attributes * * these attributes don't have to be set, only use them, if you need them */ void WorldEntity::setCharacterAttributes(CharacterAttributes* charAttr) {} /** * gets the Character attributes of this worldentity * @returns character attributes */ CharacterAttributes* WorldEntity::getCharacterAttributes() {} /** * this function is called, when two entities collide * @param entity: the world entity with whom it collides * * Implement behaviour like damage application or other miscellaneous collision stuff in this function */ void WorldEntity::collidesWith(WorldEntity* entity, const Vector& location) { PRINTF(3)("collision %s vs %s @ (%f,%f,%f)\n", this->getClassName(), entity->getClassName(), location.x, location.y, location.z); } /** * this function is called, when the ship is hit by a waepon * @param weapon: the laser/rocket/shoot that hits. * @param loc: place where it is hit * * calculate the damage depending */ void WorldEntity::hit(WorldEntity* weapon, Vector* loc) {} /** * this is called immediately after the Entity has been constructed and initialized * * Put any initialisation code that requires knowledge of location (placement if the Entity is free) and owner of the entity here. * DO NOT place such code in the constructor, those variables are set AFTER the entity is constucted. */ void WorldEntity::postSpawn () { } /** * this method is called by the world if the WorldEntity leaves valid gamespace * * For free entities this means it left the Track boundaries. With bound entities it means its Location adresses a * place that is not in the world anymore. In both cases you might have to take extreme measures (a.k.a. call destroy). */ void WorldEntity::leftWorld () { } /** * this method is called every frame * @param time: the time in seconds that has passed since the last tick * * Handle all stuff that should update with time inside this method (movement, animation, etc.) */ void WorldEntity::tick(float time) { } /** * the entity is drawn onto the screen with this function * * This is a central function of an entity: call it to let the entity painted to the screen. * Just override this function with whatever you want to be drawn. */ void WorldEntity::draw() { glMatrixMode(GL_MODELVIEW); glPushMatrix(); float matrix[4][4]; /* translate */ glTranslatef (this->getAbsCoor ().x, this->getAbsCoor ().y, this->getAbsCoor ().z); /* rotate */ this->getAbsDir ().matrix (matrix); glMultMatrixf((float*)matrix); if (this->model) this->model->draw(); glPopMatrix(); } void WorldEntity::drawBVTree(int depth, int drawMode) { glMatrixMode(GL_MODELVIEW); glPushMatrix(); /* translate */ glTranslatef (this->getAbsCoor ().x, this->getAbsCoor ().y, this->getAbsCoor ().z); /* rotate */ Vector tmpRot = this->getAbsDir().getSpacialAxis(); glRotatef (this->getAbsDir().getSpacialAxisAngle(), tmpRot.x, tmpRot.y, tmpRot.z ); if (this->obbTree) this->obbTree->drawBV(depth, drawMode); glPopMatrix(); }