テクスチャの更新


テクスチャを外出しする話の続き。
オブジェクトの外に置いたテクスチャに線を描いて、リアルタイムに反映するサンプルを作ってみた。
(右の黄色い四角に描く)

サンプル


前に
これを作ったときはオブジェクトの中に埋め込んでたので、わざわざ「こうしん」ボタンを付けてたんだけど、次はこの方法で直接書き込んでやる予定。

ソースはこんな感じ。

package
{
    import flash.display.*;
    import flash.events.*;
    import flash.geom.Rectangle;

    import org.papervision3d.cameras.Camera3D;
    import org.papervision3d.materials.ColorMaterial;
    import org.papervision3d.materials.MovieMaterial;
    import org.papervision3d.materials.utils.MaterialsList;
    import org.papervision3d.objects.DisplayObject3D;
    import org.papervision3d.objects.primitives.Cube;
    import org.papervision3d.render.BasicRenderEngine;
    import org.papervision3d.scenes.Scene3D;
    import org.papervision3d.view.Viewport3D;

    public class textureTest extends Sprite
    {

        public var container : Sprite;
        public var scene     :Scene3D;
        public var camera    :Camera3D;
        public var rootNode  :DisplayObject3D;
        public var renderer:BasicRenderEngine;
        public var viewport:Viewport3D;

        private var _cube:Cube;

         /** 外からいじりたいテクスチャ */
        private var _textureSprite:Sprite;

         /** マウス状態 */
        private var _isMouseDown:Boolean = false;

         /** コンストラクタ */
        public function textureTest():void
        {
            stage.frameRate = 60;
            stage.quality   = StageQuality.MEDIUM;
            stage.scaleMode = StageScaleMode.NO_SCALE;
            stage.align = StageAlign.TOP_LEFT;
            this.addEventListener(Event.ENTER_FRAME, loop3D);

            init3D();
        }

        /** 初期化 */
        private function init3D():void
        {
        	renderer = new BasicRenderEngine();

            scene = new Scene3D();

            rootNode = scene.addChild( new DisplayObject3D( "rootNode" ) );
            rootNode.rotationY = 45;
            rootNode.y = -500;

           //外からいじくりたいテクスチャを初期化
            _textureSprite = new Sprite();
            _textureSprite.graphics.beginFill(0xffff00);
            _textureSprite.graphics.drawRect(0,0,400,400);
            _textureSprite.graphics.endFill();
            _textureSprite.addEventListener(MouseEvent.MOUSE_DOWN, _onMouseDown);
            _textureSprite.addEventListener(MouseEvent.MOUSE_UP, _onMouseUp)
            _textureSprite.addEventListener(MouseEvent.MOUSE_MOVE, _onMouseMove);

            _textureSprite.x = 400;

            this.addChild(_textureSprite);

            //キューブのマテリアルを設定
            var m:MovieMaterial = new MovieMaterial(_textureSprite, false, true, false, new Rectangle(0, 0, 400, 400));
            m.interactive = true;
            m.precise = true;
            m.allowAutoResize = false;

            var ml:MaterialsList = new MaterialsList();
			ml.addMaterial(m, 'front');
			ml.addMaterial(new ColorMaterial(0xff0000), 'back');
			ml.addMaterial(new ColorMaterial(0x00ff00), 'right');
			ml.addMaterial(new ColorMaterial(0x00ff00), 'left');
			ml.addMaterial(new ColorMaterial(0x0000ff), 'top');
			ml.addMaterial(new ColorMaterial(0x0000ff), 'bottom');

			//キューブ
            _cube = new Cube(ml);
            _cube.rotationX = -90;
            rootNode.addChild(_cube);

            //ビューポート
            viewport = new Viewport3D(400,400,false,true);
			viewport.containerSprite.buttonMode = true;
			viewport.x = 0;
			viewport.y = 0;
			addChild(viewport);

			//カメラ
			camera = new Camera3D();
         	camera.y = 500;
        	camera.rotationX = 30;
           	camera.focus = 500;
          	camera.zoom = 1;
          	camera.target = _cube;

        }

        /** テクスチャのマウスイベント */
        private function _onMouseDown(e:MouseEvent):void{
        	_textureSprite.graphics.lineStyle(0,0);
        	_textureSprite.graphics.moveTo(_textureSprite.mouseX, _textureSprite.mouseY);
        	_isMouseDown = true;
        }
        private function _onMouseUp(e:MouseEvent):void{
        	_textureSprite.graphics.endFill();
        	_isMouseDown = false;
        }
        private function _onMouseMove(e:MouseEvent):void{
        	if(_isMouseDown){
        		_textureSprite.graphics.lineTo(_textureSprite.mouseX, _textureSprite.mouseY);
        	}
        }

        /** レンダリング */
        private function loop3D( event:Event ):void
        {
        	_cube.rotationY += 0.5;
            renderer.renderScene(this.scene, this.camera, this.viewport);
        }

        private function onStageResize(event:Event):void
        {
            container.x = this.stage.stageWidth  / 2;
            container.y = this.stage.stageHeight / 2;
        }

    }
}

virtualMouse を使えば3Dオブジェクトの表面に直接描けるんだけど、オブジェクトが複雑になると、どうもUVマップの繋ぎ目の描き味が気持ち悪いので却下。
そのうちColladaのオブジェクトをロードして動くサンプルでも作ります。

コメントを残す