パノラマ一周360度な風景写真を使って周囲を見まわしている感のあるサンプル(Papervision3D)。
doubleSided な BitmapFileMaterial を Cylinder オブジェクトに貼り付けて、カメラを Cylinder オブジェクトの内側に配置。カメラをぐるぐる回すことで、Cylinder オブジェクトの内側の画像を左右にスクロールして見る。

せっかくの Papervision3D だけど、横方向だけのスクロールなので3D感覚なし。

マウス押下でズームイン。ダブルクリックで写真を変更。

パノラマ写真素材探索

Flockr で Creative Commons ライセンスな写真を検索 ⇒ Flickr: Search "panorama 360"

今回使った写真は以下の4枚。

360° Panorama - St. Elisabeth Kirche Weisenfels on Flickr - Photo Sharing! (by Rudolf Schuba)
360° Panorama - Weisenfels on Flickr - Photo Sharing! (by Rudolf Schuba)
360° Panorama - Marktplatz Weisenfels on Flickr - Photo Sharing! (by Rudolf Schuba)
Old Wardour Castle Courtyard: 360° Panorama on Flickr - Photo Sharing! (by johnelamper)

Flex用ソースコード(Panorama.as)


package {
 
  import flash.display.*;
  import flash.events.*;
 
  import org.papervision3d.scenes.*;
  import org.papervision3d.objects.*;
  import org.papervision3d.cameras.*;
  import org.papervision3d.materials.*;
 
  [SWF(width="400", height="400", backgroundColor="#000000", frameRate="30")]
 
  public class Panorama extends Sprite {
 
    private var container : Sprite;
    private var scene     : Scene3D;
    private var camera    : FreeCamera3D;
 
    // 3Dオブジェクト踊らせ用パラメータ
    private var valx    : Number = 0;
    private var valy    : Number = 0;
 
    private var screen:DisplayObject3D = null;
 
    // 画像ファイルのパス
    private var imageFilePath:Array = new Array();
    private var imageIndex:int = -1;
 
    // マウスの状態
    private var mousedown:Boolean = false;
 
    private var ZOOM_MIN:Number = 5;
 
    public function Panorama():void {
 
      // リサイズに対応(swfをブラウザで直接ひらいているときとか)
      stage.addEventListener(Event.RESIZE, onStageResize);
 
      // 定期的にイベント発生
      addEventListener(Event.ENTER_FRAME, myLoopEvent);
 
      // 表示用の Sprite オブジェクトを生成
      container = new Sprite();
      container.x = 400 / 2; // at center : swf width  = 400
      container.y = 400 / 2; // at center : swf height = 400
 
      container.doubleClickEnabled = true;
      container.addEventListener(MouseEvent.DOUBLE_CLICK, onDoubleClick);
      container.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
      container.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
 
      addChild(container);
 
      // シーンオブジェクトを作る
      scene = new Scene3D(container);
 
      // カメラオブジェクトを作る
      camera = new FreeCamera3D();
      camera.x = 0;
      camera.y = 0;
      camera.z = 0;
      camera.focus = 500;
      camera.zoom = ZOOM_MIN;
 
      // 地球画像リスト
      //
      // 360° Panorama - St. Elisabeth Kirche Weisenfels on Flickr - Photo Sharing! (by Rudolf Schuba)
      // http://www.flickr.com/photos/rudolf_schuba/420931310/
      imageFilePath.push("420931310_f0d25ae024_b_d.jpg");
      //
      // 360° Panorama - Weisenfels on Flickr - Photo Sharing! (by Rudolf Schuba)
      // http://www.flickr.com/photos/rudolf_schuba/416818471/
      imageFilePath.push("416818471_db0fae10c7_b_d.jpg");
      //
      // 360° Panorama - Marktplatz Weisenfels on Flickr - Photo Sharing! (by Rudolf Schuba)
      // http://www.flickr.com/photos/rudolf_schuba/417327148/
      imageFilePath.push("417327148_c41f330afc_b_d.jpg");
      //
      // Old Wardour Castle Courtyard: 360° Panorama on Flickr - Photo Sharing! (by johnelamper)
      // http://www.flickr.com/photos/flashlamp/478236722/
      imageFilePath.push("478236722_c3888f42b5_b_d.jpg");
 
      changeImage();
    }
 
    private static function createCylinder(image:String):Cylinder {
 
      var material:BitmapFileMaterial = new BitmapFileMaterial(image);
      material.doubleSided = true;
 
      var radius:Number = 100;
      var height:Number = 100;
      var segmentsW:int = 32;
      var segmentsH:int = 32;
 
      var c:Cylinder = new Cylinder(material, radius, height, segmentsW, segmentsH);
      c.x =  0;
      c.y =  0;
      c.z =  0;
      return c;
    }
 
    /* 苦闘の跡(このままSphereとCubeを使うのは難しい)
    private static function createSphere(image:String):Sphere {
 
      var material:BitmapFileMaterial = new BitmapFileMaterial(image);
      material.doubleSided = true;
 
      var radius:Number = 100
      var segmentsW:int = 24;
      var segmentsH:int = 24;
 
      var sphere:Sphere = new Sphere(material, radius, segmentsW, segmentsH);
      sphere.x =  0;
      sphere.y =  0;
      sphere.z =  0;
      return sphere;
    }
 
    private static function createCube(image:String):Cube {
 
      var material:BitmapFileMaterial = new BitmapFileMaterial(image);
      material.doubleSided = true;
 
      var width:Number = 100;
      var depth:Number = 100;
      var height:Number = 100;
 
      var c:Cube = new Cube(material, width, depth, height);
      c.x =  0;
      c.y =  0;
      c.z =  0;
      return c;
    }
    */
 
    private function changeImage():void {
 
      if(screen){
        scene.removeChild(screen);
      }
 
      imageIndex++;
      if(imageIndex >= imageFilePath.length){
        imageIndex = 0;
      }
 
      screen = createCylinder(imageFilePath[imageIndex] as String);
      //screen = createSphere(imageFilePath[imageIndex] as String);
      //screen = createCube(imageFilePath[imageIndex] as String);
      scene.addChild(screen);
    }
 
    // ダブルクリック時に地球儀の絵を入れ替える
    private function onDoubleClick(event:MouseEvent):void {
      changeImage();
    }
 
    private function onMouseDown(event:MouseEvent):void {
      mousedown = true;
    }
 
    private function onMouseUp(event:MouseEvent):void {
      mousedown = false;
    }
 
    private function myLoopEvent(event:Event):void {
 
      if(mousedown){
        // マウス押下中はズームイン
        camera.zoom += 0.05;
      }else{
        // ズームアウト
        if(camera.zoom > ZOOM_MIN){
          camera.zoom -= 0.2;
        }
      }
 
      valx -= container.mouseX / 200;
      valy -= container.mouseY / 200;
      screen.rotationY = valx;
      //screen.rotationX = valy; // Y方向は動かさない方向で
 
      scene.renderCamera(camera);
    }
 
    private function onStageResize(event:Event):void {
      container.x = stage.stageWidth  / 2;
      container.y = stage.stageHeight / 2;
    }
    
  }
}

Papervision3Dによるパノラマぐるぐるサンプルあれこれ

Panoramic 360 with Papervision3d - sephiroth.it - flash & php
球体に近い 3dmax collada のオブジェクトを使うタイプ(ソースコードあり)

These Days Labs ≫ Blog Archive ≫ Panorama experiment with Papervision3D
Planeオブジェクトを4枚貼りあわせるタイプ(ソースコードあり)

Papervision3D AS3 Panorama ≪ Papervision3D
"It’s just a standard cube made out of six planes, for a total of 588 triangles." とあるので、おそらくPlaneオブジェクトを6枚貼りあわせるタイプ(ソースコードなし)

tags: zlashdot Flash Flash Flex Papervision3D

Posted by NI-Lab. (@nilab)