[Papervision3D]空中に浮かぶ板にズーム

2009 年 2 月 18 日

3dmawaruita

3dmawaruita.swf

Papervision3D使ってて3Dっぽい動きを表現したくて複数のPlaneをY軸回転させてみました。
こんなのが簡単につくれるからいいですね。
画像読み込んだりしたらおもしろそうだなー。

操作方法:
MOUSE:←→:左右回転
MOUSE:wheel:ズーム・ズームアウト
PlaneクリックでそのPlaneにポップアップ


package
{
	import caurina.transitions.Tweener;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.filters.GlowFilter;
	import org.papervision3d.cameras.CameraType;
	import org.papervision3d.core.proto.CameraObject3D;
	import org.papervision3d.events.InteractiveScene3DEvent;
	import org.papervision3d.materials.ColorMaterial;
	import org.papervision3d.materials.special.CompositeMaterial;
	import org.papervision3d.materials.WireframeMaterial;
	import org.papervision3d.objects.DisplayObject3D;
	import org.papervision3d.objects.primitives.Plane;
	import org.papervision3d.view.BasicView;
	import org.papervision3d.view.layer.ViewportLayer;

	/**
	 *
	 * @author modoki
	 */
	public class Main extends BasicView
	{
		private var myPlane:Plane;
		private var mainObj:DisplayObject3D;
		private var selectObjName:String;
		private var onPopup:Boolean = false;
		private var onMaterial:ColorMaterial;
		private var floor:Plane;

		public function Main():void
		{
			super(400, 400, true, true, CameraType.FREE);
			buttonMode = true;

			//-----------------------------
			// 初期カメラ設定
			//-----------------------------
			iniCam();

			//-----------------------------
			// MATERIAL
			//-----------------------------
			onMaterial = new ColorMaterial(0x000099, 0.8);
			onMaterial.doubleSided = true;
			onMaterial.interactive = true;

			var material:CompositeMaterial = new CompositeMaterial();
			material.addMaterial(new ColorMaterial(0xCCCCCC, 0.8));
			material.doubleSided = true;
			material.interactive = true;

			//-----------------------------
			// OBJECT
			//-----------------------------
			mainObj = new DisplayObject3D();
			scene.addChild(mainObj);

			floor = new Plane(new WireframeMaterial(), 800, 800, 5, 5);
			floor.rotationX = 90;
			scene.addChild(floor);

			for (var i:int = 0; i < 50; i++) {
				var myPlane:Plane = new Plane(material, 50, 80, 2, 2);

				// 板配置
				myPlane.name = "plane" + i;
				myPlane.x = Math.random() * 600 - 300;
				myPlane.y = Math.random() * 150;
				myPlane.z = Math.random() * 600 - 300;

				// 中心に向かせる
				//myPlane.lookAt(mainObj);
				myPlane.rotationY = Math.atan2(myPlane.x, myPlane.z) * 180 / Math.PI;

				myPlane.addEventListener(InteractiveScene3DEvent.OBJECT_CLICK, clickHandler);
				myPlane.addEventListener(InteractiveScene3DEvent.OBJECT_OVER, overHandler);
				myPlane.addEventListener(InteractiveScene3DEvent.OBJECT_OUT, outHandler);

				mainObj.addChild(myPlane);
			}

			stage.addEventListener(MouseEvent.MOUSE_WHEEL, onMouseWheel);

			// レンダリング開始
			startRendering();
		}

		/**
		 *-------------------------------------------------------
		 * カメラ初期化
		 *-------------------------------------------------------
		 */
		private function iniCam():void
		{
			// カメラ開始位置
			camera.moveBackward(3000);
			camera.moveUp(1000);
			camera.culled = true;

			// カメラ初期位置設定
			var iniCam:CameraObject3D = new CameraObject3D();
			iniCam.moveUp(500);
			iniCam.rotationX = 20;

			// カメラ開始から初期位置まで移動
			Tweener.addTween( camera, {
				x			:iniCam.x,
				y			:iniCam.y,
				z			:iniCam.z,
				rotationX	:iniCam.rotationX,
				rotationY	:iniCam.rotationY,
				rotationZ	:iniCam.rotationZ,
				time		:5,
				transition	:"easeInOut"
				} );
		}

		/**
		 *-------------------------------------------------------
		 * Handler
		 *-------------------------------------------------------
		 */
		private function onMouseWheel(e:MouseEvent):void
		{
			var target :DisplayObject3D = new DisplayObject3D();
			target.copyTransform( camera );

			if (e.delta > 0) {
				target.moveForward(200);
			}else {
				target.moveBackward(200);
			}

			Tweener.addTween( camera, {
				x			:target.x,
				y			:target.y,
				z			:target.z,
				time		:1,
				transition	:"easeInOut"
				} );
		}		

		/**
		 *-------------------------------------------------------
		 * Handler
		 *-------------------------------------------------------
		 */
		private function overHandler(e:InteractiveScene3DEvent):void
		{
			// フィルター効果つける
			var vpl:ViewportLayer = e.currentTarget.createViewportLayer(viewport, true);
			vpl.filters = [new GlowFilter(0xffffff, 0.5, 10, 10, 5)];
		}

		/**
		 *-------------------------------------------------------
		 * Handler
		 *-------------------------------------------------------
		 */
		private function outHandler(e:InteractiveScene3DEvent):void
		{
			// フィルター効果はずす
			var vpl:ViewportLayer = e.currentTarget.createViewportLayer(viewport, true);
			vpl.filters = null;
		}

		/**
		 *-------------------------------------------------------
		 * Handler
		 *-------------------------------------------------------
		 */
		private function clickHandler(e:InteractiveScene3DEvent):void
		{
			// Popアップ中
			onPopup = true;

			// Camera移動用ターゲット準備
			var target :DisplayObject3D = new DisplayObject3D();

			if (selectObjName != null) {
				// 前のオブジェクトは前の位置に戻る
				var oldObj:DisplayObject3D = mainObj.getChildByName(selectObjName);
				Tweener.addTween( oldObj, {
					y			:0,
					scale       :1,
					time		:1,
					transition	:"easeOutElastic"
					} );

				// 一度選択済み
				oldObj.material = onMaterial;
			}

			if (selectObjName != e.currentTarget.name) {
				// 前と違うオブジェクトをクリック

				target.copyTransform( e.currentTarget );
				target.moveBackward( camera.zoom * camera.focus - 100);
				target.moveUp(250);

				Tweener.addTween( mainObj, {
					rotationX	:0,
					rotationY	:0,
					rotationZ	:0,
					time		:1,
					transition	:"easeInOut"
					} );

				Tweener.addTween( camera, {
					x			:target.x,
					y			:target.y,
					z			:target.z,
					rotationX	:30,
					rotationY	:e.currentTarget.rotationY,
					rotationZ	:e.currentTarget.rotationZ,
					time		:1,
					transition	:"easeInOut"
					} );

				Tweener.addTween( e.currentTarget, {
					y			:e.currentTarget.y + 100,
					scale       :3,
					delay       :0.5,
					time		:2,
					transition	:"easeOutElastic"
					} );

				selectObjName = e.currentTarget.name;
			} else {
				// 前と同じオブジェクトをクリック

				target.copyTransform( camera );
				target.moveBackward(350);

				Tweener.addTween( camera, {
					x			:target.x,
					y			:target.y,
					z			:target.z,
					time		:1,
					transition	:"easeInOut"
					} );

				onPopup = false;
				selectObjName = null;
			}
		}

		/**
		 *-------------------------------------------------------
		 * onRenderTick
		 *-------------------------------------------------------
		 */
		override protected function onRenderTick(event:Event = null):void {
			if (!onPopup){
				mainObj.yaw(-(mouseX - stage.width * .5) / (stage.width * .1));
				floor.roll(-((mouseX - stage.width * .5) / (stage.width * .25)));
			}

			super.onRenderTick(event);
		}
	}
}

タグ: , ,

コメント / トラックバック 1 件

  1. [...] 10月25日 12:22 ra9da [Papervision3D]空中に浮かぶ板にズーム | modoki.org. [...]

コメントをどうぞ