forked from: 私はクルマ。タイヤはまだない
パネルのZソートもない(済)
* 法線(光沢)もない(済)
* タイヤがないから走れない(仕様です)
* マウスに反応もしない(暫定)
* ただクルクル回るだけ(相変わらず)
// forked from Kay's 私はクルマ。タイヤはまだない
/*
* パネルのZソートもない(済)
* 法線(光沢)もない(済)
* タイヤがないから走れない(仕様です)
* マウスに反応もしない(暫定)
* ただクルクル回るだけ(相変わらず)
*/
package {
import flash.display.*;
import flash.events.*;
import flash.geom.*;
[SWF(width=400,height=400,backgroundColor=0)]
public class Take05 extends Sprite {
private var axis_array:Array = new Array(Vector3D.X_AXIS, Vector3D.Y_AXIS, Vector3D.Z_AXIS);
private var cars:Array = new Array();
public function Take05():void {
addEventListener(MouseEvent.MOUSE_MOVE, wRotate);
for (var d:uint = 0; d < 3; d++) {
for (var h:uint = 0; h < 3; h++) {
for (var v:uint = 0; v < 3; v++) {
var car:Car = new Car(Math.floor(Math.random()*0xffffff));
car.x = 300*h-100;
car.y = 300*v-100;
car.z = 300*(3-d)+100;
car.axis = axis_array[Math.floor(Math.random()*3)];
car.nRotation = Math.random()*3-6;
car.mtx.prependRotation(Math.random()*90-180,axis_array[Math.floor(Math.random()*3)]);
car.mtx.prependScale(3,3,3);
car.render();
car.addEventListener(Event.ENTER_FRAME, xRotate);
addChild(car);
}
}
}
}
private function xRotate(e:Event):void {
var nR:Number = e.target.nRotation;
var axis:Vector3D = e.target.axis;
e.target.mtx.appendRotation(nR,axis);
e.target.render();
}
private function wRotate(e:MouseEvent):void {
root.transform.perspectiveProjection.projectionCenter = new Point(mouseX,mouseY);
}
}
}
import flash.display.*;
import flash.geom.*;
class Car extends Sprite {
public var vertices:Vector.<Number> = new Vector.<Number>();
public var normals:Vector.<Vector3D> = new Vector.<Vector3D>();
public var centers:Vector.<Vector3D> = new Vector.<Vector3D>();
private var uvt:Vector.<Number> = new Vector.<Number>();
private var panelInfo:Vector.<Number> = new Vector.<Number>();
private var faces:Vector.<Sprite> = new Vector.<Sprite>();
public var mtx:Matrix3D = new Matrix3D();
public var myColor:uint;
public var axis:Vector3D = new Vector3D();
public var nRotation:Number;
private const SWH:Number = 200;
private const SHH:Number = 200;
public function Car(color:uint):void {
myColor = color;
setApexes();
}
public function setApexes():void {
// 側面を描く頂点を取得
vertices.push(-22, 2, -15,// 0
-22, -4, -10, // 1
-10, -8, -12, // 2
0, -20, -10, // 3
12, -20, -10, // 4
18, -10, -15, // 5
26, -10, -13, // 6
28, 2, -15, // 7
14, 2, -15, // 8
-10, 2, -15); // 9
// 反対側のポイントを作成
var verticesNum:uint = vertices.length;
for (var i:uint = 0; i < verticesNum; i++) {
if (i % 3 == 2) {
vertices.push(vertices[i]*-1); // z値を反転
} else {
vertices.push(vertices[i]);
}
}
// Panell情報
var offset:uint = vertices.length/3/2;
panelInfo.push(3,4,2,5, 0x66cccc,0.8); // Left
panelInfo.push(4+offset,3+offset,5+offset,2+offset,0x66cccc,0.8); // Right
panelInfo.push(3+offset,3,2+offset,2, 0x66cccc,0.8); // Front
panelInfo.push(4,4+offset,5,5+offset, 0x66cccc,0.8); // Rear
panelInfo.push(1+offset,1,0+offset,0, myColor,1);
panelInfo.push(2+offset,2,1+offset,1, myColor,1);
panelInfo.push(4+offset,4,3+offset,3, myColor,1);
panelInfo.push(6+offset,6,5+offset,5, myColor,1);
panelInfo.push(7+offset,7,6+offset,6, myColor,1);
panelInfo.push(1,2,0,9, myColor,1);
panelInfo.push(2,5,9,8, myColor,1);
panelInfo.push(5,6,8,7, myColor,1);
panelInfo.push(2+offset,1+offset,9+offset,0+offset,myColor,1);
panelInfo.push(5+offset,2+offset,8+offset,9+offset,myColor,1);
panelInfo.push(6+offset,5+offset,7+offset,8+offset,myColor,1);
panelInfo.push(7,7+offset,8,8+offset, 0x666666,1);
panelInfo.push(8,8+offset,9,9+offset, 0x666666,1);
panelInfo.push(9,9+offset,0,0+offset, 0x666666,1);
// 総てのPanelの法線ベクトルを取得して格納しておく
var numPanel:uint = panelInfo.length/6;
for (i=0; i < numPanel; i++) {
var ind:uint = panelInfo[i*6]*3;
var pA:Vector3D = new Vector3D(vertices[ind],vertices[ind+1],vertices[ind+2]);
ind = panelInfo[i*6+1]*3;
var pB:Vector3D = new Vector3D(vertices[ind],vertices[ind+1],vertices[ind+2]);
ind = panelInfo[i*6+2]*3;
var pC:Vector3D = new Vector3D(vertices[ind],vertices[ind+1],vertices[ind+2]);
var vA:Vector3D = pB.subtract(pA);
var vB:Vector3D = pC.subtract(pB);
var vC:Vector3D = vA.crossProduct(vB);
vC.normalize();
normals.push(vC);
centers.push(pB.add(pC));
}
}
public function render():void {
var panels:Array = new Array();
var vout:Vector.<Number> = new Vector.<Number>();
Utils3D.projectVectors(mtx,vertices,vout,uvt); // 一気に2Dに投影
var numsPanel:uint = panelInfo.length/6;
for (var i:uint = 0; i < numsPanel; i++) {
var center:Vector3D = Utils3D.projectVector(mtx,centers[i]);
var dist:Number = Vector3D.distance(new Vector3D(SWH,SHH,-1000),center);
panels.push({num:i,d:dist});
}
panels = panels.sortOn("d",Array.DESCENDING | Array.NUMERIC);
graphics.clear();
for (i = 0; i < numsPanel; i++) {
var normal:Vector3D = Utils3D.projectVector(mtx,normals[panels[i].num]);
var ratio:Number = Vector3D.angleBetween(normal, new Vector3D(-0.5,-0.5,-1))/Math.PI+0.35;
var indices:Vector.<int> = new Vector.<int>();
var ioff:uint = panels[i].num*6;
indices.push(panelInfo[ioff+1],panelInfo[ioff+0],panelInfo[ioff+3]);
indices.push(panelInfo[ioff+2],panelInfo[ioff+3],panelInfo[ioff+0]);
var nColor:uint = panelInfo[ioff+4];
var nB:uint = nColor & 0xff;
var nG:uint = (nColor >> 8) & 0xff;
var nR:uint = (nColor >> 16) & 0xff;
nB = Math.floor(nB*ratio);
nG = Math.floor(nG*ratio);
nR = Math.floor(nR*ratio);
if (nB > 0xff) {
nB = 0xff;
} else if (nB < 0) {
nB = 0;
}
if (nG > 0xff) {
nG = 0xff;
} else if (nG < 0) {
nG = 0;
}
if (nR > 0xff) {
nR = 0xff;
} else if (nR < 0) {
nR = 0;
}
nColor = nR << 16 | nG << 8 | nB;
graphics.beginFill(nColor, panelInfo[ioff+5]);
graphics.drawTriangles(vout,indices,null,TriangleCulling.POSITIVE);
graphics.endFill();
}
}
}