Sealyu

          --- 博客已遷移至: http://www.sealyu.com/blog

            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
            618 隨筆 :: 87 文章 :: 225 評論 :: 0 Trackbacks
          上一課主要學習基本3D交互場景事件的用法,這一課記錄高級用法~!

              我以旋轉的立方體為例,3D場景中有一個立方體,立方體的6個面每一個面都有一幅圖(貼圖),當鼠標點擊其中的任一面時,緩動放大,再點擊時緩動縮小恢復原狀繼續旋轉。效果圖如下:

          鼠標未點擊時不斷旋轉的立方體效果

          鼠標點擊時緩動放大效果

             效果代碼如下:

           

           package 
          {
           
             
              import flash.display.DisplayObject;
              import org.papervision3d.materials.BitmapFileMaterial;
              import org.papervision3d.materials.utils.MaterialsList;
              import org.papervision3d.events.InteractiveScene3DEvent;
              import org.papervision3d.objects.primitives.Cube;
             
              public class MainAdvancedInteractiveScene3dEvent extends PaperBase
           {
                 //---------------------------------------------------------------6個面對應的material
                 private var frontMaterial:BitmapFileMaterial = new BitmapFileMaterial("img/concretetex02.jpg");
                 private var backMaterial:BitmapFileMaterial = new BitmapFileMaterial("img/concretetex03.jpg");
                 private var leftMaterial:BitmapFileMaterial = new BitmapFileMaterial("img/bashi.jpg");
              private var rightMaterial:BitmapFileMaterial = new BitmapFileMaterial("img/pic12.jpg");
                 private var topMaterial:BitmapFileMaterial = new BitmapFileMaterial("img/pic37.jpg");
                 private var bottomMaterial:BitmapFileMaterial = new BitmapFileMaterial("img/pic43.jpg");
                
              //---------------------------------------------------------------目標旋轉初始值
                 private var targetrotationX:Number = 0;
                 private var targetrotationY:Number = 0;
                 private var targetrotationZ:Number = 0;
                
              //---------------------------------------------------------------判斷是否緩動
                 private var tweening:Boolean = false;
                
                 private var cube:Cube;
                
                 public function MainAdvancedInteractiveScene3dEvent()
              {
                   init(550, 400);
                 }
                
                 override protected function init3d():void
              {
                   frontMaterial.interactive = true;
                   frontMaterial.name = "front";
            
                   backMaterial.interactive = true;
                   backMaterial.name = "back";
            
                   leftMaterial.interactive = true;
                   leftMaterial.name = "left";
            
                   rightMaterial.interactive = true;
                   rightMaterial.name = "right";
            
                   topMaterial.interactive = true;
                   topMaterial.name = "top";
            
                   bottomMaterial.interactive = true;
                   bottomMaterial.name = "bottom";        
             //------------------------------------------------------------Cube
                   cube = new Cube(new MaterialsList(
             {
                        front: frontMaterial,
                        back: backMaterial,
                        left: leftMaterial,
                        right: rightMaterial,
                        top: topMaterial,
                        bottom: bottomMaterial
                      } ), 500, 500, 500, 3, 3, 3);
                   cube.addEventListener( InteractiveScene3DEvent.OBJECT_PRESS, onPress);
                   default_scene.addChild(cube);
            }
                
                 private function onPress( e:InteractiveScene3DEvent ):void
              {
                   if (tweening)
             {
                        tweening = false;
                   }
             else
             {
                        switch(e.face3d.material.name)
               {
                            case "front":
                               targetrotationX = 0;
                               targetrotationY = 180;
                               targetrotationZ = 0;
                               tweening = true;
                            break;
                            case "back":
                               targetrotationX = 0;
                               targetrotationY = 0;
                               targetrotationZ = 0;
                               tweening = true;
                            break;
                            case "left":
                               targetrotationX = 0;
                               targetrotationY = -90;
                               targetrotationZ = 0;
                               tweening = true;
                            break;
                            case "right":
                               targetrotationX = 0;
                               targetrotationY = 90;
                               targetrotationZ = 0;
                               tweening = true;
                            break;
                            case "top":
                               targetrotationX = 90;
                               targetrotationY = 0;
                               targetrotationZ = 0;
                               tweening = true;
                            break;
                            case "bottom":
                               targetrotationX = -90;
                               targetrotationY = 0;
                               targetrotationZ = 180;
                               tweening = true;
                            break;
              }
             }
            }
                
                 override protected function processFrame():void
              {
                   if (tweening)
             {
                        if (default_camera.zoom < 6.8)
               {
                            default_camera.zoom += Math.sqrt(6.8-default_camera.zoom)/5;
                        }
                       
                        //X
                        if (cube.rotationX < targetrotationX)
               {
                            cube.rotationX += Math.sqrt(targetrotationX-cube.rotationX);
                            cube.rotationX = Math.round(cube.rotationX);
                        }else if (cube.rotationX > targetrotationX)
               {
                            cube.rotationX -= Math.sqrt(cube.rotationX-targetrotationX);
                            cube.rotationX = Math.round(cube.rotationX);
                        }
               //Y
                        if (cube.rotationY < targetrotationY)
               {
                            cube.rotationY += Math.sqrt(targetrotationY-cube.rotationY);
                            cube.rotationY = Math.round(cube.rotationY);
                        }else if (cube.rotationY > targetrotationY)
               {
                            cube.rotationY -= Math.sqrt(cube.rotationY-targetrotationY);
                            cube.rotationY = Math.round(cube.rotationY);
                        }
               //Z
                        if (cube.rotationZ < targetrotationZ)
               {
                            cube.rotationZ += Math.sqrt(targetrotationZ-cube.rotationZ);
                            cube.rotationZ = Math.round(cube.rotationZ);
                        }else if (cube.rotationZ > targetrotationZ)
               {
                            cube.rotationZ -= Math.sqrt(cube.rotationZ-targetrotationZ);
                            cube.rotationZ = Math.round(cube.rotationZ);
                        }
             }
             //
             else
             {
                        if (default_camera.zoom > 2)
               {
                            default_camera.zoom -= Math.sqrt(default_camera.zoom-2)/5;
                        }
                       
                        cube.rotationX += 2;
                        cube.rotationY += 2;
                       
                        if (cube.rotationX>= 360) cube.rotationX = 0;
                        if (cube.rotationY>= 360) cube.rotationY = 0;
                   }
                 }
              }
          }

           

              代碼比較長,關鍵處已加以說明~!

              這段代碼依然是有關InteractiveScene3DEvent類的用法,由于立方體有6個面,為了顯示每個面的不同,采用了6張圖片做貼圖;為了能讓立方體的每個面都能實現鼠標交互,在init3d()函數中設置6個面的交互屬性為true:

                   frontMaterial.interactive = true;
                   frontMaterial.name = "front";   
                   backMaterial.interactive = true;
                   backMaterial.name = "back";   
                   leftMaterial.interactive = true;
                   leftMaterial.name = "left";   
                   rightMaterial.interactive = true;
                   rightMaterial.name = "right";   
                   topMaterial.interactive = true;
                   topMaterial.name = "top";   
                   bottomMaterial.interactive = true;
                   bottomMaterial.name = "bottom"; 

           

              由于要求有緩動效果,所以在幀頻處理函數中通過默認相機的放大:

           

           default_camera.zoom += Math.sqrt(6.8-default_camera.zoom)/5;

           

              縮小:

           

           default_camera.zoom -= Math.sqrt(default_camera.zoom-2)/5;

           

          來達到效果。接著通過判斷立方體的X、Y、Z三個方向的旋轉進一步設定緩動放大縮小過程效果,從而達到高級3D場景交互事件效果的運用目的。

              總結:本節主要是關于高級3D場景交互事件用法,特別是在一些緩動算法上有一定的難度,通過平方根函數求兩點之間的距離達到緩動放大、縮小的效果(這個我習慣稱為逼近“定點距離緩動”)。

              本教程可自由轉載,請注明轉載出處,謝謝~!

          posted on 2008-11-19 14:52 seal 閱讀(697) 評論(0)  編輯  收藏 所屬分類: Flex+ActionScript
          主站蜘蛛池模板: 上饶县| 常州市| 慈利县| 大名县| 尤溪县| 三台县| 宁国市| 施秉县| 临城县| 奉节县| 保德县| 武义县| 天全县| 大厂| 临城县| 怀安县| 乌拉特前旗| 安化县| 霍邱县| 永清县| 曲阳县| 仙居县| 高台县| 楚雄市| 潮安县| 寿宁县| 福安市| 延长县| 临颍县| 定日县| 永州市| 天津市| 金华市| 安宁市| 和硕县| 九台市| 大英县| 彭州市| 四川省| 万宁市| 万州区|