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); } }
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; }