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 (0) 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 (2) 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 (2) 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 (6) 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 (5) 18.03.2008. 20:03
Comments (1) 12.03.2008. 23:21
Comments (1) 27.02.2008. 04:25