Somero2002_02Kobe, Japan 2010-04-28Kuortti.2010-06-26norge5oslo_169Nanbudo_Norge2007-12_211Nanbudo_Norge2007-12_038Kuortti.2010-06-26Nanbudo_WCh2006_076South.Africa.Roadtrip.2007-08_353Zoo2006-10-07_043Pakkas03Pitkanen_076Helsinki2005-10-15_16_019Naginata Helsinki 2010-02-07 09Jodo-Milano.2008-09_035Kobe, Japan 2010-05-01Inujima, Japan 2010-04-30Oslo.Norway.2002.summer.034Kuortti.2010-06-26South.Africa.Roadtrip.2007-08_216Shiga, Japan 2010-04-18Osaka, Japan 2010-04-29Vesa-Rauttu-60v_1899
Luna near the crossing of the two biggest rivers of Italy

Two Italy's biggest rivers, Po and Ticino, cross near Pavia.

Multiple view ports and cameras in Papervision3D

For long I have been planning to make an flash application to visualise certain Ryukyu Kobudo techniques in 3D.

The code below and the file attached is the preliminary test to see how navigation between several camera angles and view ports works. Make sure to have a truetype font file in the same directory when compiling. I was using "nrkis.ttf". You can also switch the material list of the cube. See code for more.

