/** * Papervision3Dで中心点をすらす * Papervision3DでViewportの大きさを変えずに中心点(0, 0)の位置を上にずらしたいとか下にずらしたい時があったので作ってみました。 * Viewport3Dを拡張して、vanishingPointというプロパティを追加してcontainerSpriteの中心点を調整してます。 * 赤い点がviewportの中心点、青い点が消失点、中心の白い矩形エリアが3Dオブジェクトの表示領域です。 * あまり細かく検証していないので、バグがあるかも。 * * 2010.07.16 作成 * * @author Shuhei Kamiya<loftimg.jp> * @see http://loftimg.jp/blog/actionscript/papervision3d-vanishingpoint.php */ package { import flash.display.Graphics; import flash.display.Shape; import flash.display.Sprite; import flash.display.StageAlign; import flash.display.StageScaleMode; import flash.events.Event; import flash.geom.Point; import org.libspark.betweenas3.BetweenAS3; import org.libspark.betweenas3.easing.Quart; import org.libspark.betweenas3.tweens.ITween; import org.papervision3d.cameras.Camera3D; import org.papervision3d.materials.ColorMaterial; import org.papervision3d.materials.WireframeMaterial; import org.papervision3d.materials.utils.MaterialsList; import org.papervision3d.objects.primitives.Cube; import org.papervision3d.objects.primitives.Plane; import org.papervision3d.render.BasicRenderEngine; import org.papervision3d.scenes.Scene3D; public class PV3DExViewport extends Sprite { private const _padding:Number = 30; private var _scene:Scene3D; private var _camera:Camera3D; private var _renderer:BasicRenderEngine; private var _viewport:ExViewport3D; private var _center:Shape; private var _vanishingPoint:Shape; public function PV3DExViewport() { super(); stage.scaleMode = StageScaleMode.NO_SCALE; stage.align = StageAlign.TOP_LEFT; _init3d(); _initObject(); _initScreen(); var t:ITween = BetweenAS3.serial( BetweenAS3.to(_camera, {zoom: 200}, 3, Quart.easeInOut), BetweenAS3.to(_camera, {zoom: _camera.zoom}, 3, Quart.easeInOut) ); t.stopOnComplete = false; t.onUpdate = _render; t.play(); stage.addEventListener(Event.RESIZE, _resizeHandler); _resizeHandler(); } private function _init3d():void { _scene = new Scene3D(); _camera = new Camera3D(); _renderer = new BasicRenderEngine(); _camera.zoom = 10; _viewport = new ExViewport3D(stage.stageWidth - (_padding*2), stage.stageHeight - (_padding*2), false, false, true, true); _viewport.x = _padding; _viewport.y = _padding; //ExViewport3D.vanishingPointを指定するか、 //ExViewport3Dのコンストラクタの第7引数にPointデータを指定するかしてください。 //※ExViewport3D.vanishingPointのx、yの値を直接編集しても反映されません //以下は消失点を右へ100px、下へ100px移動させる指定です。 _viewport.vanishingPoint = new Point(100, 100); addChild(_viewport); } private function _initObject():void { var material:WireframeMaterial = new WireframeMaterial(0x666666, 1, 1); var materialList:MaterialsList = new MaterialsList({all: material}); var c:Cube = new Cube(materialList, 500, 500, 500, 1, 1, 1); _scene.addChild(c); var t:ITween = BetweenAS3.to(c, {rotationX: 360, rotationY: 360, rotationZ: 360}, 5); t.stopOnComplete = false; t.play(); } private function _initScreen():void { _center = new Shape(); _center.graphics.beginFill(0xFF0000, 1); _center.graphics.drawCircle(0, 0, 3); _center.graphics.endFill(); _vanishingPoint = new Shape(); _vanishingPoint.graphics.beginFill(0x0000FF, 1); _vanishingPoint.graphics.drawCircle(0, 0, 3); _vanishingPoint.graphics.endFill(); addChild(_center); addChild(_vanishingPoint); } private function _render():void { _renderer.renderScene(_scene, _camera, _viewport); } private function _resizeHandler(e:Event=null):void { _viewport.viewportWidth = stage.stageWidth - (_padding*2); _viewport.viewportHeight = stage.stageHeight - (_padding*2); _center.x = stage.stageWidth/2; _center.y = stage.stageHeight/2; _vanishingPoint.x = _center.x + _viewport.vanishingPoint.x; _vanishingPoint.y = _center.y + _viewport.vanishingPoint.y; var g:Graphics = graphics; g.clear(); g.beginFill(0xCCCCCC, 1); g.drawRect(0, 0, stage.stageWidth, stage.stageHeight); g.endFill(); g.beginFill(0xFFFFFF, 1); g.drawRect(_padding, _padding, stage.stageWidth - (_padding*2), stage.stageHeight - (_padding*2)); g.endFill(); } } } import flash.geom.Point; import flash.geom.Rectangle; import org.papervision3d.view.Viewport3D; class ExViewport3D extends Viewport3D { override public function set viewportWidth(value:Number):void { super.viewportWidth = value; _updateVanishingPoint(); } override public function set viewportHeight(value:Number):void { super.viewportHeight = value; _updateVanishingPoint(); } public function get vanishingPoint():Point { return _vanishingPoint; } public function set vanishingPoint(value:Point):void { _vanishingPoint = value; _updateVanishingPoint(); } private var _vanishingPoint:Point; public function ExViewport3D(viewportWidth:Number = 640, viewportHeight:Number = 480, autoScaleToStage:Boolean = false, interactive:Boolean = false, autoClipping:Boolean = true, autoCulling:Boolean = true, vanishingPoint:Point=null) { _vanishingPoint = vanishingPoint || new Point(); super(viewportWidth, viewportHeight, autoScaleToStage, interactive, autoClipping, autoCulling); } private function _updateVanishingPoint():void { containerSprite.x = _hWidth + _vanishingPoint.x; containerSprite.y = _hHeight + _vanishingPoint.y; } } Papervision3Dで中心点をずらす