查看: 4002|回复: 0
打印 上一主题 下一主题

Away3D中的鼠标交互演示

[复制链接]

5472

主题

6

听众

1万

积分

版主

Rank: 7Rank: 7Rank: 7

纳金币
76544
精华
23

活跃会员 荣誉管理 突出贡献 优秀版主 论坛元老

跳转到指定楼层
楼主
发表于 2012-12-21 13:26:36 |只看该作者 |倒序浏览
本帖分享的是Away3D中的鼠标交互,摘录如下: 请点击效果截图观看全屏3D动画效果展示: package
{
        import away3d.bounds.*;
        import away3d.cameras.*;
        import away3d.containers.*;
        import away3d.controllers.*;
        import away3d.core.base.*;
        import away3d.core.pick.*;
        import away3d.debug.*;
        import away3d.entities.*;
        import away3d.events.*;
        import away3d.library.assets.*;
        import away3d.lights.*;
        import away3d.loaders.parsers.*;
        import away3d.materials.*;
        import away3d.materials.lightpickers.*;
        import away3d.primitives.*;
        import away3d.textures.*;        import flash.display.*;
        import flash.events.*;
        import flash.filters.*;
        import flash.geom.*;
        import flash.text.*;
        import flash.ui.*;        [SWF(backgroundColor="#000000", frameRate="60")]
        public class Intermediate_MouseInteraction extends Sprite
        {
                //signature swf
                [Embed(source="/../embeds/signature.swf", symbol="Signature")]
                public var SignatureSwf:Class;                //engine variables
                private var scene:Scene3D;
                private var camera:Camera3D;
                private var view:View3D;
                private var awayStats:AwayStats;
                private var cameraController:HoverController;                //signature variables
                private var Signature:Sprite;
                private var SignatureBitmap:Bitmap;                //light objects
                private var pointLightointLight;
                private var lightPicker:StaticLightPicker;                //material objects
                private var painter:Sprite;
                private var blackMaterial:ColorMaterial;
                private var whiteMaterial:ColorMaterial;
                private var grayMaterial:ColorMaterial;
                private var blueMaterial:ColorMaterial;
                private var redMaterial:ColorMaterial;                //scene objects
                private var text:TextField;
                private var pickingPositionTracer:Mesh;
                private var pickingNormalTracer:SegmentSet;
                private var head:Mesh;
                private var cubeGeometry:CubeGeometry;
                private var sphereGeometry:SphereGeometry;
                private var cylinderGeometry:CylinderGeometry;
                private var t***sGeometry:T***sGeometry;                //navigation variables
                private var move:Boolean = false;
                private var lastPanAngle:Number;
                private var lastTiltAngle:Number;
                private var lastMouseX:Number;
                private var lastMouseY:Number;
                private var tiltSpeed:Number = 4;
                private var panSpeed:Number = 4;
                private var distanceSpeed:Number = 4;
                private var tiltIncrement:Number = 0;
                private var panIncrement:Number = 0;
                private var distanceIncrement:Number = 0;                // Assets.
                [Embed(source="../embeds/head.obj", mimeType="application/octet-stream")]
                private var HeadAsset:Class;                private const PAINT_TEXTURE_SIZE:uint = 1024;                /**
                 * Cons***ctor
                 */
                public function Intermediate_MouseInteraction()
                {
                        init();
                }                /**
                 * Global initialise function
                 */
                private function init():void
                {
                        initEngine();
                        initText();
                        initLights();
                        initMaterials();
                        initObjects();
                        initListeners();
                }                /**
                 * Initialise the engine
                 */
                private function initEngine():void
                {
                        stage.scaleMode = StageScaleMode.NO_SCALE;
                        stage.align = StageAlign.TOP_LEFT;                        view = new View3D();
                        view.forceMouseMove = ***e;
                        scene = view.scene;
                        camera = view.camera;                        // Chose global picking method ( chose one ).
//                        view.mousePicker = PickingType.SHADER; // Uses the GPU, considers gpu animations, and suffers from Stage3D's drawToBitmapData()'s bottleneck.
//                        view.mousePicker = PickingType.RAYCAST_FIRST_ENCOUNTERED; // Uses the CPU, fast, but might be inaccurate with intersecting objects.
                        view.mousePicker = PickingType.RAYCAST_BEST_HIT; // Uses the CPU, guarantees accuracy with a little performance cost.                        //setup controller to be used on the camera
                        cameraController = new HoverController(camera, null, 180, 20, 320, 5);                        view.addSourceURL("srcview/index.html");
                        addChild(view);                        //add signature
                        Signature = Sprite(new SignatureSwf());
                        SignatureBitmap = new Bitmap(new BitmapData(Signature.width, Signature.height, ***e, 0));
                        stage.quality = StageQuality.HIGH;
                        SignatureBitmap.bitmapData.draw(Signature);
                        stage.quality = StageQuality.LOW;
                        addChild(SignatureBitmap);                        awayStats = new AwayStats(view);
                        addChild(awayStats);
                }                /**
                 * Create an ins***ctions overlay
                 */
                private function initText():void
                {
                        text = new TextField();
                        text.defaultTextFormat = new TextFormat("Verdana", 11, 0xFFFFFF);
                        text.width = 1000;
                        text.height = 200;
                        text.x = 25;
                        text.y = 50;
                        text.selectable = false;
                        text.mouseEnabled = false;
                        text.text = "Camera controls -----
";
                        text.text = "  Click and drag on the stage to rotate camera.
";
                        text.appendText("  Keyboard arrows and WASD also rotate camera and Z and X zoom camera.
");
                        text.appendText("icking -----
");
                        text.appendText("  Click on the head model to draw on its texture.
");
                        text.appendText("  Red objects have triangle picking precision.
" );
                        text.appendText("  Blue objects have bounds picking precision.
" );
                        text.appendText("  Gray objects are disabled for picking but occlude picking on other objects.
" );
                        text.appendText("  Black objects are completely ignored for picking.
" );
                        text.filters = [new DropshadowFilter(1, 45, 0x0, 1, 0, 0)];
                        addChild(text);
                }                /**
                 * Initialise the lights
                 */
                private function initLights():void
                {
                        //create a light for the camera
                        pointLight = new PointLight();
                        scene.addChild(pointLight);
                        lightPicker = new StaticLightPicker([pointLight]);
                }                /**
                 * Initialise the material
                 */
                private function initMaterials():void
                {
                        // uv painter
                        painter = new Sprite();
                        painter.graphics.beginFill( 0xFF0000 );
                        painter.graphics.drawCircle( 0, 0, 10 );
                        painter.graphics.endFill();                        // locator materials
                        whiteMaterial = new ColorMaterial( 0xFFFFFF );
                        whiteMaterial.lightPicker = lightPicker;
                        blackMaterial = new ColorMaterial( 0x333333 );
                        blackMaterial.lightPicker = lightPicker;
                        grayMaterial = new ColorMaterial( 0xCCCCCC );
                        grayMaterial.lightPicker = lightPicker;
                        blueMaterial = new ColorMaterial( 0x0000FF );
                        blueMaterial.lightPicker = lightPicker;
                        redMaterial = new ColorMaterial( 0xFF0000 );
                        redMaterial.lightPicker = lightPicker;
                }                /**
                 * Initialise the scene objects
                 */
                private function initObjects():void
                {
                        // To trace mouse hit position.
                        pickingPositionTracer = new Mesh( new SphereGeometry( 2 ), new ColorMaterial( 0x00FF00, 0.5 ) );
                        pickingPositionTracer.visible = false;
                        pickingPositionTracer.mouseEnabled = false;
                        scene.addChild(pickingPositionTracer);                        // To trace picking normals.
                        pickingNormalTracer = new SegmentSet();
                        pickingNormalTracer.mouseEnabled = pickingNormalTracer.mouseChildren = false;
                        var lineSegmentineSegment = new LineSegment( new Vector3D(), new Vector3D(), 0xFFFFFF, 0xFFFFFF, 3 );
                        pickingNormalTracer.addSegment( lineSegment );
                        pickingNormalTracer.visible = false;
                        view.scene.addChild( pickingNormalTracer );                        // Load a head model that we will be able to paint on on mouse down.
                        var parser:OBJParser = new OBJParser( 25 );
                        parser.addEventListener( AssetEvent.ASSET_COMPLETE, onAssetComplete );
                        parser.parseAsync( new HeadAsset() );                        // Produce a bunch of objects to be around the scene.
                        createABunchOfObjects();
                }                private function onAssetComplete( event:AssetEvent ):void {
                        if( event.asset.assetType == AssetType.MESH ) {
                                initializeHeadModel( event.asset as Mesh );
                        }
                }                private function initializeHeadModel( model:Mesh ):void {                        head = model;                        // Apply a bitmap material that can be painted on.
                        var bmd:BitmapData = new BitmapData( PAINT_TEXTURE_SIZE, PAINT_TEXTURE_SIZE, false, 0xFF0000 );
                        bmd.perlinNoise( 50, 50, 8, 1, false, ***e, 7, ***e );
                        var bitmapTexture:BitmapTexture = new BitmapTexture( bmd );
                        var textureMaterial:TextureMaterial = new TextureMaterial( bitmapTexture );
                        textureMaterial.lightPicker = lightPicker;
                        model.material = textureMaterial;                        // Set up a ray picking collider.
                        // The head model has quite a lot of triangles, so its best to use pixel bender for ray picking calculations.
                        // NOTE: Pixel bender will not produce faster results on devices with only one cpu core, and will not work on iOS.
                        model.pickingCollider = PickingColliderType.PB_BEST_HIT;
//                        model.pickingCollider = PickingColliderType.PB_FIRST_ENCOUNTERED; // is faster, but causes weirdness around the eyes                        // Apply mouse interactivity.
                        model.mouseEnabled = model.mouseChildren = model.shaderPickingDetails = ***e;
                        enableMeshMouseListeners( model );                        view.scene.addChild( model );
                }                private function createABunchOfObjects():void {                        cubeGeometry = new CubeGeometry( 25, 25, 25 );
                        sphereGeometry = new SphereGeometry( 12 );
                        cylinderGeometry = new CylinderGeometry( 12, 12, 25 );
                        t***sGeometry = new T***sGeometry( 12, 12 );                        for( var i:uint; i < 40; i++ ) {                                // Create object.
                                var object:Mesh = createSimpleObject();                                // Random orientation.
                                object.rotationX = 360 * Math.random();
                                object.rotationY = 360 * Math.random();
                                object.rotationZ = 360 * Math.random();                                // Random position.
                                var r:Number = 200 + 100 * Math.random();
                                var azimuth:Number = 2 * Math.PI * Math.random();
                                var elevation:Number = 0.25 * Math.PI * Math.random();
                                object.x = r * Math.cos(elevation) * Math.sin(azimuth);
                                object.y = r * Math.sin(elevation);
                                object.z = r * Math.cos(elevation) * Math.cos(azimuth);
                        }
                }                private function createSimpleObject():Mesh {                        var geometry:Geometry;
                        var bounds:BoundingVolumeBase;                        // Chose a random geometry.
                        var randGeometry:Number = Math.random();
                        if( randGeometry > 0.75 ) {
                                geometry = cubeGeometry;
                        }
                        else if( randGeometry > 0.5 ) {
                                geometry = sphereGeometry;
                                bounds = new BoundingSphere(); // better on spherical meshes with bound picking colliders
                        }
                        else if( randGeometry > 0.25 ) {
                                geometry = cylinderGeometry;                        }
                        else {
                                geometry = t***sGeometry;
                        }                        var mesh:Mesh = new Mesh(geometry);                        if (bounds)
                                mesh.bounds = bounds;                        // For shader based picking.
                        mesh.shaderPickingDetails = ***e;                        // Randomly decide if the mesh has a triangle collider.
                        var usesTriangleCollider:Boolean = Math.random() > 0.5;
                        if( usesTriangleCollider ) {
                                // AS3 triangle pickers for meshes with low poly counts are faster than pixel bender ones.
//                                mesh.pickingCollider = PickingColliderType.BOUNDS_ONLY; // this is the default value for all meshes
                                mesh.pickingCollider = PickingColliderType.AS3_FIRST_ENCOUNTERED;
//                                mesh.pickingCollider = PickingColliderType.AS3_BEST_HIT; // slower and more accurate, best for meshes with folds
//                                mesh.pickingCollider = PickingColliderType.AUTO_FIRST_ENCOUNTERED; // automatically decides when to use pixel bender or actionscript
                        }                        // Enable mouse interactivity?
                        var isMouseEnabled:Boolean = Math.random() > 0.25;
                        mesh.mouseEnabled = mesh.mouseChildren = isMouseEnabled;                        // Enable mouse listeners?
                        var listensToMouseEvents:Boolean = Math.random() > 0.25;
                        if( isMouseEnabled && listensToMouseEvents ) {
                                enableMeshMouseListeners( mesh );
                        }                        // Apply material according to the random setup of the object.
                        choseMeshMaterial( mesh );                        // Add to scene and store.
                        view.scene.addChild( mesh );                        return mesh;
                }                private function choseMeshMaterial( mesh:Mesh ):void {
                        if( !mesh.mouseEnabled ) {
                                mesh.material = blackMaterial;
                        }
                        else {
                                if( !mesh.hasEventListener( MouseEvent3D.MOUSE_MOVE ) ) {
                                        mesh.material = grayMaterial;
                                }
                                else {
                                        if( mesh.pickingCollider != PickingColliderType.BOUNDS_ONLY ) {
                                                mesh.material = redMaterial;
                                        }
                                        else {
                                                mesh.material = blueMaterial;
                                        }
                                }
                        }
                }                /**
                 * Initialise the listeners
                 */
                private function initListeners():void
                {
                        addEventListener(Event.ENTER_FRAME, onEnterFrame);
                        view.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
                        view.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
                        stage.addEventListener(Event.RESIZE, onResize);
                        stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
                        stage.addEventListener(KeyboardEvent.KEY_UP, onKeyUp);
                        onResize();
                }                /**
                 * Navigation and render loop
                 */
                private function onEnterFrame(event:Event):void
                {
                        // Update camera.
                        if (move) {
                                cameraController.panAngle = 0.3*(stage.mouseX - lastMouseX) + lastPanAngle;
                                cameraController.tiltAngle = 0.3*(stage.mouseY - lastMouseY) + lastTiltAngle;
                        }
                        cameraController.panAngle += panIncrement;
                        cameraController.tiltAngle += tiltIncrement;
                        cameraController.distance += distanceIncrement;                        // Move light with camera.
                        pointLight.position = camera.position;                        // Render 3D.
                        view.render();
                }                /**
                 * Key down listener for camera control
                 */
                private function onKeyDown(event:KeyboardEvent):void
                {
                        switch (event.keyCode) {
                                case Keyboard.UP:
                                case Keyboard.W:
                                        tiltIncrement = tiltSpeed;
                                        break;
                                case Keyboard.DOWN:
                                case Keyboard.S:
                                        tiltIncrement = -tiltSpeed;
                                        break;
                                case Keyboard.LEFT:
                                case Keyboard.A:
                                        panIncrement = panSpeed;
                                        break;
                                case Keyboard.RIGHT:
                                case Keyboard.D:
                                        panIncrement = -panSpeed;
                                        break;
                                case Keyboard.Z:
                                        distanceIncrement = distanceSpeed;
                                        break;
                                case Keyboard.X:
                                        distanceIncrement = -distanceSpeed;
                                        break;
                        }
                }                /**
                 * Key up listener for camera control
                 */
                private function onKeyUp(event:KeyboardEvent):void
                {
                        switch (event.keyCode) {
                                case Keyboard.UP:
                                case Keyboard.W:
                                case Keyboard.DOWN:
                                case Keyboard.S:
                                        tiltIncrement = 0;
                                        break;
                                case Keyboard.LEFT:
                                case Keyboard.A:
                                case Keyboard.RIGHT:
                                case Keyboard.D:
                                        panIncrement = 0;
                                        break;
                                case Keyboard.Z:
                                case Keyboard.X:
                                        distanceIncrement = 0;
                                        break;
                        }
                }                /**
                 * Mouse stage leave listener for navigation
                 */
                private function onStageMouseLeave(event:Event):void
                {
                        move = false;
                        stage.removeEventListener(Event.MOUSE_LEAVE, onStageMouseLeave);
                }                /**
                 * stage listener for resize events
                 */
                private function onResize(event:Event = null):void
                {
                        view.width = stage.stageWidth;
                        view.height = stage.stageHeight;
                        SignatureBitmap.y = stage.stageHeight - Signature.height;
                        awayStats.x = stage.stageWidth - awayStats.width;
                }                /**
                 * Mouse up listener for navigation
                 */
                private function onMouseUp(event:MouseEvent):void
                {
                        move = false;
                        stage.removeEventListener(Event.MOUSE_LEAVE, onStageMouseLeave);
                }                /**
                 * Mouse down listener for navigation
                 */
                private function onMouseDown(event:MouseEvent):void
                {
                        move = ***e;
                        lastPanAngle = cameraController.panAngle;
                        lastTiltAngle = cameraController.tiltAngle;
                        lastMouseX = stage.mouseX;
                        lastMouseY = stage.mouseY;
                        stage.addEventListener(Event.MOUSE_LEAVE, onStageMouseLeave);
                }                // ---------------------------------------------------------------------
                // 3D mouse event handlers.
                // ---------------------------------------------------------------------                protected function enableMeshMouseListeners( mesh:Mesh ):void {
                        mesh.addEventListener( MouseEvent3D.MOUSE_OVER, onMeshMouseOver );
                        mesh.addEventListener( MouseEvent3D.MOUSE_OUT, onMeshMouseOut );
                        mesh.addEventListener( MouseEvent3D.MOUSE_MOVE, onMeshMouseMove );
                        mesh.addEventListener( MouseEvent3D.MOUSE_DOWN, onMeshMouseDown );
                }                /**
                 * mesh listener for mouse down interaction
                 */
                private function onMeshMouseDown( event:MouseEvent3D ):void {
                        var mesh:Mesh = event.object as Mesh;
                        // Paint on the head&#39;s material.
                        if( mesh == head ) {
                                var uvoint = event.uv;
                                var textureMaterial:TextureMaterial = Mesh( event.object ).material as TextureMaterial;
                                var bmd:BitmapData = BitmapTexture( textureMaterial.texture ).bitmapData;
                                var x:uint = uint( PAINT_TEXTURE_SIZE * uv.x );
                                var y:uint = uint( PAINT_TEXTURE_SIZE * uv.y );
                                var matrix:Matrix = new Matrix();
                                matrix.translate( x, y );
                                bmd.draw( painter, matrix );
                                BitmapTexture( textureMaterial.texture ).invalidateContent();
                        }
                }                /**
                 * mesh listener for mouse over interaction
                 */
                private function onMeshMouseOver(event:MouseEvent3D):void
                {
                        var mesh:Mesh = event.object as Mesh;
                        mesh.showBounds = ***e;
                        if( mesh != head ) mesh.material = whiteMaterial;
                        pickingPositionTracer.visible = pickingNormalTracer.visible = ***e;
                        onMeshMouseMove(event);
                }                /**
                 * mesh listener for mouse out interaction
                 */
                private function  onMeshMouseOut(event:MouseEvent3D):void
                {
                        var mesh:Mesh = event.object as Mesh;
                        mesh.showBounds = false;
                        if( mesh != head ) choseMeshMaterial( mesh );
                        pickingPositionTracer.visible = pickingNormalTracer.visible = false;
                        pickingPositionTracer.position = new Vector3D();
                }                /**
                 * mesh listener for mouse move interaction
                 */
                private function  onMeshMouseMove(event:MouseEvent3D):void
                {
                        // Show tracers.
                        pickingPositionTracer.visible = pickingNormalTracer.visible = ***e;                        // Update position tracer.
                        pickingPositionTracer.position = event.scenePosition;                        // Update normal tracer.
                        pickingNormalTracer.position = pickingPositionTracer.position;
                        var normal:Vector3D = event.sceneNormal.clone();
                        normal.scaleBy( 25 );
                        var lineSegmentineSegment = pickingNormalTracer.getSegment( 0 ) as LineSegment;
                        lineSegment.end = normal.clone();
                }
        }
}  
分享到: QQ好友和群QQ好友和群 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
转播转播0 分享淘帖0 收藏收藏0 支持支持0 反对反对0
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

手机版|纳金网 ( 闽ICP备2021016425号-2/3

GMT+8, 2025-2-11 14:14 , Processed in 0.083862 second(s), 32 queries .

Powered by Discuz!-创意设计 X2.5

© 2008-2019 Narkii Inc.

回顶部