/* 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_ENTITY #include "terrain_entity.h" #include "terrain/terrain.h" #include "util/loading/load_param.h" #include "util/loading/factory.h" #include "spatial_separation.h" #include "util/loading/resource_manager.h" #include "model.h" #include "network_game_manager.h" #include "vector.h" #include "material.h" #include "glincl.h" #include "state.h" using namespace std; CREATE_FACTORY( TerrainEntity, CL_TERRAIN ); /** * standard constructor */ TerrainEntity::TerrainEntity (const TiXmlElement* root) { this->init(); if( root != NULL) this->loadParams(root); terrain->build( ); } /** * Constructor for loading a TerrainEntity out of a file * @param fileName The file to load data from. this either loads out of an OBJ-file, or loads a heightmap if no .obj-extension is found. */ TerrainEntity::TerrainEntity(const std::string& fileName ) { this->init(); if (fileName.rfind(".obj" ) != -1 || fileName.rfind(".OBJ") != -1 ) { this->loadModel(fileName); } else { // load the hightMap here. } } /** * a Constructor for the Debug-Worlds */ TerrainEntity::TerrainEntity(DebugTerrainEntity debugTerrainEntity) { this->init(); this->buildDebugTerrainEntity(debugTerrainEntity); } /** * standard deconstructor */ TerrainEntity::~TerrainEntity () { if (objectList) glDeleteLists(this->objectList, 1); if (this->vegetation) { ResourceManager::getInstance()->unload( this->vegetation ); } if( this->terrain ) delete terrain; } void TerrainEntity::init() { this->setClassID( CL_TERRAIN, "TerrainEntity"); this->toList(OM_ENVIRON); this->toReflectionList(); this->objectList = 0; this->vegetation = NULL; this->terrain = new Terrain(); //this->heightMapMaterial = new Material(); } void TerrainEntity::loadParams(const TiXmlElement* root) { WorldEntity::loadParams( root ); LoadParam(root, "scale", this, TerrainEntity, setScale) .describe("The scale in x,y,z direction"); LoadParam( root, "light_map", this, TerrainEntity, loadLightmap ) .describe("The name of the lightmap."); LoadParam( root, "elevation_map", this, TerrainEntity, loadElevationmap ) .describe( "The name of the elevation map. Must be an 8bit image" ); ResourceManager *manager = ResourceManager::getInstance(); TiXmlElement * layer = (TiXmlElement*)root->FirstChild( "material_layer" ); while ( layer ) { LayerInfo *info = new LayerInfo(); TiXmlElement *detail = (TiXmlElement*)layer->FirstChild( "detail_map" ); if ( detail ) { string detailmap( detail->Attribute( "file" ) ); info->detail = (Texture*)manager->load( detailmap, IMAGE, RP_GAME, (int)GL_TEXTURE_2D ); if ( !info->detail ) { PRINTF(0)( "%s not found\n", detailmap.c_str() ); } else PRINTF(0)( "loaded %s\n", detailmap.c_str() ); TiXmlElement *repeat = (TiXmlElement*)detail->FirstChild( "repeat" ); if ( repeat ) { repeat->QueryFloatAttribute( "x", &info->repeatX ); repeat->QueryFloatAttribute( "z", &info->repeatZ ); } } else { PRINTF(0)( "Please specify a detail-map" ); } TiXmlElement *alpha = (TiXmlElement*)layer->FirstChild( "alpha" ); if ( alpha ) { if ( !alpha->Attribute( "full" ) ) { string alphamap( alpha->Attribute( "file" ) ); info->alpha = (Texture*)manager->load( alphamap, IMAGE, RP_GAME, (int)GL_TEXTURE_2D ); if ( !info->alpha ) PRINTF(0)( "%s not found\n", alphamap.c_str() ); else PRINTF(0)( "loaded %s\n", alphamap.c_str() ); } } terrain->addMaterialLayer( info ); layer = (TiXmlElement*)layer->NextSibling( "material_layer" ); } } void TerrainEntity::setScale(float x, float y, float z) { terrain->setScale( Vector( x, y, z ) ); } void TerrainEntity::loadElevationmap( const std::string& _eleFile ) { terrain->setHeightmap( _eleFile ); } void TerrainEntity::loadLightmap( const std::string& _lightFile ) { ResourceManager *manager = ResourceManager::getInstance(); Texture *lightmap = (Texture*)manager->load( _lightFile, IMAGE, RP_GAME, (int)GL_TEXTURE_2D ); if ( lightmap ) terrain->setLightmap( lightmap ); else { PRINTF(0)("no lightmap %s\n", _lightFile.c_str() ); } } void TerrainEntity::loadVegetation(const std::string& vegetationFile) { PRINTF(4)("loadVegetation: %s\n", vegetationFile.c_str()); if (this->vegetation) ResourceManager::getInstance()->unload(this->vegetation, RP_LEVEL); if (!vegetationFile.empty()) { PRINTF(4)("fetching %s\n", vegetationFile.c_str()); this->vegetation = dynamic_cast(ResourceManager::getInstance()->load(vegetationFile, OBJ, RP_CAMPAIGN)); } else this->vegetation = NULL; } void TerrainEntity::tick( float _dt ) { if ( terrain ) terrain->tick( _dt ); } void TerrainEntity::draw () const { glMatrixMode( GL_MODELVIEW ); glPushMatrix(); glTranslatef( this->getAbsCoor().x, this->getAbsCoor().y, this->getAbsCoor().z ); Vector cam = State::getCameraNode()->getAbsCoor(); if ( this->terrain ) { terrain->setCameraPosition( cam ); terrain->draw( ); } glPopMatrix(); } void TerrainEntity::buildDebugTerrainEntity(DebugTerrainEntity debugTerrainEntity) { terrain->build( ); /* // if the TerrainEntity is the TerrainEntity of Dave if (debugTerrainEntity == TERRAINENTITY_DAVE) { objectList = glGenLists(1); glNewList (objectList, GL_COMPILE); glColor3f(1.0,0,0); int sizeX = 100; int sizeZ = 80; float length = 1000; float width = 200; float widthX = float (length /sizeX); float widthZ = float (width /sizeZ); float height [sizeX][sizeZ]; Vector normal_vectors[sizeX][sizeZ]; for ( int i = 0; imodel = (OBJModel*) new Model(); this->model->setName("CUBE"); this->model->addVertex (-0.5, -0.5, 0.5); this->model->addVertex (0.5, -0.5, 0.5); this->model->addVertex (-0.5, 0.5, 0.5); this->model->addVertex (0.5, 0.5, 0.5); this->model->addVertex (-0.5, 0.5, -0.5); this->model->addVertex (0.5, 0.5, -0.5); this->model->addVertex (-0.5, -0.5, -0.5); this->model->addVertex (0.5, -0.5, -0.5); this->model->addVertexTexture (0.0, 0.0); this->model->addVertexTexture (1.0, 0.0); this->model->addVertexTexture (0.0, 1.0); this->model->addVertexTexture (1.0, 1.0); this->model->addVertexTexture (0.0, 2.0); this->model->addVertexTexture (1.0, 2.0); this->model->addVertexTexture (0.0, 3.0); this->model->addVertexTexture (1.0, 3.0); this->model->addVertexTexture (0.0, 4.0); this->model->addVertexTexture (1.0, 4.0); this->model->addVertexTexture (2.0, 0.0); this->model->addVertexTexture (2.0, 1.0); this->model->addVertexTexture (-1.0, 0.0); this->model->addVertexTexture (-1.0, 1.0); this->model->finalize(); */ } } void TerrainEntity::getAltitude( Vector& _position, Vector& _normal ) { Vector altitude( _position.x-getAbsCoor().x, 0.0f, _position.z-getAbsCoor().z ), normal( 0.0f, 0.0f, 0.0f ); if ( terrain ) terrain->getAltitude( altitude, normal ); _position.y = altitude.y+getAbsCoor().y; _normal.z = normal.z; _normal.y = normal.y; _normal.z = normal.z; } float TerrainEntity::getHeight( float x, float z ) { Vector altitude( x-getAbsCoor().x, 0.0f, z-getAbsCoor().z ), normal( 0.0f, 0.0f, 0.0f ); if ( terrain ) terrain->getAltitude( altitude, normal ); return altitude.y+getAbsCoor().y; }