Welcome to the new Ogre Wiki!
If you haven't done so already, be sure to visit the Wiki Portal to read about how the wiki works. Especially the Ogre Wiki Overview page.
If you haven't done so already, be sure to visit the Wiki Portal to read about how the wiki works. Especially the Ogre Wiki Overview page.
TerrainMeshDecal
Using a mesh decal to show a marker on the terrain for terrain selection
Terrain Selection using a Mesh Decal
When reading Intermediate Tutorial 5, I wanted to use a decal to indicate where the user clicks on the terrain. With help from the forums, here's some simple code to achieve that goal with a mesh decal. The idea is simple - create a small square mesh that sits just above the terrain where the user clicked, and texture it.
First, creating a manual object for the mesh. "Crosshairs" is the name of the material I'm using. Since this attaches the mesh to the scene, it should only be called once.
// Initial creation of the mesh decal void createMeshDecal() { mMeshDecal = new Ogre::ManualObject("MeshDecal"); mSceneMgr->getRootSceneNode()->attachObject(mMeshDecal); int x_size = 4; // number of polygons int z_size = 4; mMeshDecal->begin("Crosshairs", Ogre::RenderOperation::OT_TRIANGLE_LIST); for (int i=0; i<=x_size; i++) { for (int j=0; j<=z_size; j++) { mMeshDecal->position(Ogre::Vector3(i, 0, j)); mMeshDecal->textureCoord((float)i / (float)x_size, (float)j / (float)z_size); } } for (int i=0; i<x_size; i++) { for (int j=0; j<z_size; j++) { mMeshDecal->quad( i * (x_size+1) + j, i * (x_size+1) + j + 1, (i + 1) * (x_size+1) + j + 1, (i + 1) * (x_size+1) + j); } } mMeshDecal->end(); }
Next, the code I call when the user clicks on the terrain. "rad" is the "radius" of the decal - I had vague thoughts of making the decal larger if it's further in the distance.
// Update mesh decal when terrain selection happens void setMeshDecal(Ogre::Real x, Ogre::Real z, Ogre::Real rad) { Ogre::Real x1 = x - rad; Ogre::Real z1 = z - rad; int x_size = 4; // number of polygons int z_size = 4; Ogre::Real x_step = rad * 2/ x_size; Ogre::Real z_step = rad * 2/ z_size; mMeshDecal->beginUpdate(0); // redefine vertices for (int i=0; i<=x_size; i++) { for (int j=0; j<=z_size; j++) { mMeshDecal->position(Ogre::Vector3(x1, getTerrainHeight(x1, z1) + 1, z1)); mMeshDecal->textureCoord((float)i / (float)x_size, (float)j / (float)z_size); z1 += z_step; } x1 += x_step; z1 = z - rad; } // redefine quads for (int i=0; i<x_size; i++) { for (int j=0; j<z_size; j++) { mMeshDecal->quad( i * (x_size+1) + j, i * (x_size+1) + j + 1, (i + 1) * (x_size+1) + j + 1, (i + 1) * (x_size+1) + j); } } mMeshDecal->end(); }
Finally, figuring out the intersection with the ground:
Ogre::Real getTerrainHeight(Ogre::Real x, Ogre::Real z) { Ogre::Ray* verticalRay = new Ogre::Ray( Ogre::Vector3(x, 5000, z), Ogre::Vector3::NEGATIVE_UNIT_Y ); mRaySceneQuery->setRay( *verticalRay ); // Execute query Ogre::RaySceneQueryResult &result = mRaySceneQuery->execute(); Ogre::RaySceneQueryResult::iterator itr = result.begin( ); if ( itr != result.end() && itr->worldFragment ) { Ogre::Vector3 intersection = itr->worldFragment->singleIntersection; return intersection.y; } else { return 0; } }
And last, the material I'm using. Crosshairs.png is the image file from Intermediate Tutorial 5.
material Crosshairs { technique { pass { scene_blend alpha_blend depth_write off texture_unit { texture Crosshairs.png scale 1 1 } } } }
Contributors to this page: jacmoe
and
Beauty
.
Page last modified on Saturday 02 of January, 2010 05:44:08 GMT by jacmoe
.
The content on this page is licensed under the terms of the Creative Commons Attribution-ShareAlike License.
As an exception, any source code contributed within the content is released into the Public Domain.

