This tutorial shows you how "read" the height of an Elevation mesh in order to place or move objects on it's surface using the Away3D 2.0 library or higher.
We assume here you already know how the elevation class works, see the tutorial
How to create an elevation for more details on the Elevation class.
A word on the concept and how it works
The ElevationReader class manages surface tracking using exactly the same parameters as the Elevation class. For obvious reasons it must use the same elevation source BitmapData as well. Both classes share the same principles of color measurement, but this class does not generate any 3d objects. The ElevationReader class generates its own version of the elevation mesh but in a BitmapData form, a smooth shaded interpretation of the mesh based on the source passed to the ElevationReader class. Between each point defined on x - x1 and y - y1, the class draws gradients between the color values along the x and y axes.
At runtime, you are able to return the height from a given x and y coordinate, allowing an optional offset if you wish your object/camera to be higher than the actual surface level (usually the case). Depending on how your mesh is oriented, the returned number can be used to set the x,y or z properties of your object.
The reason a separate smoothed gradient BitmapData is used (instead of the original source BitmapData) is simple - say for the purpose of this tutorial you wanted to make an elevation from a source.jpg image containing some noisy pixels in between the resolution you passed to the Elevation class. The color channel values at coordinates between those points will not be an exact reflection of the mesh elevation. ElevationReader saves you the time-consuming task of making the smoothed map yourself.
Since the surface reading is pixel based, the higher the source resolution the better the reading. Try to have a source size as close as possible to the mesh size. In the case of very rough terrains, the constructor allows you to pass a smoothing integer which averages the current surface calculations with the previous calculation - the higher the integer the slower the reaction time in surface height. This value is useful when an object needs to move slowly across a low resolution terrain.
The above demo shows you the gradient. Both meshes are the same elevation, but the top one is textured using the smoothed result generated by the ElevationReader. You can see here that the lower the elevation, the darker the color (the internal color channel being used by the class is the red one).
ElevationReader.generate method properties
- sourceBmd:BitmapData - This is the same source BitmapData the Elevation class uses.
- channel:String - Specifies the color channel as: r, g, b or a. The default is r.
- subdivisionX:int - Specifies the gap between pixels to be read along the x axis, the default is 10.
- subdivisionY:int - Specifies the gap between pixels to be read along the y axis, the default is 10.
- factorX:Number - Specifies the scale along the x axis, the default is 1.
- factorY:Number - Specifies the scale along the y axis, the default is 1.
- elevate:Number - Specifies the scale along the z axis (the elevation multiplier), the default is 0.5.
ElevationReader public methods
- get source():BitmapData - returns the generated smoothed BitmapData object
- getLevel(x:Number, y:Number offset:Number = 0):Number - the most useful value, returns the height value of the surface at the given coordinates x and y, adding an optional extra offset.
How to implement
You'll need to import 2 classes from the extrusions package
import away3d.extrusions.Elevation; import away3d.extrusions.ElevationReader;
The code shown below is used by the the demo at top of this tutorial:
private function prepareWorld():void
{
//the scale along x axis
var factorW:Number = 8;
//the scale along y axis
var factorH:Number = 8;
//the elevation scale along z axis
var factorD:Number = 3.5;
//the precision for the x and y on the source
var precisionX:Number = 20;
var precisionY:Number = 20;
//make a new instance of the reader
elevationreader = new ElevationReader(0);
//we pass exactly same settings as for the Elevation class
elevationreader.traceLevels(elevatesource_bmd,
"r",
precisionX,
precisionY,
factorW,
factorH,
factorD);
//make a material
var mat:IMaterial = new BitmapMaterial(colorsource_bmd , {smooth:false, debug:false});
//you can reuse the smooth data if you want to test
var source_elevation:BitmapData = elevationreader.source;
var elevate:Elevation = new Elevation();
// now we generate the mesh, again using same params
var points:Array = elevate.generate(source_elevation,
"r",
precisionX,
precisionY,
factorW,
factorH,
factorD)
var extrude:SkinExtrude = new SkinExtrude(points, {material:mat,
recenter:true,
closepath:false,
coverall:true,
subdivision:1,
bothsides:false,
flip:false});
extrude.rotationX = 90;
extrude.x = extrude.z = 0;
extrude.y = 400;
(extrude as Mesh).pushback = true;
this.scene.addChild(extrude);
var matsphere:IMaterial = new BitmapMaterial(generateFromLib("spheretexture"));
target = new Sphere ({material:matsphere,
segmentsH:5,
segmentsW:5,
radius:50});
target.pushfront = true;
scene.addChild(target);
}
To update the y of the sphere at runtime, just pass the x and z coordinates of the sphere in the getLevel method to return the surface y. Note that thanks to the orientation of the mesh, the z value is negative in this case.
private function render(e:Event):void
{
if(target.x > 2400){
target.x = -2400;
target.z = -1500 + Math.random()*3000;
}else{
target.x += 50;
}
target.rotationZ -= 30;
target.y = elevationreader.getLevel(target.x, -target.z, 20);
view.render();
}



June 11th, 2008 at 8:19 pm
Very nice. Elevation is a really cool feature of Away3D - with a 20×20 segments plane it looks super smooth.
June 19th, 2008 at 11:08 am
Fabrice you are a genius!!!
October 14th, 2009 at 8:50 am
Hi Fabrice,
Very impresive demo. I was wondering if it is possible to actually use some real elevation data and also some real ground level photography like the google street view and place the elevation model in there. So for example create the spherical viewer like in the away3d tutorials and within there insert an extract of a known elevation model?
Lookin forward to your response.
Cheers
Dan
October 15th, 2009 at 10:00 am
Hi Dan,
Sure you can, the above demo demonstrate an automated solution standard in the Away engine. There are many other ways to achieve similar results. If you want to play around, you could try the NormalUV Modifier class found in extrusions package. This class offers you another level of possibilities in this field and is suitable for irregular surfaces and works in every plans.(xy, xz, yz)…