FrustumClippingとCamera3D.target

Planeを倒して床を表現するとき、Planeがカメラに近いところでカリングされてしまう。

target

これを解消するために、レンダラのclippingをFrustumClippingにする。けど、カメラにtargetを指定しているとなんかFrustumClippingされてる領域がカメラを回す方向と逆にずれる。

target_clipping

仕方ないから、カメラにtargetを指定するのをやめて、カメラ位置を更新する毎にlookAt()してみる。

lookat_clipping

で、一応解決。
FrustumClippingクラスについては[PV3D2.0] FrustumClippingnote.xを参照。

最後のサンプルの「FrustumClippingして、lookAt()でカメラを振り向かせる」ソース。

  • ActionScript
  • CameraTargetWithFrustumClipping.as
  • Source
package
{
	import flash.display.Sprite;
	import flash.events.Event;
	import org.papervision3d.cameras.Camera3D;
	import org.papervision3d.core.clipping.FrustumClipping;
	import org.papervision3d.materials.ColorMaterial;
	import org.papervision3d.materials.special.CompositeMaterial;
	import org.papervision3d.materials.WireframeMaterial;
	import org.papervision3d.objects.primitives.Cone;
	import org.papervision3d.objects.primitives.Plane;
	import org.papervision3d.render.BasicRenderEngine;
	import org.papervision3d.scenes.Scene3D;
	import org.papervision3d.view.Viewport3D;

	[SWF(backgroundColor = 0x000000, width = 600, height = 400, frameRate = 30)]
	public class CameraTargetWithFrustumClipping extends Sprite
	{

		private var _render:BasicRenderEngine;
		private var _scene:Scene3D;
		private var _camera:Camera3D;
		private var _viewport:Viewport3D;

		private var _floor:Plane;
		private var _cone:Cone;

		private var _cameraRadius:Number;
		private var _cameraAngle:Number;

		public function CameraTargetWithFrustumClipping()
		{
			if (stage) init();
			else addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
		}

		private function onAddedToStage(e:Event):void
		{
			removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
			init();
		}

		private function init():void
		{
			var colorMaterial:ColorMaterial = new ColorMaterial(0x0099CC);
			var wireframeMaterial:WireframeMaterial = new WireframeMaterial(0x00CCFF);
			var compositeMaterial:CompositeMaterial = new CompositeMaterial();
			compositeMaterial.addMaterial(colorMaterial);
			compositeMaterial.addMaterial(wireframeMaterial);

			init3D();
			initFloor(compositeMaterial);
			initCone(compositeMaterial);
			initEvent();
		}

		private function init3D():void
		{
			_cameraRadius = 1000;
			_cameraAngle = 0;

			_render = new BasicRenderEngine();
			_render.clipping = new FrustumClipping(FrustumClipping.ALL);
			_scene = new Scene3D();
			_camera = new Camera3D();
			_viewport = new Viewport3D(stage.stageWidth, stage.stageHeight);

			addChild(_viewport);
		}

		private function initFloor(compositeMaterial:CompositeMaterial):void
		{
			_floor = new Plane(compositeMaterial, 2000, 2000, 4, 4);
			_floor.rotationX = 90;
			_floor.y = -350;

			_scene.addChild(_floor);
		}

		private function initCone(compositeMaterial:CompositeMaterial):void
		{
			_cone = new Cone(compositeMaterial, 300, 400);
			//_camera.target = _cone;    // _camera.target を使うのをやめて

			_scene.addChild(_cone);
		}

		private function initEvent():void
		{
			addEventListener(Event.ENTER_FRAME, onEnterFrame);
		}

		private function onEnterFrame(e:Event):void
		{
			_cameraAngle += Math.PI / 180 * 3;
			_camera.x = _cameraRadius * Math.cos(_cameraAngle);
			_camera.z = _cameraRadius * Math.sin(_cameraAngle);
			_camera.lookAt(_cone);       // _camera.lookAt() を使う

			render();
		}

		private function render():void
		{
			_render.renderScene(_scene, _camera, _viewport);
		}


	}

}
  1. package
  2. {
  3.     import flash.display.Sprite;
  4.     import flash.events.Event;
  5.     import org.papervision3d.cameras.Camera3D;
  6.     import org.papervision3d.core.clipping.FrustumClipping;
  7.     import org.papervision3d.materials.ColorMaterial;
  8.     import org.papervision3d.materials.special.CompositeMaterial;
  9.     import org.papervision3d.materials.WireframeMaterial;
  10.     import org.papervision3d.objects.primitives.Cone;
  11.     import org.papervision3d.objects.primitives.Plane;
  12.     import org.papervision3d.render.BasicRenderEngine;
  13.     import org.papervision3d.scenes.Scene3D;
  14.     import org.papervision3d.view.Viewport3D;
  15.  
  16.     [SWF(backgroundColor = 0x000000, width = 600, height = 400, frameRate = 30)]
  17.     public class CameraTargetWithFrustumClipping extends Sprite
  18.     {
  19.  
  20.         private var _render:BasicRenderEngine;
  21.         private var _scene:Scene3D;
  22.         private var _camera:Camera3D;
  23.         private var _viewport:Viewport3D;
  24.  
  25.         private var _floor:Plane;
  26.         private var _cone:Cone;
  27.  
  28.         private var _cameraRadius:Number;
  29.         private var _cameraAngle:Number;
  30.  
  31.         public function CameraTargetWithFrustumClipping()
  32.         {
  33.             if (stage) init();
  34.             else addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
  35.         }
  36.  
  37.         private function onAddedToStage(e:Event):void
  38.         {
  39.             removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
  40.             init();
  41.         }
  42.  
  43.         private function init():void
  44.         {
  45.             var colorMaterial:ColorMaterial = new ColorMaterial(0x0099CC);
  46.             var wireframeMaterial:WireframeMaterial = new WireframeMaterial(0x00CCFF);
  47.             var compositeMaterial:CompositeMaterial = new CompositeMaterial();
  48.             compositeMaterial.addMaterial(colorMaterial);
  49.             compositeMaterial.addMaterial(wireframeMaterial);
  50.  
  51.             init3D();
  52.             initFloor(compositeMaterial);
  53.             initCone(compositeMaterial);
  54.             initEvent();
  55.         }
  56.  
  57.         private function init3D():void
  58.         {
  59.             _cameraRadius = 1000;
  60.             _cameraAngle = 0;
  61.  
  62.             _render = new BasicRenderEngine();
  63.             _render.clipping = new FrustumClipping(FrustumClipping.ALL);
  64.             _scene = new Scene3D();
  65.             _camera = new Camera3D();
  66.             _viewport = new Viewport3D(stage.stageWidth, stage.stageHeight);
  67.  
  68.             addChild(_viewport);
  69.         }
  70.  
  71.         private function initFloor(compositeMaterial:CompositeMaterial):void
  72.         {
  73.             _floor = new Plane(compositeMaterial, 2000, 2000, 4, 4);
  74.             _floor.rotationX = 90;
  75.             _floor.y = -350;
  76.  
  77.             _scene.addChild(_floor);
  78.         }
  79.  
  80.         private function initCone(compositeMaterial:CompositeMaterial):void
  81.         {
  82.             _cone = new Cone(compositeMaterial, 300, 400);
  83.             //_camera.target = _cone;    // _camera.target を使うのをやめて
  84.  
  85.             _scene.addChild(_cone);
  86.         }
  87.  
  88.         private function initEvent():void
  89.         {
  90.             addEventListener(Event.ENTER_FRAME, onEnterFrame);
  91.         }
  92.  
  93.         private function onEnterFrame(e:Event):void
  94.         {
  95.             _cameraAngle += Math.PI / 180 * 3;
  96.             _camera.x = _cameraRadius * Math.cos(_cameraAngle);
  97.             _camera.z = _cameraRadius * Math.sin(_cameraAngle);
  98.             _camera.lookAt(_cone);       // _camera.lookAt() を使う
  99.  
  100.             render();
  101.         }
  102.  
  103.         private function render():void
  104.         {
  105.             _render.renderScene(_scene, _camera, _viewport);
  106.         }
  107.  
  108.  
  109.     }
  110.  
  111. }


About this entry