[转载]基于sandy3d的地形系统,有距离迷雾支持

[url]http://wonderfl.net/c/aWS6[/url]

package {
import flash.display.Sprite;
import flash.display.BitmapData;
import flash.display.Bitmap;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.events.KeyboardEvent;
import flash.net.URLRequest;
import flash.display.Loader;
import flash.geom.Rectangle;
import flash.display.StageScaleMode;
import flash.system.LoaderContext;

import sandy.core.Scene3D;
import sandy.core.scenegraph.Group;
import sandy.core.scenegraph.Camera3D;
import sandy.materials.attributes.MaterialAttributes;
import sandy.materials.attributes.LineAttributes;
import sandy.primitive.Plane3D;
import sandy.materials.Appearance;
import sandy.materials.ColorMaterial;
/**
* Please wait while loading texture(200*200)&heightmap(200*200) img.
* Dynamic terrain Class
* Based on Protopop&Mclelun's version of Collin Cusce's Terrain Class.
* Thanks to Murat KURT's LargeMap.
*
* @author sindney
* @version 1.1
* @date 07.21.2010
*/
[SWF(width = "465", height = "465", frameRate = "30")]
public class Main extends Sprite {

private var keyp:Array=[];
private var _hmOk:Boolean = false;
private var _tOk:Boolean = false;

private var _heightmap:Loader=new Loader();
private var _texture:Loader=new Loader();

private var g:Group;
private var camera:Camera3D;
private var scene:Scene3D;

private var _terrain:DynamicTerrain;

public function Main() {
graphics.beginFill(0x000000);
graphics.drawRect(0,0,stage.stageWidth,stage.stageHeight);
graphics.endFill();

stage.scaleMode = StageScaleMode.NO_SCALE;
stage.quality="low";

_heightmap.load(new URLRequest("http://assets.wonderfl.net/images/related_images/6/62/62b0/62b07692ba26b00d15f2b38e5c2a3285a64a31f1m"), new LoaderContext (true));
_texture.load(new URLRequest("http://assets.wonderfl.net/images/related_images/4/46/4677/4677c3b3576698a5e8ea13fbfdbbdf52d01846f8m"), new LoaderContext (true));
_texture.contentLoaderInfo.addEventListener(Event.COMPLETE,function(e:Event):void {_tOk = true;});
_heightmap.contentLoaderInfo.addEventListener(Event.COMPLETE,function(e:Event):void {_hmOk = true;});

camera = new Camera3D(stage.stageWidth,stage.stageHeight);
g = new Group();
scene = new Scene3D("scene",this,camera,g);
camera.y = 200;
camera.z = -200;
camera.tilt = 45;

addEventListener( Event.ENTER_FRAME, checkIfLoaded );
}

private function keyd(e:KeyboardEvent):void {
keyp[e.keyCode]=true;
}
private function keyu(e:KeyboardEvent):void {
keyp[e.keyCode]=false;
}

private function checkIfLoaded(e:Event):void {
if(_tOk&&_hmOk){
//Dynamic Terrain
var bRect:Rectangle = new Rectangle(0, 0, 200, 200);
var rect:Rectangle = new Rectangle(0, 0, 50, 50);
//200*(50/200)
var hRect:Rectangle = new Rectangle(0, 0, 50, 50);

_terrain = new DynamicTerrain("myDynamicTerrain", BitmapData (_texture.content["bitmapData"]), BitmapData (_heightmap.content["bitmapData"]), bRect, rect, hRect, 250, 10, 1);
//_terrain.appearance.frontMaterial.attributes = new MaterialAttributes( new LineAttributes(1,0x0066ff));
_terrain.enableFog = true;
_terrain.fogColor = 0x000000;
g.addChild(_terrain);

//Event Listener
stage.addEventListener(KeyboardEvent.KEY_DOWN,keyd);
stage.addEventListener(KeyboardEvent.KEY_UP,keyu);
stage.addEventListener(MouseEvent.MOUSE_WHEEL,wheel);
addEventListener( Event.ENTER_FRAME, render );
removeEventListener( Event.ENTER_FRAME, checkIfLoaded );
}
}

private function render(e:Event):void {
//w87 s83 a65 d68 up38 down40 right37 left39
if (keyp[38]||keyp[87]) {
camera.z+=5;
}
if (keyp[40]||keyp[83]) {
camera.z-=5;
}
if (keyp[65]||keyp[39]) {
camera.x+=5;
}
if (keyp[68]||keyp[37]) {
camera.x-=5;
}
if(camera.x>750)camera.x=750;
if(camera.x<0)camera.x=0;
if(camera.z<-950)camera.z=-950;
if(camera.z>-200)camera.z=-200;

_terrain.moveTo(camera.x,camera.z+200);
scene.render();
}

//mouse control
private function wheel(e:MouseEvent):void {
if (e.delta > 0) {
camera.tilt += 4;
} else {
camera.tilt -= 4;
}
}
}
}