/**
* @mxmlc -noplay -source-path=E:/AS3libs
*/
package {
    import flash.display.*;
    import flash.events.*;
    import flash.text.*;
    import flash.ui.*;

    import org.papervision3d.objects.DisplayObject3D;
    import org.papervision3d.objects.primitives.*;
    import org.papervision3d.view.Viewport3D;
    import org.papervision3d.render.BasicRenderEngine;
    import org.papervision3d.materials.*;
    import org.papervision3d.materials.utils.MaterialsList;
    import org.papervision3d.cameras.Camera3D;
    import org.papervision3d.core.*;
    import org.papervision3d.core.render.data.RenderStatistics;
    import org.papervision3d.scenes.Scene3D;

    import gs.TweenLite;

    [SWF(width = "970", height = "500", frameRate = "33", backgroundColor = "#FFFFFF")]

    public class MultiView extends Sprite {

        private var scene:Scene3D;
        private var cameras:Array;
        private var views:Array;
        private var renderer:BasicRenderEngine;
        private var currentCamera:int;
        private var center:DisplayObject3D;
        private var cube:Cube;
        private var format:TextFormat;
        private var currentZoom:Number = 1;

        [Embed(source="nrkis.ttf", fontFamily="nrkis")]
        public var nrkis:String;

        public function MultiView() {
            stage.align = StageAlign.TOP_LEFT;
            stage.scaleMode = StageScaleMode.NO_SCALE;
            stage.quality = StageQuality.HIGH;

            renderer = new BasicRenderEngine();

            scene = new Scene3D();

            center = new DisplayObject3D();
            center.name = "center";
            scene.addChild(center);

            format = new TextFormat();
            format.font = "nrkis";
            format.bold = true;
            format.align = TextFormatAlign.LEFT;
            format.color = 0x010101;
            format.size = 13;

            createViews();

            createCameras();

            this.addEventListener(Event.ENTER_FRAME, onEnterFrame);
            stage.addEventListener(KeyboardEvent.KEY_UP, onKeyUp);

            var mclist:Object = {};
            var locs:Array = ["all", "front", "back", "right", "left", "top", "bottom"];
            for (var s:uint = 0; s < locs.length; s++) {
                var mc:Sprite = new Sprite();
                mc.name = String(locs[s]);
                var gra:Graphics = mc.graphics;
                gra.lineStyle(1, 0x000000);
                gra.beginFill(0x123456 * s + 0x555555);
                gra.drawRect(0, 0, 200, 100);
                var tx:TextField = new TextField();
                tx.defaultTextFormat = format;
                tx.embedFonts = true;
                tx.text = mc.name;
                tx.width = 100;
                mc.addChild(tx);
                mclist[locs[s]] = new MovieMaterial(mc, true);
            }

            var materials:MaterialsList = new MaterialsList({
                all:    new ColorMaterial(0x63FF04, 1, true),
                front:    new ColorMaterial(0x63FF04, 1, true),
                back:    new ColorMaterial(0xFF6304, 1, true),
                right:    new ColorMaterial(0x63CCFF, 1, true),
                left:    new ColorMaterial(0x0463FF, 1, true),
                top:    new ColorMaterial(0xCCFF63, 1, true),
                bottom:    new ColorMaterial(0xCCCCCC, 1, true)
            });
            cube = new Cube(new MaterialsList(mclist), 200, 300, 100, 4, 4, 4);
            scene.addChild(cube);
        }

        private function createViews():void {
            views = [];
            var settings:Array = [
                { w: 640, h: 480, x: 0, y: 1 },
                { w: 320, h: 240, x: 642, y: 1 },
                { w: 320, h: 240, x: 642, y: 242 }
            ];

            var len:uint = settings.length;
            for (var i:uint = 0; i < len; i++) {
                var opts:Object = settings[i] as Object;

                var view:Viewport3D = new Viewport3D(opts.w, opts.h);
                view.name = "Viewport " + i.toString();
                view.x = opts.x;
                view.y = opts.y;
                view.graphics.lineStyle(1, 0x000000);
                view.graphics.drawRect(0, 0, opts.w - 1, opts.h - 1);
                addChild(view);

                var tx:TextField = new TextField();
                tx.defaultTextFormat = format;
                tx.embedFonts = true;
                tx.name = "title";
                tx.width = opts.w;
                view.addChild(tx);

                var rx:TextField = new TextField();
                rx.defaultTextFormat = format;
                rx.embedFonts = true;
                rx.multiline = true;
                rx.wordWrap = true;
                rx.name = "render";
                rx.width = opts.w;
                rx.height = 32;
                rx.y = opts.h - 32;
                view.addChild(rx);

                views.push(view);
            }
        }

        private function createCameras():void {
            cameras = [];

            var cams:Array = [
                { x: 0, y: 0, z: 200, name: "Front" },
                { x: 0, y: 0, z: -200, name: "Back" },
                { x: 1, y: 200, z: 0, name: "Top" }, // x non zero to get out from the box.
                { x: 1, y: -200, z: 0, name: "Bottom" },
                { x: 200, y: 0, z: 0, name: "Right" },
                { x: -200, y: 0, z: 0, name: "Left" },
                { x: 160, y: 160, z: 160, name: "Angular" } // Extra camera for special angle.
            ];

            var len:uint = cams.length;
            for (var i:uint = 0; i < len; i++) {
                var opts:Object = cams[i] as Object;

                var cam:Camera3D = new Camera3D(center, currentZoom);
                cam.name = opts.name;
                cam.x = opts.x;
                cam.y = opts.y;
                cam.z = opts.z;
                cameras.push(cam);
            }
            stage.addEventListener(MouseEvent.MOUSE_WHEEL, onMouseWheel);
        }

        private function onEnterFrame(evt:Event):void {
            var vwlen:uint = views.length;

            for (var i:uint = 0; i < vwlen; i++) {
                var view:Viewport3D = views[i] as Viewport3D;
                var cam:Camera3D = cameras[i] as Camera3D;
                if (view.name == "Viewport 0") {
                    cam.zoom = currentZoom * 2;
                }
                else {
                    cam.zoom = currentZoom;
                }

                var title:TextField = view.getChildByName("title") as TextField;
                title.text = view.name + " - " + cam.name + " - Zoom: " + cam.zoom.toFixed(2);

                var stat:RenderStatistics = renderer.renderScene(scene, cam, view);
                var render:TextField = view.getChildByName("render") as TextField;
                render.text = stat.toString();
            }
        }

        private function onKeyUp(evt:KeyboardEvent):void {
            var cam:Camera3D;
            switch(evt.keyCode) {
                case Keyboard.LEFT:
                    // rotate camera array
                    cam = cameras.shift() as Camera3D;
                    cameras.push(cam);
                    break;
                case Keyboard.RIGHT:
                    // rotate camera array
                    cam = cameras.pop() as Camera3D;
                    cameras.unshift(cam);
                    break;
                case 82: // r
                    // Rotate the object
                    TweenLite.to(cube, 1, {rotationY: "+90"});
                    break;
            }
        }

        private function onMouseWheel(evt:MouseEvent):void {
            currentZoom += evt.delta / 100;
        }
    }
}

Use left / right arrow keys on the keyboard to change the camera, mouse wheel to adjust the zoom, "r" rotates the cube.

MultiView.swf

Time: 24/03/2008 23:46

QR code for paazio.nanbudo.fi