マウスのドラッグで3Dモデルが回転するサンプル。
3頂点による面クラス(Face.as)と頂点クラス(Vertex.as)は Flex SDK で回転する3Dオブジェクト描画のサンプルを作る にあるものを流用。
メインクラスのソースコード(GuruGuru3DModel.as)
package {
import flash.display.*;
import flash.events.*;
import flash.text.*;
import flash.utils.*;
public class GuruGuru3DModel extends Sprite {
// 描画キャンバス
private var shape:Shape;
// 描画補助情報
private var m_Scale:Number = 100;
private var Center_x:Number = 100;
private var Center_y:Number = 100;
// 3Dモデル情報
private var face:Array = new Array();
private var controller:Sprite; // マウスイベント取得用
private var moused:Boolean = false; // マウスボタン押下中
private var mousex:Number = -1; // マウスX位置
private var mousey:Number = -1; // マウスY位置
private var angle:Number = 6;
public function GuruGuru3DModel() {
// 3Dモデル描画用
shape = new Shape();
addChild(shape);
// マウスイベント取得用。こんなんでいいのかなぁ……
controller = new Sprite();
controller.alpha = 0;
controller.graphics.beginFill(0x00FF00);
controller.graphics.drawRect(0,0,240,240);
controller.graphics.endFill();
addChild(controller);
// 頂点
var vertex:Array = new Array();
vertex[0] = new Vertex(-1, 0, 0);
vertex[1] = new Vertex( 0, 0, 1);
vertex[2] = new Vertex( 0, 1, 0);
vertex[3] = new Vertex( 1, 0, 0);
vertex[4] = new Vertex( 0,-1, 0);
vertex[5] = new Vertex( 0, 0,-1);
// 辺
face[0] = new Face(vertex[1], vertex[4], vertex[2]);
face[1] = new Face(vertex[1], vertex[0], vertex[4]);
face[2] = new Face(vertex[1], vertex[2], vertex[0]);
face[3] = new Face(vertex[3], vertex[2], vertex[4]);
face[4] = new Face(vertex[0], vertex[5], vertex[4]);
face[5] = new Face(vertex[4], vertex[5], vertex[3]);
face[6] = new Face(vertex[3], vertex[5], vertex[2]);
face[7] = new Face(vertex[2], vertex[5], vertex[0]);
// 3Dモデルを描画
drawModel();
// マウスイベント登録
controller.addEventListener(MouseEvent.MOUSE_DOWN, mousedown);
controller.addEventListener(MouseEvent.MOUSE_UP, mouseup);
controller.addEventListener(MouseEvent.MOUSE_MOVE, mousemove);
}
private function mousedown(evt:MouseEvent):void {
if(!moused){
moused = true;
mousex = evt.localX;
mousey = evt.localY;
}
}
private function mouseup(evt:MouseEvent):void {
moused = false;
mousex = -1;
mousey = -1;
}
private function mousemove(evt:MouseEvent):void {
if(moused){
var x:Number = evt.localX - mousex;
var y:Number = evt.localY - mousey;
mousex = evt.localX;
mousey = evt.localY;
rotate(y, x, 0);
drawModel();
}
}
private function drawModel():void {
// 前の描画を消去
shape.graphics.clear();
// 3Dモデルを描画
for(var i:int=0; i < face.length; i++) {
var x0:Number = face[i].vertex[0].x * m_Scale + Center_x;
var x1:Number = face[i].vertex[1].x * m_Scale + Center_x;
var x2:Number = face[i].vertex[2].x * m_Scale + Center_x;
var y0:Number = -face[i].vertex[0].y * m_Scale + Center_y;
var y1:Number = -face[i].vertex[1].y * m_Scale + Center_y;
var y2:Number = -face[i].vertex[2].y * m_Scale + Center_y;
// 奥行き(Z軸)
var depth:Number = 3 - (face[i].vertex[0].z + face[i].vertex[1].z + face[i].vertex[2].z);
// 描画ペンの太さ
var penWidth:Number = depth;
// アルファ値(0~1を指定) しかしこのプログラムでは意味がないような...
var penAlpha:Number = depth / 3;
shape.graphics.lineStyle(penWidth, 0xff0000, penAlpha);
shape.graphics.moveTo(x0, y0);
shape.graphics.lineTo(x1, y1);
shape.graphics.lineTo(x2, y2);
shape.graphics.lineTo(x0, y0);
}
}
// ActionScript の Math.sin とか Math.cos には
// 角度(°)ではなくラジアンが必要
private static function toRadians(degree:Number):Number{
return degree / 180.0 * Math.PI;
}
// 3Dモデルを回転
private function rotate(x:Number,y:Number,z:Number):void{
for(var i:int=0; i<face.length; i++) {
face[i].rotate(toRadians(x), toRadians(y), toRadians(z));
}
}
}
}
MOUSE_UP が確実に呼ばれるわけではないみたい? マウスアップしてもグリグリ回転できるときがある。
tags: zlashdot Flash 3D Flash Flex
Posted by NI-Lab. (@nilab)