import flash.display.BitmapData;
import flash.display.Bitmap;
import flash.geom.Rectangle;
import flash.geom.Point;
import flash.geom.Matrix;
import flash.filters.GlowFilter;

import sandy.primitive.Plane3D;
import sandy.core.data.Vertex;
import sandy.materials.Appearance;
import sandy.materials.BitmapMaterial;

class DynamicTerrain extends Plane3D {
//bigMap, map
private var mBmd:BitmapData;
private var tBmd:BitmapData;

//bigHeightMap, heightMap
private var hBmd:BitmapData;
private var thBmd:BitmapData;

//bigMapRectangle, mapRectangle, heightmapRectangle ,update delay
private var mRect:Rectangle;
private var tRect:Rectangle;
private var thRect:Rectangle;
private var delay:uint;

private var qua:uint;
private var magnitude:Number;

public function get mag():Number {
return magnitude;
}
public function set mag(_v:Number):void {
magnitude = _v;
updateTerrain();
}

private var _enableFog:Boolean = false;
private var _gf:GlowFilter = new GlowFilter(0xffffff,1,10,10,2,1,true);

//fake distance fog
public function get enableFog():Boolean {
return _enableFog;
}
public function set enableFog(_v:Boolean):void {
_enableFog = _v;
updateTerrain();
}
public function get fogColor():uint {
return _gf.color;
}
public function set fogColor(_v:uint):void {
_gf.color = _v;
updateTerrain();
}
public function get fogFilter():GlowFilter {
return _gf;
}
public function set fogFilter(_v:GlowFilter):void {
_gf = _v;
updateTerrain();
}


public function DynamicTerrain(name:String = null, _terrain:BitmapData = null, _heightmap:BitmapData = null, _bigMapRect:Rectangle = null, _mapRect:Rectangle = null, _hmRect:Rectangle = null, _s:uint = 500, _q:uint = 10, mag:Number = 1) {
super(name, _s, _s, _q, _q, Plane3D.ZX_ALIGNED);

qua = _q;
delay = int(_s/_q);
mRect = _bigMapRect;
tRect = _mapRect;
thRect = _hmRect;

mBmd = _terrain;
hBmd = _heightmap;
tBmd = new BitmapData(tRect.width, tRect.height, true, 0x000000);
thBmd = new BitmapData(thRect.width, thRect.height, false, 0x000000);

enableBackFaceCulling = false;
magnitude = mag;
bigMapSize = int((mBmd.height/tBmd.height)*_s );

appearance = new Appearance(new BitmapMaterial(tBmd));

moveTo(0,0);
}
private function updateTerrain():void {
//split map.
thBmd.copyPixels(hBmd, thRect, new Point());
tBmd.copyPixels(mBmd, tRect, new Point());
if (_enableFog) {
tBmd.applyFilter(tBmd, tBmd.rect, new Point(), _gf);
}

//update geometry.
var i:int = 0;
for each (var _v:Vertex in geometry.aVertex) {
var _t:Number = thRect.width/qua;
var _y:int = int(i/(qua+1));
var _x:int = int(i-_y*(qua+1));
var _ny:int = thBmd.getPixel(_x*_t,thRect.width - _y*_t);
_v.y = _ny * magnitude * .00001;
i++;
}
}
private var oldX:int = -1;
private var oldZ:int = -1;
private var bigMapSize:uint;

public function moveTo(_x:Number = 0, _z:Number = 0):void {
var nx:int = int(_x/delay);
var nz:int = int(_z/delay);
if (oldX != nx || oldZ != nz) {
oldX = nx;
oldZ = nz;
x = nx*delay;
z = nz*delay;
tRect.x = (x/bigMapSize)*mBmd.height;
tRect.y = -(z/bigMapSize)*mBmd.height;
thRect.x = (x/bigMapSize)*hBmd.height;
thRect.y = -(z/bigMapSize)*hBmd.height;

updateTerrain();
}
}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值