Click for shoot. Press R button to restore glass mesh:
//Bullet Resistant Glass by Mawhrin Skel http://flickr.com/photos/24789570@N03/2698809741/ [Embed(source='2698809741_76eddd085c.jpg')] private var MeshMat:Class; [Embed(source = 'broken.png')] private var BrokenCenter:Class //Parquet 2.0 version 6 by Kochubey http://www.filterforge.com/filters/488.html private const GROUND_TEXTURE:String = "488-v6+.jpg" private const BULLET_TEXTURE:String = "bullet_back.png" private static const BOUNDS:Number = 3000; // Limit for bullet private static const MESH_SIZE:uint = 512 private static const MESH_TESSELATION_X:uint = 8 private static const MESH_TESSELATION_Y:uint = 8 private static const GROUND_Y:int = -300 private static const SHOOT_POWER:Number = 0.15 // 1 is maximum //Glass Mesh private var mesh:Plane; private var meshMaterial:MaterialObject3D private var meshSprite:Sprite private var brokenCenterBmp:Bitmap //Bullet private var bullets:Array = new Array(); private var collidedBulletIndex:uint; //Physics private var isPhysicsOn:Boolean = false private var meshPartsPhysics:Array = new Array() private var detainedParts:Array = new Array() private var detainedPartsCounter:uint = 0 private var ground:Plane public function Main() { super(800, 600, false, false, "CAMERA3D"); preparePv3d(); createMaterials(); createObjects(); addListeners(); } public function preparePv3d():void { addChild(new StatsView(renderer)); } public function createMaterials():void { meshSprite = new Sprite() meshSprite.addChild(new MeshMat() as Bitmap) meshSprite.alpha = 0.3 brokenCenterBmp = new BrokenCenter() as Bitmap brokenCenterBmp.alpha = 0 meshSprite.addChild(brokenCenterBmp); meshMaterial = new MovieMaterial(meshSprite, true, true, false, new Rectangle(0, 0, MESH_SIZE, MESH_SIZE)) meshMaterial.doubleSided = true; } public function createObjects():void { ground = new Plane(new BitmapFileMaterial(GROUND_TEXTURE), 1024, 1024, 6, 6) ground.rotationX = -270 ground.y = GROUND_Y ground.z = 100 scene.addChild(ground) restoreMesh() // create glass mesh } public function breakMesh(mesh:TriangleMesh3D):void { if (!isPhysicsOn && bullets[collidedBulletIndex] !=null) { detainedPartsCounter = 0 detainedParts = new Array() meshPartsPhysics = new Array(); var geom:GeometryObject3D = mesh.geometry; var oTris:Array = geom.faces; var nTris:Array = new Array(); var vert:Vertex3D; var nVert:Vertex3D; var triangle:Triangle3D; var nTriangle:Triangle3D; for (var i:int = 0; i < oTris.length; i++) { var currFace:Triangle3D = oTris[i]; var vertCacheA:Dictionary = new Dictionary(true); var triangleBucketA:Array = new Array(); var vertBucketA:Array = new Array(); var meshX:int var meshY:int triangle = currFace for (var k:int = 0; k < currFace.vertices.length; k++) { vert = currFace.vertices[k]; if(!(nVert = vertCacheA[vert])){ nVert = vert.clone(); vertCacheA[vert] = nVert; } vertBucketA.push(nVert) triangle.vertices[k] = nVert; } // Save position for new mesh meshX = triangle.vertices[0].x meshY = triangle.vertices[0].y // Calculate shift for vertices var shiftX:int = MESH_SIZE/MESH_TESSELATION_X var shiftY:int = MESH_SIZE/MESH_TESSELATION_Y if (triangle.vertices[0].x > triangle.vertices[1].x) shiftX = -MESH_SIZE/MESH_TESSELATION_X if (triangle.vertices[0].y > triangle.vertices[2].y) shiftY = -MESH_SIZE/MESH_TESSELATION_Y // Set local position for vertices triangle.vertices[0].x = 0 triangle.vertices[0].y = 0 triangle.vertices[1].x = shiftX triangle.vertices[1].y = 0 triangle.vertices[2].x = 0 triangle.vertices[2].y = shiftY triangle.updateVertices(); //create new mesh add it on scene var meshA:TriangleMesh3D = new TriangleMesh3D(mesh.material, vertBucketA, [triangle]); meshA.geometry.ready = true meshA.x = meshX meshA.y = meshY brokenCenterBmp.x = bullets[collidedBulletIndex].x - (mesh.x - MESH_SIZE*0.5) -brokenCenterBmp.width/2 brokenCenterBmp.y = -bullets[collidedBulletIndex].y - (mesh.y - MESH_SIZE*0.5) -brokenCenterBmp.height/2 brokenCenterBmp.alpha = 1 //add physics for new mesh meshPartsPhysics.push(new PolygonPhysics(TriangleMesh3D(meshA), 10, .5, 1)); scene.addChild(meshPartsPhysics[i].Object3D); } for each(var meshPart:PolygonPhysics in meshPartsPhysics) { var xdiff : Number = meshPart.Object3D.x-bullets[collidedBulletIndex].x; var ydiff : Number = meshPart.Object3D.y-bullets[collidedBulletIndex].y; var distance : Number = Math.sqrt((xdiff * xdiff) + (ydiff * ydiff)) if (distance > MESH_SIZE*SHOOT_POWER*1.5){ meshPart.isDetained = true; //add impulse for detained parts meshPart.LinImpulse = new Number3D(Math.random()*10, 10, 10-Math.random()*20) meshPart.RotImpulse= new Number3D(Math.random()*.2,Math.random()*.2,Math.random()*.2) }else { //add impulse for not detained parts var impX:int var impY:int if (bullets[collidedBulletIndex].x < meshPart.Object3D.x) impX = MESH_SIZE*SHOOT_POWER*.5 else impX = -MESH_SIZE*SHOOT_POWER*.5 if (bullets[collidedBulletIndex].y < meshPart.Object3D.y) impY = MESH_SIZE*SHOOT_POWER*.5 else impY = -MESH_SIZE*SHOOT_POWER*.5 meshPart.LinImpulse = new Number3D(impX, impY, (MESH_SIZE - distance)*SHOOT_POWER) meshPart.RotImpulse= new Number3D(Math.random()*.6,Math.random()*.6,Math.random()*.6) } } isPhysicsOn = true; } scene.removeChild(mesh) } public function restoreMesh():void { if (meshPartsPhysics.length > 0) { for (var i:int = 0; i < meshPartsPhysics.length; i++) { scene.removeChild(meshPartsPhysics[i].Object3D); } } mesh = new Plane(meshMaterial, MESH_SIZE, MESH_SIZE, MESH_TESSELATION_X, MESH_TESSELATION_Y) scene.addChild(mesh) isPhysicsOn = false brokenCenterBmp.alpha = 0 } public function enterFrameHandler(event:Event):void { if(isPhysicsOn){ updatePhysics(); detainedPartsCounter++ } updateBullet(); rotateCamera(); singleRender(); } private function updateBullet():void { for each(var bullet:DisplayObject3D in bullets) { bullet.moveForward(100); if(bullet.hitTestObject(mesh)){ breakMesh(mesh); collidedBulletIndex = bullets.indexOf(bullet) } if (Math.abs(bullet.x) > BOUNDS/2 || Math.abs(bullet.y) > BOUNDS/2 || Math.abs(bullet.z) > BOUNDS/2) { bullets.splice(bullets.indexOf(bullet), 1 ); scene.removeChild(bullet); } } } private function updatePhysics():void { for (var i:int = 0; i < meshPartsPhysics.length; i++) { if(meshPartsPhysics[i].isDetained == false || detainedPartsCounter > meshPartsPhysics.length*SHOOT_POWER){ if (meshPartsPhysics[i].Object3D.y > GROUND_Y) { meshPartsPhysics[i].AddForce(meshPartsPhysics[i].CGPosition, Number3DPlus.multiply(new Number3D(0, -.2, 0), meshPartsPhysics[i].Mass)); meshPartsPhysics[i].Update(1.7); }else { if(meshPartsPhysics[i].isStopped == false){ meshPartsPhysics[i].resetPos(); meshPartsPhysics[i].Object3D.rotationY = Math.random()*180 // dirty fix meshPartsPhysics[i].ResetImpulse(); meshPartsPhysics[i].ResetForce(); meshPartsPhysics[i].Object3D.y = GROUND_Y meshPartsPhysics[i].Object3D.rotationX = 90 meshPartsPhysics[i].Object3D.rotationZ = 0 meshPartsPhysics[i].isStopped = true } } } } } public function addListeners():void { addEventListener(Event.ENTER_FRAME, enterFrameHandler); stage.addEventListener(KeyboardEvent.KEY_UP, keyUpHandler); stage.addEventListener(MouseEvent.CLICK, onMouseClick); } private function rotateCamera():void { camera.rotationX = -(viewport.mouseY - stage.height / 2) / 5; camera.rotationY = (viewport.mouseX - stage.width / 2) / 5; } private function onMouseClick(e:MouseEvent):void { var bullet:Plane = new Plane(new BitmapFileMaterial(BULLET_TEXTURE), 64, 64, 1, 1) bullet.copyPosition(camera); bullet.copyTransform(camera); bullet.moveForward(400); scene.addChild(bullet); bullets.push(bullet); } public function keyUpHandler(e:KeyboardEvent):void { if (isChar(e.charCode, "r")) { if (meshPartsPhysics.length > 0) restoreMesh(); else breakMesh(mesh); } } private function isChar(code:Number, str:String):Boolean{ if(code == str.charCodeAt()) return true; return false; }
Comments (0) 07.10.2008. 21:10
var relativeSpherePosition1:Number3D = new Number3D( colorSphere1.x-(plane1.x-PLANE_SIZE*0.5), colorSphere1.y-(plane2.y-PLANE_SIZE*0.5), colorSphere1.z-(plane3.z-PLANE_SIZE*0.5) );And drawing spot on MovieMaterial. Thanks Andy Zupko for show easy way to get movie from material: Sprite(MovieMaterial(plane1.material).movie)
public var p3d:Plane3D; // just for hold plane orientation public var spot:Shape = new Shape(); public var spotColor:Number public var spotWidth:int public var spotHeight:int public var spotDepth:int public var sx:int public var sy:int public var sz:int public var movieFromMat:Sprite; public static const MIN_DISTANCE:uint = 400; public function ColorSpotCaster(plane3d:Plane3D, movieFromMaterial:Sprite, color:Number, width:int, height:int) { this.p3d = plane3d this.movieFromMat = movieFromMaterial this.spotColor = color this.spotWidth = width this.spotHeight = height this.spotDepth = width drawSpot(); } public function drawSpot():void { spot.name = "spot"; var gType:String = GradientType.RADIAL; var matrix:Matrix = new Matrix(); matrix.createGradientBox(spotWidth,spotHeight,0,-spotWidth*0.5, -spotHeight*0.5); var gColors:Array = [spotColor, 0x000000]; var gAlphas:Array = [1,0]; var gRatio:Array = [0,255]; var g:Graphics = spot.graphics g.beginGradientFill(gType,gColors,gAlphas,gRatio,matrix); g.drawRect(-spotWidth*0.5, -spotHeight*0.5, spotWidth, spotHeight); movieFromMat.addChild(spot) } public function updateSpotPositions(relativeColorThingPosition:Number3D, planeSize:uint, distance:uint):void { if (p3d.normal.y == 1) { spot.x = relativeColorThingPosition.x spot.y = planeSize-relativeColorThingPosition.z }else if (p3d.normal.z == 1) { spot.x = relativeColorThingPosition.x spot.y = planeSize-relativeColorThingPosition.y }else if (p3d.normal.x == 1) { spot.x = relativeColorThingPosition.z spot.y = planeSize-relativeColorThingPosition.y } spot.alpha = (MIN_DISTANCE - distance) / MIN_DISTANCE if(distance > MIN_DISTANCE*0.5) spot.scaleX = spot.scaleY =2+distance/100 else spot.scaleX = spot.scaleY =2+(MIN_DISTANCE-distance)/100 }
Comments (1) 15.07.2008. 17:24
private var view:View3D; private var camera:HoverCamera3D; private var thing:Object3D; private var thingIndex:uint; //loading materials images private var loader:Loader; private var loader2:Loader; private var isLoad:Boolean; private var isLoad2:Boolean; private var isImagesLoaded:Boolean; //lights private var lightDirect:DirectionalLight3D; private var lightDirect2:DirectionalLight3D; private var sphere:Sphere; private var sphere2:Sphere; private var lightColors:Array = [0xff0000, 0x00ff00, 0x0000ff, 0xffffff, 0x00ffff, 0xff00ff, 0xffff00]; private var lightColorIndex:uint = 0; //lights dragging private var clickTarget:uint; private var isMousePress:Boolean; private var dragPositionX:int; private var dragPositionZ:int; //navigation variables private var lastPanAngle:Number; private var lastTiltAngle:Number; private var lastMouseX:Number; private var lastMouseY:Number; private var isDragging:Boolean = false; public function NormalMapTest():void { prepareAway3d(); createLights(); createObjects(); addListeners(); } private function prepareAway3d():void { camera = new HoverCamera3D(); view = new View3D({camera:camera}); view.x = 250; view.y = 250; addChild(view); } private function createLights():void { lightDirect = new DirectionalLight3D( { color:0xFFFFFF, ambient:0.25, diffuse:0.75, specular:0.9 } ); lightDirect2 = new DirectionalLight3D( { color:0xffffff, ambient:0.25, diffuse:0.75, specular:0.9 } ); lightDirect.x = -200; lightDirect.z = -200; lightDirect2.x = 200; lightDirect2.z = 200; lightDirect.y = 200; lightDirect2.y = 200; view.scene.addChild( lightDirect ); view.scene.addChild( lightDirect2 ); } private function createObjects():void { sphere = new Sphere({material: new ColorMaterial(0xffffff), radius:40, segmentsW:4, segmentsH:4, y:50}); sphere2 = new Sphere( { material: new ColorMaterial(0xffffff), radius:40, segmentsW:4, segmentsH:4, y:50 } ); thingIndex = 1; createObject3D(new WireframeMaterial(), true); sphere.name = "light1"; sphere2.name = "light2"; view.scene.addChild(sphere); view.scene.addChild(sphere2); } private function createObject3D(material:*, changeMat:Boolean):void { if (thing) { view.scene.removeChild(thing); } switch (thingIndex) { case 1 : thing = new Plane( { material:material, width:512, height:512, segmentsW:2, segmentsH:2, ownCanvas:true } ); if (changeMat) { //Cobble Stone by Nutsy http://www.filterforge.com/filters/3643.html loadMaterial("3643-diffuse.jpg", "3643-normal.jpg"); } break; case 2 : thing = new Sphere( { material: material, radius:256, segmentsW:12, segmentsH:12, y: -128, ownCanvas:true } ); thing.rotationX = -90; if (changeMat) { //Wooden Wave by Constantin Malkov http://www.filterforge.com/filters/5043.html loadMaterial("5043-diffuse.jpg", "5043-normal.jpg"); } break; case 3 : thing = new Cube( { material: material, width:400, height:200, depth:400, ownCanvas:true } ); if (changeMat) { //Lounge Lizards by Crapadilla http://www.filterforge.com/filters/1596.html loadMaterial("1596-diffuse.jpg", "1596-normal.jpg"); } break; case 4 : thing = new Torus( { material: material, radius:150, tube:100, segmentsR:8, segmentsT:12, ownCanvas:true } ); if (changeMat) { //Snow_02 by jensp http://www.filterforge.com/filters/442.html loadMaterial("442-diffuse.jpg", "442-normal.jpg"); } break; } view.scene.addChild(thing); } private function addListeners():void { addEventListener(Event.ENTER_FRAME, onEnterFrame); stage.addEventListener(KeyboardEvent.KEY_UP, keyUpHandler); stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDownHandler); stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUpHandler); view.scene.addOnMouseMove(dragElement); view.scene.addOnMouseUp(dropElement); sphere.addOnMouseDown(clickElement); sphere2.addOnMouseDown(clickElement); thing.addOnMouseDown(dropElement);// drop light when click on thing } private function loadMaterial(urlDiffuse:String, urlNormal:String):void { isImagesLoaded = false; isLoad = false; loader = new Loader( ); loader.contentLoaderInfo.addEventListener( Event.COMPLETE, handleComplete ); loader.load( new URLRequest( urlDiffuse ) ); isLoad2 = false; loader2 = new Loader( ); loader2.contentLoaderInfo.addEventListener( Event.COMPLETE, handleComplete2 ); loader2.load( new URLRequest( urlNormal ) ); } private function handleComplete( event:Event ):void { isLoad = true; if (isLoad2) { setupMaterial(); } } private function handleComplete2( event:Event ):void { isLoad2 = true; if (isLoad) { setupMaterial(); } } private function setupMaterial():void { isImagesLoaded = true; var image1:Bitmap = loader.content as Bitmap; var image2:Bitmap = loader2.content as Bitmap; var material:Dot3BitmapMaterial = new Dot3BitmapMaterial(image1.bitmapData, { normalMap:image2.bitmapData } ); createObject3D(material, false); } private function onEnterFrame(event:Event):void { if (clickTarget == 1) { lightDirect.x = dragPositionX; lightDirect.z = dragPositionZ; } else if (clickTarget == 2) { lightDirect2.x = dragPositionX; lightDirect2.z = dragPositionZ; } view.render(); sphere.position = lightDirect.position; sphere2.position = lightDirect2.position; if (isDragging && isMousePress == false) { camera.targetpanangle = 0.3*(stage.mouseX - lastMouseX) + lastPanAngle; camera.targettiltangle = 0.3*(stage.mouseY - lastMouseY) + lastTiltAngle; } camera.hover(); } private function clickElement(event:MouseEvent3D):void { isMousePress = true; if (event.object.name == "light1") { clickTarget = 1; } else if (event.object.name == "light2") { clickTarget = 2 ; if (lightColorIndex >= lightColors.length) { lightColorIndex = 0; } lightDirect2.color = lightColors[lightColorIndex]; //trace("lightColors[lightColorIndex]",lightColors[lightColorIndex]) sphere2.material = new ColorMaterial(lightColors[lightColorIndex]); lightColorIndex++; } } private function dropElement(event:MouseEvent3D):void { isMousePress = false; clickTarget = 0; } private function dragElement(event:MouseEvent3D):void { dragPositionX = event.sceneX; dragPositionZ = event.sceneZ; } private function onMouseUpHandler(event:MouseEvent):void { isDragging = false; } private function onMouseDownHandler(event:MouseEvent):void { lastPanAngle = camera.targetpanangle; lastTiltAngle = camera.targettiltangle; lastMouseX = stage.mouseX; lastMouseY = stage.mouseY; isDragging = true; } private function keyUpHandler(e:KeyboardEvent):void { if (isChar(e.charCode, "1")) { thingIndex = 1; createObject3D(new WireframeMaterial(), true); } else if (isChar(e.charCode, "2")) { thingIndex = 2; createObject3D(new WireframeMaterial(), true); } else if (isChar(e.charCode, "3")) { thingIndex = 3; createObject3D(new WireframeMaterial(), true); } else if (isChar(e.charCode, "4")) { thingIndex = 4; createObject3D(new WireframeMaterial(), true); } } private function isChar(code:Number, str:String):Boolean { if (code == str.charCodeAt()) { return true; } return false; }
Comments (3) 17.05.2008. 06:19
Get Sources of Tree Biomorph Toy AS
Lindenmayer Systems very powerful tool for make organic structures. My example make with Andy Zupko L-system class, for make separate branches, and add TweenLite for animating each line. I take two Turtle rules from Artificial Life by Scott Cameron.Get Sources Of Animate L-system
Comments (3) 25.04.2008. 13:48
private var body1:DAE; private var body2:DAE; private var bodyOnScene:DAE; //Flags private var isDragging:Boolean = false; private var stats:StatsView; private var morphSlider_breast:Slider; private var morphSlider_waist:Slider; private var morphSlider_pelvis:Slider; private var stateText:TextField; public function MorphTest1() { super(600, 600, false, false, "CAMERA3D"); preparePv3d(); loadAssets(); createObjects(); addControls(); addListeners(); startRendering(); } public function preparePv3d():void { camera.z = -800; camera.zoom = 20; stats = new StatsView(renderer); stage.addChild(stats); } public function loadAssets():void { var daeFile:String = "assets/woman_body_deatached_mat2.DAE"; body1 = new DAE(); body1.load(daeFile); body1.addEventListener(FileLoadEvent.LOAD_PROGRESS, loadProgress); body1.addEventListener(FileLoadEvent.LOAD_COMPLETE, daeLoadComplete); bodyOnScene = new DAE(); bodyOnScene.load(daeFile); bodyOnScene.addEventListener(FileLoadEvent.LOAD_PROGRESS, loadProgress); bodyOnScene.addEventListener(FileLoadEvent.LOAD_COMPLETE, daeLoadComplete); var daeFile2:String = "assets/woman_body_deatached_mat2_max.DAE"; body2 = new DAE(); body2.load(daeFile2); body2.addEventListener(ProgressEvent.PROGRESS, loadProgress); body2.addEventListener(Event.COMPLETE, daeLoadComplete); } public function createObjects():void { bodyOnScene.scale = body1.scale = body2.scale = 30; bodyOnScene.y = -150; bodyOnScene.rotationX = 90; bodyOnScene.rotationY = 30; scene.addChild(bodyOnScene); } public function addControls():void { morphSlider_breast = new Slider(); stage.addChild(morphSlider_breast); morphSlider_breast.y = 100; morphSlider_breast.x = 610; morphSlider_breast.name = "Breast"; morphSlider_waist = new Slider(); stage.addChild(morphSlider_waist); morphSlider_waist.y = 200; morphSlider_waist.x = 610; morphSlider_waist.name = "Waist"; morphSlider_pelvis = new Slider(); stage.addChild(morphSlider_pelvis); morphSlider_pelvis.y = 300; morphSlider_pelvis.x = 610; morphSlider_pelvis.name = "Hips"; morphSlider_breast.liveDragging = morphSlider_waist.liveDragging = morphSlider_pelvis.liveDragging = true; morphSlider_breast.maximum = morphSlider_waist.maximum = morphSlider_pelvis.maximum = 100; morphSlider_breast.minimum = morphSlider_waist.minimum = morphSlider_pelvis.minimum = 0; morphSlider_breast.width = morphSlider_waist.width = morphSlider_pelvis.width = 180; stateText = new TextField(); stateText.autoSize = TextFieldAutoSize.LEFT; var format:TextFormat = new TextFormat("Arial", 10, 0xff00000) stateText.defaultTextFormat = format stage.addChild(stateText) stateText.x = 200; stateText.y = 5; stateText.text = "Loading Collada"; } public function addListeners():void { stage.addEventListener(MouseEvent.MOUSE_DOWN, onPressHandler); stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUpHandler); morphSlider_breast.addEventListener(SliderEvent.CHANGE, onSliderChangeHandler); morphSlider_waist.addEventListener(SliderEvent.CHANGE, onSliderChangeHandler); morphSlider_pelvis.addEventListener(SliderEvent.CHANGE, onSliderChangeHandler); } public function onPressHandler(event:MouseEvent):void { isDragging = true; } public function onMouseUpHandler(event:MouseEvent):void { isDragging = false; } public function onSliderChangeHandler(event:SliderEvent):void { trace(event.target.name) switch(event.target.name) { case("Breast"): { morphingThing("Breast-node-Node_001", morphSlider_breast.value/100); break; } case("Waist"): { morphingThing("Waist-node-Node_001", morphSlider_waist.value/100); break; } case("Hips"): { morphingThing("Pelvis-node-Node_001", morphSlider_pelvis.value/100); break; } } } public function morphingThing(childname:String, lerpstep:Number) { for (var i:int = 0; i < body1.getChildByName("COLLADA_Scene").getChildByName(childname).geometry.vertices.length; i++) { var v:Vertex3D = bodyOnScene.getChildByName("COLLADA_Scene").getChildByName(childname).geometry.vertices[i]; v.x = lerp(body1.getChildByName("COLLADA_Scene").getChildByName(childname).geometry.vertices[i].x, body2.getChildByName("COLLADA_Scene").getChildByName(childname).geometry.vertices[i].x, lerpstep); v.y = lerp(body1.getChildByName("COLLADA_Scene").getChildByName(childname).geometry.vertices[i].y, body2.getChildByName("COLLADA_Scene").getChildByName(childname).geometry.vertices[i].y, lerpstep); v.z = lerp(body1.getChildByName("COLLADA_Scene").getChildByName(childname).geometry.vertices[i].z, body2.getChildByName("COLLADA_Scene").getChildByName(childname).geometry.vertices[i].z, lerpstep); v.calculateNormal(); } for each(var face:Triangle3D in body1.getChildByName("COLLADA_Scene").getChildByName(childname).faces) face.createNormal(); } override protected function onRenderTick(event:Event=null):void { rotateCamera(); super.onRenderTick(event); } private function rotateCamera():void{ if(isDragging && mouseX < 600){ var x:Number = (stage.mouseX - stage.stageWidth/2) / 4; camera.moveLeft(x); var y:Number = (stage.mouseY - stage.stageHeight/2) / 6; camera.moveDown(y); if (camera.y > 1000 || camera.y < -200) camera.moveDown(-y); } } private function loadProgress(e:FileLoadEvent):void { stateText.text = "Loading Collada: " + Math.floor((e.bytesLoaded / e.bytesTotal) * 100) + "%" + " " +(e.bytesLoaded +"/"+ e.bytesTotal); } private function daeLoadComplete(e:Event):void { stateText.text = "Complete Collada"; } public function lerp(coord1:Number, coord2:Number, lerpstep:Number):Number { return(coord1+(coord2-coord1)*lerpstep); }
Comments (7) 28.03.2008. 21:33
private var theta:Number = 0; private var buffer:Array = new Array(2); private var renderBuffer:int = 0; private var k1:Number; private var k2:Number; private var k3:Number; //Common private var range:int = 20; // play with tesselation private var waterSegsX:int = range; private var waterSegsY:int = range; private var waterSegsXreal:int = waterSegsX+1; private var waterSegsYreal:int = waterSegsY+1; private var waterXcenter:int = range/2; private var waterYcenter:int= range/2; private var isPause:Boolean = false; //3D private var waterSurface:Plane; private var light:PointLight3D; public function Fluid2() { super(600, 400, false, false, "CAMERA3D"); preparePv3d(); prepareMath(); createObjects(); addListeners(); } public function preparePv3d():void { stage.quality = "LOW"; stage.scaleMode = "noScale"; stage.align = StageAlign.TOP_LEFT; camera.zoom = 5; addChild(new Stats()) // Mr.Doob Stats http://code.google.com/p/mrdoob/ } public function changeWaterMaterial(matIndex:uint):void { var material1:CompositeMaterial; var material2:ShadedMaterial; var envmapAsset:Class = getDefinitionByName("pat710.jpg") as Class; //"BlueSkies" by Michael Lambert http://www.filterforge.com/filters/710.html var envmapBitmapData:BitmapData = new envmapAsset(0, 0) as BitmapData; var waterShader:EnvMapShader; var waterBitmapMat:BitmapMaterial; var bumpmapAsset:Class; var bumpmapBitmapData:BitmapData; switch(matIndex) { case 1: material1 = new CompositeMaterial(); material1.addMaterial(new ColorMaterial(0x0000fff, 1)); var wireframe:WireframeMaterial = new WireframeMaterial(0x9b85f9, 1); wireframe.doubleSided = true; material1.addMaterial(wireframe); waterSurface.material = material1; makeSplash(30); // play with splash height break; case 2: bumpmapAsset = getDefinitionByName("bump465.jpg") as Class; bumpmapBitmapData = new bumpmapAsset(0,0) as BitmapData; waterShader = new EnvMapShader(light, envmapBitmapData, envmapBitmapData,0,bumpmapBitmapData); waterBitmapMat = new BitmapAssetMaterial("diffuse465.jpg"); //"poolwater" by DrEvil http://www.filterforge.com/filters/465.html material2 = new ShadedMaterial(waterBitmapMat, waterShader); waterSurface.material = material2; makeSplash(30); break; case 3: bumpmapAsset = getDefinitionByName("bump465.jpg") as Class; bumpmapBitmapData = new bumpmapAsset(0,0) as BitmapData; waterShader = new EnvMapShader(light, envmapBitmapData, envmapBitmapData,0,bumpmapBitmapData); waterBitmapMat = new BitmapAssetMaterial("pat2192.jpg"); //"Aqua Absolute" by Zephos http://www.filterforge.com/filters/2192.html material2 = new ShadedMaterial(waterBitmapMat, waterShader); waterSurface.material = material2; makeSplash(30); break; case 4: bumpmapAsset = getDefinitionByName("bump4141.jpg") as Class; bumpmapBitmapData = new bumpmapAsset(0,0) as BitmapData; waterShader = new EnvMapShader(light, envmapBitmapData, envmapBitmapData,0,bumpmapBitmapData); waterBitmapMat = new BitmapAssetMaterial("diffuse4141.jpg"); // "Sea Water" by Constantin Malkov http://www.filterforge.com/filters/4141.html material2 = new ShadedMaterial(waterBitmapMat, waterShader); waterSurface.material = material2; makeSplash(30); break; } waterSurface.material.doubleSided = true; } public function createObjects():void { light = new PointLight3D(false, false); waterSurface = new Plane(new MaterialObject3D(), 1200, 1200, waterSegsX, waterSegsY); changeWaterMaterial(1); waterSurface.material.doubleSided = true; waterSurface.rotationX = -90; scene.addChild(waterSurface); camera.lookAt(waterSurface); trace("vertices: ", waterSurface.geometry.vertices.length, "faces: ", waterSurface.geometry.faces.length) } public function prepareMath():void { populateBuffer(); //trace(buffer[0].length, buffer[1].length) var d:Number = 1; var t:Number = 0.1; var c:Number = 2.1; var mu:Number = 0.001; var f1:Number = c*c*t*t/(d*d); var f2:Number = 1/(mu*t+2); k1 = (4 - 8*f1)*f2; k2 = (mu*t-2)*f2; k3 = 2 * f1 * f2; } public function populateBuffer():void { var x:int,y:int,z:int; // 3-d displacement will be stored in the array(2*w*h) for(var i:int = 0 ; i < 2; i++){ var a:Array = new Array(); for(var j:int = 0 ; j < waterSegsYreal; j++){ var aa:Array = new Array(); for(var k:int = 0 ; k < waterSegsXreal; k++) aa.push(new Number3D(j,0,k)); a.push(aa); } buffer[i] = a; } } public function makeSplash(splashHeight:int):void { populateBuffer(); buffer[renderBuffer][waterXcenter][waterYcenter].y = splashHeight; } public function addListeners():void { addEventListener(Event.ENTER_FRAME, onEnterFrame); stage.addEventListener(KeyboardEvent.KEY_UP, keyUpHandler); } private function evaluate():void{ for(var j:int = 1 ; j < waterSegsYreal-1; j++){ var crnt:Array = buffer[renderBuffer][j]; var prev:Array = buffer[1-renderBuffer][j]; for (var i:int = 1 ; i < waterSegsXreal-1; i++) { // trace(j, i); var currentN:Number3D = (Number3D)(buffer[renderBuffer][j + 1][i]); var currentP:Number3D = (Number3D)(buffer[renderBuffer][j - 1][i]); ((Number3D)(prev[i])).y = k1*((Number3D)(crnt[i])).y + k2*((Number3D)(prev[i])).y + k3*(((Number3D)(crnt[i+1])).y + ((Number3D)(crnt[i-1])).y + currentN.y + currentP.y); } } renderBuffer = 1-renderBuffer; } public function onEnterFrame(event:Event):void { light.copyPosition(camera); if(!isPause){ theta += 0.05; var verCounter:uint = 0; for(var x:int = 0 ; x < waterSegsXreal ; x++){ for(var z:int = 0 ; z < waterSegsYreal ; z++){ waterSurface.geometry.vertices[verCounter].z = buffer[renderBuffer][x][z].y * 3; verCounter++; } } evaluate(); for each(var face:Triangle3D in waterSurface.geometry.faces) face.createNormal(); for each(var vertex:Vertex3D in waterSurface.geometry.vertices) vertex.calculateNormal(); } rotateCamera(); singleRender(); } private function rotateCamera():void{ var x:Number = (stage.mouseX - stage.stageWidth/2) / 4; camera.moveLeft(x); var y:Number = (stage.mouseY - stage.stageHeight/2) / 6; camera.moveDown(y); if (camera.y > 1000 || camera.y < -200) camera.moveDown(-y); } public function keyUpHandler(e:KeyboardEvent):void { if (isChar(e.charCode, "1")) changeWaterMaterial(1); else if(isChar(e.charCode, "2")) changeWaterMaterial(2); else if (isChar(e.charCode, "3")) changeWaterMaterial(3); else if (isChar(e.charCode, "4")) changeWaterMaterial(4); else if (isChar(e.charCode, "0")) if(isPause == false) isPause = true; else isPause = false; } private function isChar(code:Number, str:String):Boolean{ if(code == str.charCodeAt()) return true; return false; }
For speed comparison i make it (just geometry) fluid on Away3D, i done equal FPS on both engines.
UPD:
Comments (7) 18.03.2008. 20:03
Comments (1) 12.03.2008. 23:21
Comments (1) 27.02.2008. 04:25