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); } } }