package geometry.basics { import away3d.core.base.SubGeometry; import away3d.core.math.Vector3DUtils; import away3d.entities.Mesh; import away3d.events.LoaderEvent; import away3d.loaders.Loader3D; import away3d.loaders.misc.AssetLoaderContext; import away3d.loaders.parsers.OBJParser; import away3d.materials.BitmapMaterial; import away3d.primitives.Sphere; import flash.display.BitmapData; import flash.events.Event; import flash.geom.Vector3D; import flash.utils.getTimer; /** * @author Nicolas Barradeau * http://en.nicoptere.net */ public class G_Deformation extends BaseScene { [Embed(source="../../../lib/res/models/windmill/windmill.obj", mimeType="application/octet-stream")] private var OBJ:Class; [Embed(source="../../../lib/res/models/windmill/windmill.jpg")] private var source:Class; private var texture:BitmapData = new source().bitmapData; private var _loader:Loader3D; private var mesh:Mesh; private var vertices:Vector.; private var origins:Vector.; private var subGeometry:SubGeometry; private var sphere:Vector3D = new Vector3D( 100, 100, 100 ); private var radius:Number = 250; private var sphereMesh:Sphere; public function G_Deformation():void { addChild( GlobalTextField.instance ); GlobalTextField.instance.htmlText = '

the windmill model & texture is a courtesy of Raphaƫl Kuntz\na talented 3D artist, his website is here: http://visu.kuntz.tv/

' ; var size:uint = 256, color:uint = 0xFF000000, backgroundColor:uint = 0xFFFFFFFF; setup(); Loader3D.enableParser(OBJParser); _loader = new Loader3D(); _loader.addEventListener(LoaderEvent.RESOURCE_COMPLETE, onResourceComplete); _loader.loadData( OBJ, new AssetLoaderContext(false), null ); addChild( GlobalTextField.instance ); } private function onResourceComplete(e:LoaderEvent):void { var model:Mesh = Mesh(_loader.getChildAt(0)); model.material = new BitmapMaterial( texture ); model.material.lights = lights; addMesh( model ); model.scale( .5 ); subGeometry = model.geometry.subGeometries[ 0 ]; vertices = subGeometry.vertexData.concat(); origins = vertices.concat(); //make mesh double sided subGeometry.updateIndexData( subGeometry.indexData.concat( subGeometry.indexData.concat().reverse() ) ); //create a debug sphere sphereMesh = new Sphere( RED, radius * .5, 32, 16 ); addMesh( sphereMesh ); RED.alpha = .1; addEventListener( Event.ENTER_FRAME, oef ); } private function oef(e:Event):void { var t:Number = ( getTimer() * .01 ) / 180 * Math.PI; //move the sphere sphere.x = Math.cos( t ) * 250; sphere.y = Math.sin( t/5 )* 50; sphere.z = Math.sin( t ) * 250; for (var i:int = 0; i < vertices.length; i+= 3 ) { var o:Vector3D = new Vector3D( origins[ i ], origins[ i + 1 ], origins[ i + 2 ] ); //if the vertex is under a given radius from the sphere var dist:Number = Vector3D.distance( o, sphere ); if ( dist < radius ) { //move it var diff:Vector3D = o.subtract( sphere ); diff.normalize(); diff.scaleBy( radius ); o = diff.add( sphere ); } vertices[ i ] = o.x; vertices[ i + 1 ] = o.y; vertices[ i + 2 ] = o.z; } //update geometry subGeometry.updateVertexData( vertices ); //position debug sphere sphere.scaleBy( .5 ); sphereMesh.position = sphere; } } }