<?xml version="1.0"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script>
<![CDATA[
[Embed(source = "../assets/alternativa3d_small.png")] [Bindable] public var Logo:Class;
import alternativa.engine3d.core.Mesh;
import alternativa.engine3d.core.Object3D;
import alternativa.engine3d.loaders.Loader3DS;
import alternativa.engine3d.loaders.LoaderOBJ;
import alternativa.engine3d.materials.TextureMaterialPrecision;
import alternativa.utils.MeshUtils;
import flash.display.Sprite;
import flash.events.Event;
import flash.filesystem.File;
import flash.net.FileFilter;
private var loader3ds:Loader3DS;
private var loaderObj:LoaderOBJ;
private var openFile:File = new File();
private var verticesNum:int;
private var facesNum:int;
private function onLoad3DModelClick():void{
openFile.addEventListener(Event.SELECT, onOpenFileComplete);
openFile.browseForOpen("Open 3D model", [new FileFilter("3D model file (*.3ds,*.obj)", "*.3ds;*.obj;", "3DS;OBJ;")]);
}
private function onOpenFileComplete(event:Event):void {
var path:String = event.target.nativePath.replace(/\\/g, "/");
if (openFile.extension == "3ds") {
loader3ds = new Loader3DS();
loader3ds.smooth = true;
loader3ds.precision = TextureMaterialPrecision.HIGH;
loader3ds.addEventListener(Event.COMPLETE, onLoadingComplete);
loader3ds.load(path);
}else if (openFile.extension == "obj") {
loaderObj = new LoaderOBJ();
loaderObj.smooth = true;
loaderObj.precision = TextureMaterialPrecision.HIGH;
loaderObj.addEventListener(Event.COMPLETE, onLoadingComplete);
loaderObj.load(path);
}
}
private function onLoadingComplete(e:Event):void {
var pkg:String = "my.package";
outputField.text = "";
verticesNum = facesNum = 0;
//go through each part of the model
var loader:* = openFile.extension == "3ds" ? loader3ds : loaderObj
for (var o:* in loader.content.children) {
var object:Object3D = o;
weldVerticesAndFaces(object);
//output an ActionScript class from the mesh
if (object is Mesh) {
outputField.text += MeshUtils.generateClass(Mesh(object), pkg) + "\n\n";
verticesNum += Mesh(object).vertices.length;
facesNum += Mesh(object).faces.length;
}
}
geometryStatLabel.text = "Vertices: " + verticesNum + " Faces: " + facesNum;
}
// Optimizing object geometry
private function weldVerticesAndFaces(object:Object3D):void {
if (object is Mesh) {
MeshUtils.autoWeldVertices(Mesh(object), 0.01);
MeshUtils.autoWeldFaces(Mesh(object), 0.01, 0.001);
}
// Launching procedure for object's children
for (var key:* in object.children) {
weldVerticesAndFaces(key);
}
}
]]>
</mx:Script>
<mx:HBox paddingLeft="200">
<mx:Button label="Load 3D Model" click="onLoad3DModelClick()"/>
<mx:Label id="geometryStatLabel" width="200" paddingTop="2" />
</mx:HBox>
<mx:TextArea width = "100%" height = "100%" id = "outputField" / >
<mx:Image source="{Logo}" />
</mx:WindowedApplication>
UPD: Added vertices and face counter
UPD2: Oops! I wasn't first who made AIR exporter, just found Alternativa Class Generating AIR App by Chris Rebstock
05.04.2009. 04:46
Google maps added under the layer with papervision3d and rotating by Flash 10 3D API (but it's very slow), it's impossible to use maps as material. Please vote for issue to remove security sandbox violation on BitmapData.draw()
Key differences with pv3d.org example in enterFrameHandler()
[Embed(source="../assets/Focus.dae", mimeType = "application/octet-stream")] private var carAsset:Class;
[Embed(source="../assets/wheel.jpg")] private var wheelBitmapAsset:Class;
[Embed(source = "../assets/body.jpg")] private var bodyBitmapAsset:Class;
private var car:DAE;
private var focusMaterials:MaterialsList;
private var viewport:Viewport3D;
private var scene:Scene3D;
private var camera:SpringCamera3D;
private var renderer:BasicRenderEngine;
private var topSpeed:Number = 0;
private var topSteer:Number = 0;
private var speed:Number = 0;
private var steer:Number = 0;
private var keyRight:Boolean = false;
private var keyLeft:Boolean = false;
private var keyForward:Boolean = false;
private var keyReverse:Boolean = false;
private var gmaps:Map;
//for maps 3d transformations
private var mapContainer:Sprite;
private var mapRotationContainer:Sprite;
private var prevDistX:Number = 0;
private var prevDistZ:Number = 0;
private var startPlane:Plane;
[SWF(width=700, height=500, backgroundColor=0x343434, frameRate=25)]
public function Main() {
initMap();
init3D();
}
private function initMap():void {
gmaps = new Map();
//gmaps.key = ""
gmaps.setSize( new Point( 512, 512 ) );
gmaps.addEventListener( MapEvent.MAP_READY, mapReadyHandler );
gmaps.cacheAsBitmap = true
mapContainer = new Sprite()
addChild(mapContainer)
mapContainer.addChild( gmaps );
mapContainer.rotationX = -50;
mapContainer.cacheAsBitmap = true
mapRotationContainer = new Sprite()
mapRotationContainer.graphics.drawRect( -512, -512, 1024, 1024)
gmaps.scaleX = gmaps.scaleY = 2
gmaps.x = -512
gmaps.y = -512
mapRotationContainer.addChild(gmaps)
mapRotationContainer.x = 350
mapRotationContainer.y = 410
//uncomment for displaying the center of map rotation
//var center:Sprite = new Sprite()
//center.graphics.beginFill(0xff0000)
//center.graphics.drawRect( -10, -10, 20, 20)
//mapRotationContainer.addChild(center)
mapContainer.addChild(mapRotationContainer)
}
private function mapReadyHandler(e:Event):void {
var type:IMapType = MapType.SATELLITE_MAP_TYPE;
var latlng:LatLng = new LatLng( 48.873659 , 2.295764 );
gmaps.setCenter( latlng, 17, type );
this.addEventListener( Event.ENTER_FRAME, enterFrameHandler );
stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown)
stage.addEventListener(KeyboardEvent.KEY_UP, onKeyUp)
}
private function init3D():void {
viewport = new Viewport3D(700, 500);
scene = new Scene3D();
this.addChild(viewport);
startPlane = new Plane(new WireframeMaterial(0x77ee77), 10, 10);
startPlane.rotationX = 90
scene.addChild(startPlane);
camera = new SpringCamera3D(50);
camera.mass = 10;
camera.damping = 10;
camera.stiffness = 2;
camera.lookOffset = new Number3D(0, 0, 10);
camera.positionOffset = new Number3D(0, 25, -40);
camera.near = -10000;
renderer = new BasicRenderEngine();
addChild(new Stats())
//Setup materials for the object
var wheelBitmap:Bitmap = new wheelBitmapAsset() as Bitmap;
var bodyBitmap:Bitmap = new bodyBitmapAsset() as Bitmap;
var bodyMaterial:BitmapMaterial = new BitmapMaterial(bodyBitmap.bitmapData);
bodyMaterial.smooth = true;
var wheelMaterial:BitmapMaterial = new BitmapMaterial(wheelBitmap.bitmapData);
wheelMaterial.smooth = true;
focusMaterials = new MaterialsList();
focusMaterials.addMaterial(bodyMaterial, "materialBody");
focusMaterials.addMaterial(wheelMaterial, "materialWheel");
// Load Collada
var byteArray:ByteArray = new carAsset() as ByteArray;
car = new DAE(true);
car.load(byteArray, focusMaterials);
car.scale = 6;
car.useClipping = false;
camera.target = car;
scene.addChild(car);
}
/// HANDLERS
private function enterFrameHandler(e:Event):void {
//pan google maps
var dx:Number = car.x - startPlane.x
var dz:Number = car.z - startPlane.z
gmaps.panBy( new Point(-(prevDistX - dx), (prevDistZ-dz)));
prevDistX = dx
prevDistZ = dz
//rotate google maps
if(car.rotationX == 0) mapRotationContainer.rotationZ = 360-(car.rotationY)
else if (car.rotationX == 180) mapRotationContainer.rotationZ = -(180-car.rotationY)
if( car ) {
// Calculate current steer and speed
driveCar();
// Update car model
updateCar();
}
renderer.renderScene( scene, camera, viewport );
}
private function updateCar():void {
// Steer front wheels
var steerFR :DisplayObject3D = car.getChildByName( "Steer_FR", true );
var steerFL :DisplayObject3D = car.getChildByName( "Steer_FL", true );
steerFR.rotationY = -steer;
steerFL.rotationY = -steer;
// Rotate wheels
var wheelFR :DisplayObject3D = steerFR.getChildByName( "Wheel_FR", true );
var wheelFL :DisplayObject3D = steerFL.getChildByName( "Wheel_FL", true );
var wheelRR :DisplayObject3D = car.getChildByName( "Wheel_RR", true );
var wheelRL :DisplayObject3D = car.getChildByName( "Wheel_RL", true );
var roll :Number = speed * 2;
wheelFR.roll( -roll );
wheelRR.roll( -roll );
wheelFL.roll( roll );
wheelRL.roll( roll );
// Steer car
car.yaw( speed * steer / 500 );
// Move car
car.moveForward( speed );
}
private function driveCar():void {
// Speed
if( keyForward )
{
topSpeed = 9;
}
else if( keyReverse )
{
topSpeed = -3;
}
else
{
topSpeed = 0;
}
speed -= ( speed - topSpeed ) / 10;
// Steer
if( keyRight )
{
if( topSteer < 45 )
{
topSteer += 1.5;
}
}
else if( keyLeft )
{
if( topSteer > -45 )
{
topSteer -= 1.5;
}
}
else
{
topSteer -= topSteer / 24;
}
steer -= ( steer - topSteer ) / 2;
}
private function onKeyDown( event :KeyboardEvent ):void {
switch( event.keyCode )
{
case "W".charCodeAt():
case Keyboard.UP:
keyForward = true;
keyReverse = false;
break;
case "S".charCodeAt():
case Keyboard.DOWN:
keyReverse = true;
keyForward = false;
break;
case "A".charCodeAt():
case Keyboard.LEFT:
keyLeft = true;
keyRight = false;
break;
case "D".charCodeAt():
case Keyboard.RIGHT:
keyRight = true;
keyLeft = false;
break;
}
}
private function onKeyUp( event :KeyboardEvent ):void {
switch( event.keyCode )
{
case "W".charCodeAt():
case Keyboard.UP:
keyForward = false;
break;
case "S".charCodeAt():
case Keyboard.DOWN:
keyReverse = false;
break;
case "A".charCodeAt():
case Keyboard.LEFT:
keyLeft = false;
break;
case "D".charCodeAt():
case Keyboard.RIGHT:
keyRight = false;
break;
case Keyboard.TAB:
if ( gmaps.getCurrentMapType() == MapType.SATELLITE_MAP_TYPE ) gmaps.setMapType( MapType.NORMAL_MAP_TYPE );
else if ( gmaps.getCurrentMapType() == MapType.NORMAL_MAP_TYPE ) gmaps.setMapType( MapType.HYBRID_MAP_TYPE );
else if ( gmaps.getCurrentMapType() == MapType.HYBRID_MAP_TYPE ) gmaps.setMapType( MapType.PHYSICAL_MAP_TYPE );
else if ( gmaps.getCurrentMapType() == MapType.PHYSICAL_MAP_TYPE ) gmaps.setMapType( MapType.SATELLITE_MAP_TYPE );
break;
case 187: // +
gmaps.zoomIn();
break;
case 189: // -
gmaps.zoomOut();
break;
}
}
Comments (3) 16.02.2009. 00:00
Drag points to change curve:
This example based on bezier Demo #8. Just small modification:
private function redraw ():void {
<...>
segmentCenters = new Array();
var segmentsNum:uint = 10
var times:Array = bezier.getTimesSequence(20)
for (var i:int = 1; i < times.length; i++) {
var p1:Point = bezier.getPoint(times[i - 1]);
var p2:Point = bezier.getPoint(times[i]);
drawSegment2D(p1, p2)
}
drawSegment2D(bezier.getPoint(times[i - 1]), bezier.end)
}
private function drawSegment2D(p1:Point, p2:Point):void {
var dx:Number = p2.x - p1.x
var dy:Number = p2.y - p1.y
//calculate rotation
var angle:Number = Math.atan2(dy, dx) * Number3D.toDEGREES
//calculate width of segment
var distance:Number = Math.sqrt(dx * dx + dy * dy)
//and center position
var cx:int = p1.x + dx/2
var cy:int = p1.y + dy / 2
segmentCenters.push(new Segment2D(new Point(cx, cy), distance, angle));
}
And create planes from each segment:
var seg:Segment2D = bezierView.segmentCenters[i]
var plane:Plane = new Plane(new MaterialObject3D(), seg.length * propMult * 0.9, 100, 0, 0);
//create extruded plane (Extruder class by J-roen http://www.j-roen.net/papervision/2008/06/12/tutorial-7-vertexes/)
var depth:Number = 10;
var fMat:MaterialObject3D = new ColorMaterial(0xfffcdf);
var sMat:ColorMaterial = new ColorMaterial(0xbfbca2);
var mList:MaterialsList = new MaterialsList( { front: fMat, back: fMat, side: sMat } );
var p1:Point = new Point(plane.geometry.vertices[0].x, plane.geometry.vertices[0].y)
var p2:Point = new Point(plane.geometry.vertices[1].x, plane.geometry.vertices[1].y)
var p3:Point = new Point(plane.geometry.vertices[2].x, plane.geometry.vertices[2].y)
var p4:Point = new Point(plane.geometry.vertices[3].x, plane.geometry.vertices[3].y)
var extrudedPlane:DisplayObject3D = new Extruder( mList, [p1, p2, p4, p3], depth )
//add our extrudedPlane for scene
extrudedPlane.rotationY = -seg.angle
extrudedPlane.x = seg.center.x
extrudedPlane.z = seg.center.y
scene.addChild(extrudedPlane)
I'm also use here new QuadrantRenderEngine because with ViewportLayers when rotating camera happens overlaps. Quaternion rotating for rolling ball from Dragging in 3D - The Right Way.
Get Full SourceComments (3) 21.10.2008. 03:24
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