Vegetation* TerrainTile::getVegetationAt(vector3df pos) { for (int i=0 ; i<(int)vegetationVector.size() ; i++) { Vegetation* temp = (Vegetation*)vegetationVector[i]; if(temp->getPosition().getDistanceFrom(pos) < vegetationRange ) return temp; } return 0; }
void Client::receiveInitialVegetationSpawning(const std::string& packetContents) { PacketBuf::InitialVegetationSpawn message; Packet::deserialize(packetContents, &message); assert(message.x_size() == message.y_size()); for (int i = 0; i < message.x_size(); ++i) { Vegetation* tree = new Vegetation("tree1", SpriteSheetRenderer::SpriteSheetType::Entity); tree->setPosition(message.x(i), message.y(i)); m_world->m_treesSpatialHash->insert(tree); m_world->m_spriteSheetRenderer->registerSprite(tree); } }
void TerrainTile::transformMeshByVertices(vector<TerrainData> list, bool norecalc) { core::stringw title=L"Generating terrain"; GUIManager::getInstance()->setTextLoader(title); App::getInstance()->getDevice()->getGUIEnvironment()->drawAll(); //Terrain first for (u32 a=0; a<list.size(); a++) { mb_vertices[list[a].id].Pos.Y = list[a].value; } App::getInstance()->quickUpdate(); int counter=0; //Then plant the trees title=L"Generating trees"; GUIManager::getInstance()->setTextLoader(title); App::getInstance()->getDevice()->getGUIEnvironment()->drawAll(); for (u32 a=0; a<list.size(); a++) { if (list[a].tree && list[a].type>=0) { // Now create a new tree with the informations Vegetation* v = new Vegetation(list[a].type); if (v) { counter++; v->setPosition(list[a].pos); v->setScale(list[a].sca); v->setRotation(list[a].rot); // Update the infos vegetationVector.push_back(v); } } } if (!norecalc) recalculate(); else { needrecalc=true; recalculate(true); } }
TerrainTile::~TerrainTile() { for (int i=0 ; i<(int)vegetationVector.size() ; i++) { Vegetation* temp = (Vegetation*)vegetationVector[i]; if (temp->getNode()) temp->getNode()->remove(); //if (temp) // delete temp; } vegetationVector.clear(); if (selector) selector->drop(); if (node) { node->remove(); } }
//Reposition the vegetation (trees) to touch the ground void TerrainTile::resetVegetationHeight() { for (int i=0 ; i<(int)vegetationVector.size() ; i++) { Vegetation* temp = (Vegetation*)vegetationVector[i]; f32 newpos = this->getHeightAt(temp->getPosition(),4000.0f); if (newpos<-200.0f) //Remove the tree if it's too low (underwater) { temp->getNode()->remove(); vegetationVector.erase(vegetationVector.begin()+i); } else temp->setPosition(vector3df(temp->getPosition().X,newpos-3.0f,temp->getPosition().Z)); //little offset of 3 units. } }
void TerrainTile::saveToXML(TiXmlElement* parentElement) { // Save the terrain land f32 x = 0; f32 z = 0; x = node->getPosition().X; z = node->getPosition().Z; TiXmlElement* segmentXML = new TiXmlElement("terrainSegment"); segmentXML->SetDoubleAttribute("x",x); segmentXML->SetDoubleAttribute("z",z); core::stringc file=TerrainManager::getInstance()->filename; segmentXML->SetAttribute("mesh",file.c_str()); //Saving the vegetation information with the tile if (vegetationVector.size()>0) { for (int i=0 ; i<(int)vegetationVector.size() ; i++) { TiXmlElement* vertexXML = new TiXmlElement("tree"); Vegetation * tree = (Vegetation*)vegetationVector[i]; if (tree!=NULL) { vector3df treepos=tree->getPosition(); vertexXML->SetAttribute("v",tree->getType()); vertexXML->SetDoubleAttribute("tx",tree->getPosition().X); vertexXML->SetDoubleAttribute("ty",tree->getPosition().Y); vertexXML->SetDoubleAttribute("tz",tree->getPosition().Z); vertexXML->SetDoubleAttribute("tr",tree->getNode()->getRotation().Y); vertexXML->SetDoubleAttribute("ts",tree->getNode()->getScale().X); } segmentXML->LinkEndChild(vertexXML); } } parentElement->LinkEndChild(segmentXML); }
void PetPM::tick (const Time&, const Weather& weather, const double Rn, const Vegetation& crops, const Surface& surface, const Geometry& geo, const Soil& soil, const SoilHeat& soil_heat, const SoilWater& soil_water, Treelog& msg) { // Weather. const double Temp = weather.air_temperature (); const double VaporPressure = weather.vapor_pressure (); const double U2 = weather.wind (); const double AtmPressure = weather.air_pressure (); const double Cloudiness = weather.cloudiness (); // Ground heat flux. const double G = soil_heat.top_flux (geo, soil, soil_water); const double LAI = crops.LAI (); if (LAI > 0.0) { const double CropHeight = 0.01 * crops.height (); //cm -> m const double ScreenHeight = weather.screen_height (); // Dry. reference_evapotranspiration_dry = FAO::PenmanMonteith (CropHeight, ScreenHeight, LAI, crops.rs_min (), Rn, G, Temp, VaporPressure, U2, AtmPressure) * 3600; potential_evapotranspiration_dry = std::max (0.0, reference_evapotranspiration_dry); // Wet. reference_evapotranspiration_wet = FAO::PenmanMonteith (CropHeight, ScreenHeight, LAI, 0.0, Rn, G, Temp, VaporPressure, U2, AtmPressure) * 3600; potential_evapotranspiration_wet = std::max (0.0, reference_evapotranspiration_wet); } else { const double Si = weather.global_radiation (); // Use reference crop as fallback for bare soil. const double ref_albedo = 0.23; net_radiation->tick (Cloudiness, Temp, VaporPressure, Si, ref_albedo, msg); const double ref_Rn = net_radiation->net_radiation (); reference_evapotranspiration_dry = FAO::RefPenmanMonteith (ref_Rn, G, Temp, VaporPressure, U2, AtmPressure) * 3600; potential_evapotranspiration_dry = reference_to_potential_dry (crops, surface, reference_evapotranspiration_dry); reference_evapotranspiration_wet = FAO::RefPenmanMonteithWet (ref_Rn, G, Temp, VaporPressure, U2, AtmPressure, rb) * 3600; potential_evapotranspiration_wet = reference_to_potential_wet (crops, surface, reference_evapotranspiration_wet); } }
Vegetation* TerrainTile::paintVegetation(vector3df clickPos, bool erase) { //Do a prior check to see if there is a least one tree active in the list of active objects vector<bool> enabled=VegetationSeed::getInstance()->getEnabled(); vector<int> newlist; for(int i = 0; i<(int)enabled.size(); i++) { if (enabled[i]==true) newlist.push_back(i); //New list will contain the list of the enabled items } if (newlist.size()==0) return NULL; IMeshBuffer* meshBuffer = ((IMeshSceneNode*)node)->getMesh()->getMeshBuffer(0); S3DVertex* mb_vertices = (S3DVertex*) meshBuffer->getVertices(); u16* mb_indices = meshBuffer->getIndices(); Vegetation* returnvalue = NULL; for (unsigned int j = 0; j < meshBuffer->getVertexCount(); j += 1) { if(erase) { vector3df realPos = vector3df (0.0f,0.0f,0.0f); //Should be able to place a tree anywhere on a custom model if (!custom) realPos = mb_vertices[j].Pos*(scale/nodescale) + node->getPosition(); else realPos = clickPos; clickPos.Y = realPos.Y; if(realPos.getDistanceFrom(clickPos) < vegetationRange/2 && getVegetationAt(vector3df(realPos.X,realPos.Y,realPos.Z))) { Vegetation* toRemove = getVegetationAt(vector3df(realPos.X,realPos.Y,realPos.Z)); returnvalue = toRemove; return returnvalue; // Done outside the function (caller will do the removal) } } else { vector3df realPos = vector3df (0.0f,0.0f,0.0f); //Should be able to place a tree anywhere on a custom model if (!custom) realPos = mb_vertices[j].Pos*(scale/nodescale) + node->getPosition(); else realPos = clickPos; clickPos.Y = realPos.Y; if(realPos.getDistanceFrom(clickPos) < (vegetationRange/2) && !getVegetationAt(vector3df(realPos.X,realPos.Y,realPos.Z))) { Vegetation* v = new Vegetation(); //v->setPosition(vector3df(realPos.X + (rand()%5)*0.1f - 0.25f,realPos.Y/(scale/nodescale),realPos.Z + (rand()%5)*0.1f - 0.25f)); //v->setPosition(vector3df(realPos.X + (rand()%5)*scale/100,realPos.Y,realPos.Z + (rand()%5)*scale/100)); v->setPosition(vector3df(realPos.X,realPos.Y,realPos.Z)); f32 treesize = (f32)(rand() % 50 + 25); f32 treerot = (f32)(rand() % 1 + 359); v->setScale(vector3df(treesize,treesize,treesize)); v->setRotation(vector3df(0,treerot,0)); #ifdef DEBUG printf("Attempting to place a tree with this size: %f\n",treesize); #endif vegetationVector.push_back(v); returnvalue = v; return returnvalue; #ifdef APP_DEBUG cout << "DEBUG : TERRAIN TILE : VEGETATION CREATED: " << realPos.X << "," << realPos.Y << "," << realPos.Z << " TOTAL:" << vegetationVector.size() << endl; #endif } } } return returnvalue; }
bool TerrainTile::loadFromXML(TiXmlElement* parentElement) { s32 id = 0; f32 y = 0.0f; vector<TerrainData> vertices; vector3df pos=vector3df(0,0,0); f32 rota = 0; f32 scal = 0; f32 tsize = 0; int ttype = -1; bool atree=false; u32 counter=0; u32 counter1=0; u32 treecounter=0; if (!TerrainManager::getInstance()->isParametric()) //Old format for tiles { TiXmlNode* vertex = parentElement->FirstChild( "vertex" ); //printf("A non-parametric project is loaded, loading tile vertices...\n"); while( vertex != NULL ) { if (!custom) { id = atoi(vertex->ToElement()->Attribute("id")); y = (f32)atof(vertex->ToElement()->Attribute("y")); this->transformMeshByVertex(id,y,false,true); core::stringw title=L"Getting terrain vertices:"; title.append(stringw(counter)); title.append(L" loaded trees:"); title.append(stringw(treecounter)); GUIManager::getInstance()->setTextLoader(title); App::getInstance()->getDevice()->getGUIEnvironment()->drawAll(); counter1++; } stringc sttype = vertex->ToElement()->Attribute("v"); if (sttype.size()>0) { atree=true; ttype=atoi(sttype.c_str()); stringc stposx = vertex->ToElement()->Attribute("tx"); if (stposx.size()>0) { treecounter++; pos.X = (f32)atof(stposx.c_str()); pos.Y = (f32)atof(vertex->ToElement()->Attribute("ty")); pos.Z = (f32)atof(vertex->ToElement()->Attribute("tz")); stringc tsizes = vertex->ToElement()->Attribute("ts"); stringc ttr = vertex->ToElement()->Attribute("ts"); if (tsizes.size()>0) tsize=(f32)atof(vertex->ToElement()->Attribute("ts")); if (ttr.size()>0) rota=(f32)atof(vertex->ToElement()->Attribute("tr")); if (!TerrainManager::getInstance()->isParametric()) { printf("Terrain is NOT parametric\n"); // Now create a new tree with the informations Vegetation* v = new Vegetation(ttype); v->setPosition(pos); if (tsize==0.0f) //Old format, try to compensate with "default values" { f32 treesize = (f32)(rand() % 100 + 50)/100; treesize*= 0.3f; v->setScale(vector3df(treesize*(scale/7.5f),treesize*(scale/7.5f),treesize*(scale/7.5f))); v->setRotation(vector3df(0,0,0)); } else { v->setScale(vector3df(tsize,tsize,tsize)); v->setRotation(vector3df(0,rota,0)); } // Update the infos vegetationVector.push_back(v); } } } vertex = parentElement->IterateChildren( "vertex", vertex ); } } else { printf("A parametric project is loaded, loading tree informations...\n"); TiXmlNode* tree = parentElement->FirstChild( "tree" ); while( tree != NULL ) { core::stringw title=L"Getting terrain vertices:"; title.append(stringw(counter)); title.append(L" loaded trees:"); title.append(stringw(treecounter)); GUIManager::getInstance()->setTextLoader(title); App::getInstance()->getDevice()->getGUIEnvironment()->drawAll(); counter++; //Put back default values atree=false; ttype=-1; stringc sttype = tree->ToElement()->Attribute("v"); if (sttype.size()>0) { atree=true; ttype=atoi(sttype.c_str()); stringc stposx = tree->ToElement()->Attribute("tx"); if (stposx.size()>0) { treecounter++; pos.X = (f32)atof(stposx.c_str()); pos.Y = (f32)atof(tree->ToElement()->Attribute("ty")); pos.Z = (f32)atof(tree->ToElement()->Attribute("tz")); stringc tsizes = tree->ToElement()->Attribute("ts"); stringc ttr = tree->ToElement()->Attribute("ts"); if (tsizes.size()>0) tsize=(f32)atof(tree->ToElement()->Attribute("ts")); if (ttr.size()>0) rota=(f32)atof(tree->ToElement()->Attribute("tr")); if (TerrainManager::getInstance()->isParametric()) { printf("Terrain is NOT parametric\n"); // Now create a new tree with the informations Vegetation* v = new Vegetation(ttype); v->setPosition(pos); if (tsize==0.0f) //Old format, try to compensate with "default values" { f32 treesize = (f32)(rand() % 100 + 50)/100; treesize*= 0.3f; v->setScale(vector3df(treesize*(scale/7.5f),treesize*(scale/7.5f),treesize*(scale/7.5f))); v->setRotation(vector3df(0,0,0)); } else { v->setScale(vector3df(tsize,tsize,tsize)); v->setRotation(vector3df(0,rota,0)); } // Update the infos vegetationVector.push_back(v); } } } if (!custom)// This slow down when loading and should be optimized. { if (TerrainManager::getInstance()->isParametric()) { TerrainData data; data.id=id; data.value=y; data.pos=pos; data.type=ttype; data.tree=atree; data.rot=vector3df(0,rota,0); data.sca=vector3df(tsize,tsize,tsize); vertices.push_back(data); } else this->transformMeshByVertex(id,y,false,true); } tree = parentElement->IterateChildren( "tree", tree ); } } //Temporary solution so we can edit the tiles (editing was only permitted on non-custom tiles) custom=false; needrecalc=true; //this->recalculate(); return true; }