Flashの3D表現ライブラリの1つである、Alternativa3Dに手を出してみました。
使ってるバージョンは7.5です。
今回は、コントローラーを使ってみました。
これを使うと、Object3Dの位置や向きを簡単に制御できます。
で、作ったのはこれ。
カメラが円運動をしつつ、常に原点をむくようにコントロールしています。
lookAtがあるので、カメラの視線を簡単に変更できるのが嬉しいです。
以下ソースです。
package
{
import alternativa.engine3d.containers.DistanceSortContainer;
import alternativa.engine3d.controllers.SimpleObjectController;
import alternativa.engine3d.core.Camera3D;
import alternativa.engine3d.core.Clipping;
import alternativa.engine3d.core.View;
import alternativa.engine3d.materials.TextureMaterial;
import alternativa.engine3d.primitives.Sphere;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Graphics;
import flash.display.Shape;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageQuality;
import flash.display.StageScaleMode;
import flash.events.Event;
[SWF(backgroundColor=0x000000)]
public class Main extends Sprite
{
[Embed(source='image.jpg')]
private var img:Class;
private static const RADIAN:Number = Math.PI/180;
private var rootContainer:DistanceSortContainer;
private var camera:Camera3D;
private var view:View;
private var theta:Number;
private var radius:Number;
private var controller:SimpleObjectController;
private var back:Graphics;
private var flug:int;
public function Main()
{
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
stage.quality = StageQuality.LOW;
stage.frameRate = 30;
// ベースとなるコンテナ。
rootContainer = new DistanceSortContainer();
rootContainer.sortByZ = true;
// カメラの初期化 (PV3Dでいうフリーカメラみたいなの)。
camera = rootContainer.addChild(new Camera3D) as Camera3D;
// コントローラーの作成
controller = new SimpleObjectController(stage, camera,1);
// ビューポート (View is DisplayObject)
view = new View(800,500);
view.logoAlign = StageAlign.TOP_LEFT;
camera.view = addChild(view) as View;
// Sphereを配置
theta = flug = 0;
radius = 600;
var texture:BitmapData = (new img as Bitmap).bitmapData;
var mat:TextureMaterial = new TextureMaterial(texture, false, true);
var sphere:Sphere = rootContainer.addChild(new Sphere(150,14,14,false,mat)) as Sphere;
back = (addChild(new Shape) as Shape).graphics;
onResize();
addEventListener(Event.ENTER_FRAME, onFrame);
stage.addEventListener(Event.RESIZE, onResize);
}
private function onResize(e:Event=null):void
{
// viewの位置を調整
view.x = (stage.stageWidth - 800)/2;
view.y = (stage.stageHeight - 500)/2;
// 枠を描写
back.clear();
back.lineStyle(0, 0x777777);
back.drawRect(view.x, view.y, 800, 500);
}
private function onFrame(e:Event):void
{
// カメラの位置を計算
var _x:Number = Math.sin(theta * RADIAN) * radius;
var _y:Number = -Math.cos(theta * RADIAN) * radius;
theta ++;
controller.setObjectPosXYZ(_x, _y, 0);
controller.lookAtXYZ(0,0,0);
// 半径計算 (大きくなったり小さくなったり)
switch(flug)
{
case 1:
radius+=2;
if (radius > 600) flug=0;
break;
case 0:
radius-=2;
if (radius < 300) flug=1;
break;
}
// レンダリング
camera.render();
}
}
}
