void Map::generateMesh(std::string materialName) { Ogre::ManualObject* plane = new Ogre::ManualObject("plane"); plane->estimateIndexCount(m_length * m_width * 8); plane->estimateVertexCount(m_length * m_width * 8); plane->clear(); plane->begin(materialName); Ogre::Vector3 pos = Ogre::Vector3(0, 0, 0); Ogre::Quaternion quat; Ogre::Quaternion quatNext; unsigned long planeNum = 0; for (unsigned int i = 0; i < m_length; i++) { quat = m_rotationalSpline.getPoint(i); quatNext = m_rotationalSpline.getPoint(i + 1); for (int x = -100 * (m_width / (double) 2), j = 0; (unsigned) j < m_width; j++, x += 100) { int back = -100; int left = x; int right = x + 100; int down = -20 ; Ogre::Vector3 nextPos = pos + quat * Ogre::Vector3(0, 0, back); Ogre::Vector3 posMinus50 = pos + quat * Ogre::Vector3(left, 0, 0); Ogre::Vector3 posPlus50 = pos + quat * Ogre::Vector3(right, 0, 0); Ogre::Vector3 nextPosMinus50 = nextPos + quatNext * Ogre::Vector3(left, 0, 0); Ogre::Vector3 nextPosPlus50 = nextPos + quatNext * Ogre::Vector3(right, 0, 0); //TODO: fix normals? plane->position(posMinus50); plane->normal((quat * Vector3(0, 1, 0)).normalisedCopy()); plane->textureCoord(1, 1); plane->position(nextPosMinus50); plane->normal((quat * Vector3(0, 1, 0)).normalisedCopy()); plane->textureCoord(1, 0); plane->position(posPlus50); plane->normal((quat * Vector3(0, 1, 0)).normalisedCopy()); plane->textureCoord(0, 1); plane->position(nextPosPlus50); plane->normal((quat * Vector3(0, 1, 0)).normalisedCopy()); plane->textureCoord(0, 0); Ogre::Vector3 nextPosDown = nextPos + quat * Ogre::Vector3(0, down, 0); Ogre::Vector3 posMinus50Down = posMinus50 + quat * Ogre::Vector3(0, down, 0); Ogre::Vector3 posPlus50Down = posPlus50 + quat * Ogre::Vector3(0, down, 0); Ogre::Vector3 nextPosMinus50Down = nextPosMinus50 + quatNext * Ogre::Vector3(0, down, 0); Ogre::Vector3 nextPosPlus50Down = nextPosPlus50 + quatNext * Ogre::Vector3(0, down, 0); //TODO: fix normals? plane->position(posMinus50Down); plane->normal((quat * Vector3(-1, -1, 1)).normalisedCopy()); plane->textureCoord(0, 0); plane->position(nextPosMinus50Down); plane->normal((quat * Vector3(-1, -1, -1)).normalisedCopy()); plane->textureCoord(0, 1); plane->position(posPlus50Down); plane->normal((quat * Vector3(1, -1, 1)).normalisedCopy()); plane->textureCoord(1, 0); plane->position(nextPosPlus50Down); plane->normal((quat * Vector3(1, -1, -1)).normalisedCopy()); plane->textureCoord(1, 1); if (m_cubes[planeNum / (double) m_width][planeNum % m_width] != HOLE) { //if (m_cubes[planeNum / (double) m_width][planeNum % m_width] == NORMAL) //{ //top plane->triangle(0 + planeNum * 8, 1 + planeNum * 8, 2 + planeNum * 8); plane->triangle(2 + planeNum * 8, 1 + planeNum * 8, 0 + planeNum * 8); plane->triangle(1 + planeNum * 8, 3 + planeNum * 8, 2 + planeNum * 8); plane->triangle(2 + planeNum * 8, 3 + planeNum * 8, 1 + planeNum * 8); //} //bottom plane->triangle(4 + planeNum * 8, 5 + planeNum * 8, 6 + planeNum * 8); plane->triangle(6 + planeNum * 8, 5 + planeNum * 8, 4 + planeNum * 8); plane->triangle(5 + planeNum * 8, 7 + planeNum * 8, 6 + planeNum * 8); plane->triangle(6 + planeNum * 8, 7 + planeNum * 8, 5 + planeNum * 8); if (planeNum % m_width == 0 || m_cubes[planeNum / (double) m_width][(planeNum - 1) % m_width] == HOLE) { //left plane->triangle(0 + planeNum * 8, 4 + planeNum * 8, 5 + planeNum * 8); plane->triangle(5 + planeNum * 8, 4 + planeNum * 8, 0 + planeNum * 8); plane->triangle(0 + planeNum * 8, 1 + planeNum * 8, 5 + planeNum * 8); plane->triangle(5 + planeNum * 8, 1 + planeNum * 8, 0 + planeNum * 8); } if (planeNum % m_width == m_width - 1 || m_cubes[planeNum / (double) m_width][(planeNum + 1) % m_width] == HOLE) { //right plane->triangle(2 + planeNum * 8, 6 + planeNum * 8, 7 + planeNum * 8); plane->triangle(7 + planeNum * 8, 6 + planeNum * 8, 2 + planeNum * 8); plane->triangle(2 + planeNum * 8, 3 + planeNum * 8, 7 + planeNum * 8); plane->triangle(7 + planeNum * 8, 3 + planeNum * 8, 2 + planeNum * 8); } if (planeNum / (double) m_width >= m_length - 1 || m_cubes[(planeNum + m_width) / (double) m_width][planeNum % m_width] == HOLE) { //back plane->triangle(5 + planeNum * 8, 7 + planeNum * 8, 1 + planeNum * 8); plane->triangle(1 + planeNum * 8, 7 + planeNum * 8, 5 + planeNum * 8); plane->triangle(1 + planeNum * 8, 3 + planeNum * 8, 7 + planeNum * 8); plane->triangle(7 + planeNum * 8, 3 + planeNum * 8, 1 + planeNum * 8); } if (planeNum / (double) m_width <= m_width || m_cubes[(planeNum - m_width) / (double) m_width][planeNum % m_width] == HOLE) { //front plane->triangle(2 + planeNum * 8, 6 + planeNum * 8, 4 + planeNum * 8); plane->triangle(4 + planeNum * 8, 6 + planeNum * 8, 2 + planeNum * 8); plane->triangle(0 + planeNum * 8, 4 + planeNum * 8, 2 + planeNum * 8); plane->triangle(2 + planeNum * 8, 4 + planeNum * 8, 0 + planeNum * 8); } } planeNum++; } pos = pos + quat * Ogre::Vector3(0, 0, -100); } plane->end(); plane->setCastShadows(false); m_mapMainNode->attachObject(plane); MeshPtr ptr = plane->convertToMesh("planeMesh"); Entity* planeEntity = m_pSceneMgr->createEntity("planeEntity", "planeMesh"); }
void Map::generateMeshObstacles(std::string materialName) { Ogre::ManualObject* obstacles = new Ogre::ManualObject("obstacles"); obstacles->estimateIndexCount(m_length * m_width * 8); obstacles->estimateVertexCount(m_length * m_width * 8); obstacles->clear(); obstacles->begin(materialName); Ogre::Vector3 pos = Ogre::Vector3(0, 0, 0); Ogre::Quaternion quat; Ogre::Quaternion quatNext; unsigned long planeNum = 0; m_obstaclePositions.clear(); for (unsigned int i = 0; i < m_length; i++) { quat = m_rotationalSpline.getPoint(i); quatNext = m_rotationalSpline.getPoint(i + 1); for (int x = -100 * (m_width / (double) 2), j = 0; (unsigned) j < m_width; j++, x += 100) { int back = -100; int left = x; int right = x + 100; int up = 100; Ogre::Vector3 nextPos = pos + quat * Ogre::Vector3(0, 0, back); Ogre::Vector3 posMinus50 = pos + quat * Ogre::Vector3(left, 0, 0); Ogre::Vector3 posPlus50 = pos + quat * Ogre::Vector3(right, 0, 0); Ogre::Vector3 nextPosMinus50 = nextPos + quatNext * Ogre::Vector3(left, 0, 0); Ogre::Vector3 nextPosPlus50 = nextPos + quatNext * Ogre::Vector3(right, 0, 0); //TODO: fix normals obstacles->position(posMinus50); obstacles->normal((quat * Vector3(0, 1, 0)).normalisedCopy()); obstacles->textureCoord(1, 1); obstacles->position(nextPosMinus50); obstacles->normal((quat * Vector3(0, 1, 0)).normalisedCopy()); obstacles->textureCoord(1, 0); obstacles->position(posPlus50); obstacles->normal((quat * Vector3(0, 1, 0)).normalisedCopy()); obstacles->textureCoord(0, 1); obstacles->position(nextPosPlus50); obstacles->normal((quat * Vector3(0, 1, 0)).normalisedCopy()); obstacles->textureCoord(0, 0); Ogre::Vector3 nextPosUp = nextPos + quat * Ogre::Vector3(0, up, 0); Ogre::Vector3 posMinus50Up = posMinus50 + quat * Ogre::Vector3(0, up, 0); Ogre::Vector3 posPlus50Up = posPlus50 + quat * Ogre::Vector3(0, up, 0); Ogre::Vector3 nextPosMinus50Up = nextPosMinus50 + quatNext * Ogre::Vector3(0, up, 0); Ogre::Vector3 nextPosPlus50Up = nextPosPlus50 + quatNext * Ogre::Vector3(0, up, 0); //TODO: fix normals obstacles->position(posMinus50Up); obstacles->normal((quat * Vector3(-1, 1, 1)).normalisedCopy()); obstacles->textureCoord(0, 0); obstacles->position(nextPosMinus50Up); obstacles->normal((quat * Vector3(-1, 1, -1)).normalisedCopy()); obstacles->textureCoord(0, 1); obstacles->position(posPlus50Up); obstacles->normal((quat * Vector3(1, 1, 1)).normalisedCopy()); obstacles->textureCoord(1, 0); obstacles->position(nextPosPlus50Up); obstacles->normal((quat * Vector3(1, 1, -1)).normalisedCopy()); obstacles->textureCoord(1, 1); if (m_cubes[planeNum / (double) m_width][planeNum % m_width] == OBSTACLE) { //TODO: check if this hack works.. m_obstaclePositions.push_back(posMinus50); //top obstacles->triangle(4 + planeNum * 8, 5 + planeNum * 8, 6 + planeNum * 8); obstacles->triangle(6 + planeNum * 8, 5 + planeNum * 8, 4 + planeNum * 8); obstacles->triangle(5 + planeNum * 8, 7 + planeNum * 8, 6 + planeNum * 8); obstacles->triangle(6 + planeNum * 8, 7 + planeNum * 8, 5 + planeNum * 8); if (planeNum % m_width == 0 || m_cubes[planeNum / (double) m_width][(planeNum - 1) % m_width] != OBSTACLE) { //left obstacles->triangle(0 + planeNum * 8, 4 + planeNum * 8, 5 + planeNum * 8); obstacles->triangle(5 + planeNum * 8, 4 + planeNum * 8, 0 + planeNum * 8); obstacles->triangle(0 + planeNum * 8, 1 + planeNum * 8, 5 + planeNum * 8); obstacles->triangle(5 + planeNum * 8, 1 + planeNum * 8, 0 + planeNum * 8); } if (planeNum % m_width == m_width - 1 || m_cubes[planeNum / (double) m_width][(planeNum + 1) % m_width] != OBSTACLE) { //right obstacles->triangle(2 + planeNum * 8, 6 + planeNum * 8, 7 + planeNum * 8); obstacles->triangle(7 + planeNum * 8, 6 + planeNum * 8, 2 + planeNum * 8); obstacles->triangle(2 + planeNum * 8, 3 + planeNum * 8, 7 + planeNum * 8); obstacles->triangle(7 + planeNum * 8, 3 + planeNum * 8, 2 + planeNum * 8); } if (planeNum / (double) m_width >= m_length - 1 || m_cubes[(planeNum + m_width) / (double) m_width][planeNum % m_width] != OBSTACLE) { //back obstacles->triangle(5 + planeNum * 8, 7 + planeNum * 8, 1 + planeNum * 8); obstacles->triangle(1 + planeNum * 8, 7 + planeNum * 8, 5 + planeNum * 8); obstacles->triangle(1 + planeNum * 8, 3 + planeNum * 8, 7 + planeNum * 8); obstacles->triangle(7 + planeNum * 8, 3 + planeNum * 8, 1 + planeNum * 8); } if (planeNum / (double) m_width <= m_width || m_cubes[(planeNum - m_width) / (double) m_width][planeNum % m_width] != OBSTACLE) { //front obstacles->triangle(2 + planeNum * 8, 6 + planeNum * 8, 4 + planeNum * 8); obstacles->triangle(4 + planeNum * 8, 6 + planeNum * 8, 2 + planeNum * 8); obstacles->triangle(0 + planeNum * 8, 4 + planeNum * 8, 2 + planeNum * 8); obstacles->triangle(2 + planeNum * 8, 4 + planeNum * 8, 0 + planeNum * 8); } } planeNum++; } pos = pos + quat * Ogre::Vector3(0, 0, -100); } obstacles->end(); obstacles->setCastShadows(true); //TODO: fix graphics bug when no obstacles /*if (m_obstaclePositions.size() <= 0) { return; }*/ m_mapMainNode->attachObject(obstacles); MeshPtr ptr = obstacles->convertToMesh("obstaclesMesh"); Entity* obstaclesEntity = m_pSceneMgr->createEntity("obstaclesEntity", "obstaclesMesh"); }
// Given a scene node for a terrain, find the manual object on that scene node and // update the manual object with the heightmap passed. If there is no manual object on // the scene node, remove all it's attachments and add the manual object. // The heightmap is passed in a 1D array ordered by width rows (for(width) {for(length) {hm[w,l]}}) // This must be called between frames since it touches the scene graph // BETWEEN FRAME OPERATION void Region::UpdateTerrain(const int hmWidth, const int hmLength, const float* hm) { Ogre::SceneNode* node = this->TerrainSceneNode; LG::Log("Region::UpdateTerrain: updating terrain for region %s", this->Name.c_str()); if (node == NULL) { LG::Log("Region::UpdateTerrain: terrain scene node doesn't exist. Not updating terrain."); return; } // Find the movable object attached to the scene node. If not found remove all. if (node->numAttachedObjects() > 0) { Ogre::MovableObject* attached = node->getAttachedObject(0); if (attached->getMovableType() != "ManualObject") { // don't know why this would ever happen but clean out the odd stuff LG::Log("Found extra stuff on terrain scene node"); node->detachAllObjects(); } } // if there is not a manual object on the node, create a new one if (node->numAttachedObjects() == 0) { LG::Log("Region::UpdateTerrain: creating terrain ManualObject for region %s", this->Name.c_str()); // if no attached objects, we add our dynamic ManualObject Ogre::ManualObject* mob = LG::RendererOgre::Instance()->m_sceneMgr->createManualObject("ManualObject/" + node->getName()); mob->addQueryFlags(Ogre::SceneManager::WORLD_GEOMETRY_TYPE_MASK); mob->setDynamic(true); mob->setCastShadows(true); mob->setVisible(true); node->attachObject(mob); // m_visCalc->RecalculateVisibility(); } Ogre::ManualObject* mo = (Ogre::ManualObject*)node->getAttachedObject(0); // stuff our heightmap information into the dynamic manual object mo->estimateVertexCount(hmWidth * hmLength); mo->estimateIndexCount(hmWidth * hmLength * 6); if (mo->getNumSections() == 0) { // if first time mo->begin(LG::GetParameter("Renderer.Ogre.DefaultTerrainMaterial")); } else { mo->beginUpdate(0); // we've been here before } int loc = 0; for (int xx = 0; xx < hmWidth; xx++) { for (int yy = 0; yy < hmLength; yy++) { mo->position((Ogre::Real)xx, (Ogre::Real)yy, hm[loc++]); mo->textureCoord((float)xx / (float)hmWidth, (float)yy / (float)hmLength); mo->normal(0.0, 1.0, 0.0); // always up (for the moment) } } for (int px = 0; px < hmLength-1; px++) { for (int py = 0; py < hmWidth-1; py++) { mo->quad(px + py * hmWidth, px + (py + 1) * hmWidth, (px + 1) + (py + 1) * hmWidth, (px + 1) + py * hmWidth ); } } mo->end(); return; }