Juli 2009
3D-Landschaften: Papervision3D, Flash 10 & O3D
Fortsetzung, Teil 2
Die Papervision3D-Variante
Wie schon erwähnt, hält Papervision als bereits gut ausgebaute 3D-Engine eine Vielzahl an Methoden und Funktionen bereit, die uns den Landschaftsbau vereinfachen. Die weitere Vorgehensweise ist nun wie folgt (Listing 2), (Abb. 1):
- Eine Grundfläche/ein Polygonnetz definieren
- Farbwerte der bereits ausgewählten Textur einlesen
- Höhenkarte via perlinNoise erzeugen
- Höhenkarte via paletteMap einfärben
- Höhenkarte sowie Textur animieren
- Vertex-Positionen innerhalb der Grundfläche anhand der Höhenkarte verschieben
package {///////////////////////////////////// import used classes///////////////////////////////////import flash.display.*;import flash.events.*;import org.papervision3d.materials.BitmapMaterial;import org.papervision3d.scenes.Scene3D;import org.papervision3d.cameras.FreeCamera3D;import org.papervision3d.objects.Plane;import org.papervision3d.core.geom.Mesh3D;import flash.geom.*;import mx.core.BitmapAsset;///////////////////////////////////// class///////////////////////////////////public class Pv3dTectonicMesh extends Sprite {private var rootNode:DisplayObjectContainer;private var animNode:Sprite;private var heightNode:Sprite;private var container:Sprite;private var textureMap:BitmapData;private var canvasMap1:BitmapData;private var canvasMap2:BitmapData;private var displayMap:BitmapData;private var heightMap:BitmapData;private var heightTmp:BitmapData;private var groundMap:Bitmap;private var bmp1:Bitmap;private var bmp2:Bitmap;private var bmp3:Bitmap;private var bmp4:Bitmap;private var scene:Scene3D;private var camera:FreeCamera3D;private var tectonicMesh:Plane;private var shiftList0 :Array;private var shiftList1 :Array;private var baseX:Number;private var baseY:Number;private var octaves:Number;private var seed:Number;private var fNoise:Boolean;private var vertices:Array;private var gridX:Number;private var gridY:Number;private var vertexIndex:Number;private var iW:Number;private var iH:Number;private var colorPool:Array = new Array();///////////////////////////////////// class constructor///////////////////////////////////public function Pv3dTectonicMesh(rootNode:DisplayObjectContainer, colorMap:Bitmap) {this.rootNode = rootNode;this.animNode = new Sprite();this.heightNode = new Sprite();this.groundMap = colorMap;setup();}///////////////////////////////////// setup///////////////////////////////////private function setup():void {this.container = new Sprite();this.container.x = 400;this.container.y = 300;this.scene = new Scene3D( this.container );this.camera = new FreeCamera3D();this.camera.x = 0;this.camera.z = -600;this.camera.y = 525;this.camera.zoom = 15;this.camera.focus = 100;var heightMapWidth:Number = 1024;this.heightMap = new BitmapData( heightMapWidth, heightMapWidth, false, 0 );this.textureMap = new BitmapData( heightMapWidth, heightMapWidth, false, 0 );this.canvasMap1 = new BitmapData( heightMapWidth, heightMapWidth, false, 0 );this.canvasMap2 = new BitmapData( heightMapWidth, heightMapWidth, false, 0 );this.heightTmp = new BitmapData( heightMapWidth, heightMapWidth, false, 0 );this.displayMap = new BitmapData( heightMapWidth, heightMapWidth, false, 0 );var grad:BitmapAsset = BitmapAsset(groundMap);for ( var ra:uint = 0; ra < 256; ra++) {this.colorPool[ra] = grad.bitmapData.getPixel(10, 256 - ra);}this.bmp1 = new Bitmap( this.canvasMap1 );this.bmp2 = new Bitmap( this.canvasMap2 );this.bmp3 = new Bitmap( this.heightMap );this.bmp4 = new Bitmap( this.heightMap );var material:BitmapMaterial = new BitmapMaterial( this.displayMap );material.doubleSided = false;this.tectonicMesh = new Plane( material, 680, 680, 16, 16 );this.tectonicMesh.rotationX = -90;calculate();paint();this.scene.addChild( this.tectonicMesh, "TectonicPlate" );this.animNode.addChild( this.bmp1 );this.bmp2.x = this.bmp1.x + this.bmp1.width;this.bmp4.scaleX = -1.0;this.bmp4.x = (this.bmp3.x + this.bmp3.width)*2;this.animNode.addChild( this.bmp2 );this.heightNode.addChild( this.bmp3 );this.heightNode.addChild( this.bmp4 );this.rootNode.addChild( this.container );this.rootNode.addChild( this.panel );this.camera.lookAt( this.tectonicMesh );this.scene.renderCamera( this.camera );init();}///////////////////////////////////// initialize///////////////////////////////////private function init():void {this.container.addEventListener( Event.ENTER_FRAME, onUpdateFrame );this.container.stage.addEventListener( MouseEvent.MOUSE_DOWN, calculate );}///////////////////////////////////// calculate terrain///////////////////////////////////private function calculate( event:Event = null ):void {this.baseX = heightMap.width / ( 3 + Math.random() * 5 );this.baseY = heightMap.width / ( 3 + Math.random() * 5 );this.octaves = 2 + Math.round( Math.random() * 2 );this.seed = Math.random() * 8;if ( Math.random() > 0.5 ) {this.fNoise = true;} else {this.fNoise = false;}heightMap.perlinNoise( this.baseX, this.baseY, this.octaves, this.seed, false, this.fNoise, 4, false );textureMap.paletteMap( heightMap,heightMap.rect,new Point(), this.colorPool, this.colorPool, this.colorPool );this.vertices = tectonicMesh.geometry.vertices;this.gridX = tectonicMesh.segmentsW;this.gridY = tectonicMesh.segmentsH;this.vertexIndex = 0;this.iW = heightMap.width / gridX;this.iH = heightMap.height / gridY;for ( var ix:int = 0; ix < gridX + 1; ix++ ) {for( var iy:int = 0; iy < gridY + 1; iy++ ) {vertices[vertexIndex].z = -Math.min( 255,Math.max(1,heightMap.getPixel(ix*iW,heightMap.height-iy*iH)))/1;vertexIndex++;}}}///////////////////////////////////// paint terrain///////////////////////////////////private function paint( event:Event = null ):void {textureMap.paletteMap( heightMap, heightMap.rect, new Point(), this.colorPool, this.colorPool, this.colorPool );this.canvasMap1.draw( this.textureMap );this.canvasMap2.draw( this.textureMap, new Matrix( -1, 0, 0, 1, 1024, 0 ) );bmp1.x -= 3;bmp2.x -= 3;bmp3.x -= 3;bmp4.x -= 3;if ( this.bmp1.x + bmp1.width < 0 ) {this.bmp1.x = bmp2.x + bmp2.width;}if ( this.bmp2.x + bmp2.width < 0 ) {this.bmp2.x = bmp1.x + bmp1.width;}if ( this.bmp3.x + bmp3.width < 0 ) {this.bmp3.x = (bmp4.x + bmp4.width)-1024;}if ( this.bmp4.x + bmp4.width < 1024 ) {this.bmp4.x = (this.bmp3.x + this.bmp3.width)*2;}this.heightTmp.draw( this.heightNode );this.displayMap.draw( this.animNode );vertexIndex = 0;for ( var ix:int = 0; ix < gridX + 1; ix++ ) {for( var iy:int = 0; iy < gridY + 1; iy++ ) {vertices[vertexIndex].z = -Math.min( 255,Math.max(1,this.heightTmp.getPixel(ix*iW,this.heightTmp.height-iy*iH)))/1;vertexIndex++;}}}///////////////////////////////////// onUpdateFrame///////////////////////////////////private function onUpdateFrame(e:Event):void {paint();var axeAngle:Number = scene.container.mouseX/160;camera.x += (600*Math.cos(axeAngle)-camera.x)/20;camera.z += ( -600 * Math.sin(axeAngle) - camera.z) / 20;camera.lookAt( this.tectonicMesh);scene.renderCamera( camera );}}
Bisher keine Kommentare
3d,


























