Un test utilisant les "modifiers" (je ne sais pas comment ça se dit en français) cloth et twist de la bibliothèque as3mod.




La classe :
package {
	
	import caurina.transitions.Tweener;
	
	import com.as3dmod.ModifierStack;
	import com.as3dmod.modifiers.Cloth;
	import com.as3dmod.modifiers.Twist;
	import com.as3dmod.plugins.pv3d.LibraryPv3d;
	
	import flash.display.BitmapData;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.utils.getDefinitionByName;
	
	import org.papervision3d.cameras.Camera3D;
	import org.papervision3d.materials.BitmapMaterial;
	import org.papervision3d.objects.DisplayObject3D;
	import org.papervision3d.objects.primitives.Cylinder;
	import org.papervision3d.objects.primitives.Plane;
	import org.papervision3d.render.BasicRenderEngine;
	import org.papervision3d.scenes.Scene3D;
	import org.papervision3d.view.Viewport3D;
	
	public class ClothEffect extends Sprite {

		private var _view:Viewport3D;
		private var _camera:Camera3D;
		private var _scene:Scene3D;
		private var _renderer:BasicRenderEngine;
		private var _flag:DisplayObject3D;
		private var _modifierStack:ModifierStack;
		private var _cloth:Cloth;
		private var _twist:Twist;
		private var _wind:Number=2;
		private var _windDirection:Number=1;
		private var _windVariation:Number=2;
		private var _background:Class;
		private var _flagAsset:BitmapData;
		private var _woodAsset:BitmapData;

		private var _angle:Number = 3;

		public function ClothEffect():void {

			// initialize libraries
			initPV3D();
			initAS3DMod();

			addEventListener(Event.ENTER_FRAME, handleEnterFrame);

			tweenA();
		}



		private function initPV3D():void {

			var bmp:BitmapData;
			var material:BitmapMaterial;
			var pole:Cylinder;

			// create basic scene setup
			_scene=new Scene3D();
			_view=new Viewport3D(800, 600);
			//_view.y=-100;
			_renderer=new BasicRenderEngine();
			_camera=new Camera3D();
			_camera.zoom = 90;
			
			// create the flag
			var classRef2:Class=getDefinitionByName("Flag") as Class;
			_flagAsset=new classRef2(600, 400);

			bmp=_flagAsset;
			material=new BitmapMaterial(bmp);
			_flag=new Plane(material, 500, 400, 15, 20);
			_flag.material.doubleSided=true;
			_scene.addChild(_flag);

			_camera.target=_flag;

			addChild(_view);
		}



		private function initAS3DMod():void {

			// create the modifier stack and assing it to the flag

			_modifierStack=new ModifierStack(new LibraryPv3d(), _flag);
			_cloth=new Cloth();
			_modifierStack.addModifier(_cloth);
			_twist = new Twist();
			_modifierStack.addModifier(_twist);

			// sets the left side of the flag as immobile
			_cloth.lockXMax(20);
			_cloth.lockXMin(0);
			_cloth.lockYMax(20);
			_cloth.lockYMin(0);
		}

		private function tweenA():void {
			
			var X:Number = Math.sin(_windDirection) * _wind - Math.random() * _windVariation;
			var Z:Number = Math.cos(_windDirection) * _wind - Math.random() * _windVariation;
			
			var rX:Number = Math.random() *  (400);
			var rY:Number = Math.random() * (400);
			var rZ:Number = Math.random() * (400);
			var rYY:Number = Math.random() * (45);
			
			_angle = (_angle == 30 ? -30 : 30); 
			
			Tweener.addTween(_twist, {angle:_angle, time:2, transition:"easeInOutElastic"});
			Tweener.addTween(_flag, {rotationY:rYY, x:rX, y:rY, z:rZ, time:2, transition:"easeInOutElastic", onComplete:tweenC});
			Tweener.addTween(_cloth, {forceX:X, forceZ:Z, time:2, transition:"easeInOutElastic"});
			
		}
		
		private function tweenC():void {
			//trace("tweenC");
			
			var rX:Number = Math.random() *  (-400);
			var rY:Number = Math.random() * (-400);
			var rZ:Number = Math.random() * (-400);
			var rYY:Number = Math.random() * (45);
			
			Tweener.addTween(_twist, {angle:0, time:2, transition:"easeInOutElastic"});
			Tweener.addTween(_flag, {rotationY:rYY, x:rX, y:rY, z:rZ, time:2, transition:"easeInOutElastic", onComplete:tweenA});
		}

		private function handleEnterFrame(event:Event):void {
			
			var halfW:Number=stage.stageWidth * .5,
				halfH:Number=stage.stageHeight * .5;
		
			var cameraAngle:Number=(0.1 + mouseX / halfW - halfW) * 1.3;
			
			// applies the modifier and updates the cloth simulation
			_modifierStack.apply();
			
			// render the scene
			_renderer.renderScene(_scene, _camera, _view);
		}
	}
}