package {
import flash.display.*;
import flash.events.*;
import flash.filters.*;
import flash.geom.*;
import org.papervision3d.core.*;
import org.papervision3d.core.math.*;
import org.papervision3d.core.geom.* ;
import org.papervision3d.scenes.*;
import org.papervision3d.objects.primitives.*;
import org.papervision3d.cameras.*;
import org.papervision3d.materials.*;
import org.papervision3d.materials.shadematerials.* ;
import org.papervision3d.materials.utils.*;
import org.papervision3d.view.*;
import org.papervision3d.render.*;
import org.papervision3d.lights.*;
import org.papervision3d.materials.special.LineMaterial ;
[SWF(width="600", height="600", backgroundColor="#ffffff")]
public class Shadow extends Sprite{
private var renderer:BasicRenderEngine = new BasicRenderEngine();
private var viewport:Viewport3D = new Viewport3D(600, 600, false, true);
private var scene:Scene3D = new Scene3D();
private var camera:Camera3D = new Camera3D();
private var pointLight:PointLight3D;
private var parentCube:Cube;
private var childCube:Cube;
private var bd:BitmapData;
private var LEN:Number = 100;
private var lastPoint:Point;
private var mouseDown:Boolean = false;
public function Shadow():void
{
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE ;
addChild(viewport);
camera.y = 1200;
camera.z = -4400;
camera.x = 0;
camera.focus = 4400;
camera.zoom = 1.5;
pointLight = new PointLight3D();
pointLight.y = 300;
pointLight.z = -100;
bd = new BitmapData(800, 800, false, 0xff);
parentCube = new Cube(new MaterialsList({all: new BitmapMaterial(bd)}),800,800,10);
parentCube.y = -200;
scene.addChild(parentCube);
childCube = new Cube(new MaterialsList({
all:new PhongMaterial(pointLight, 0xFF88FF, 0x111111, 1)}), LEN*2, LEN*2, LEN*2);
scene.addChild(childCube);
stage.addEventListener(KeyboardEvent.KEY_DOWN , function(e:KeyboardEvent):void{
rotate(e.keyCode);
});
drawLines();
renderer.renderScene(scene, camera, viewport);
stage.addEventListener(MouseEvent.MOUSE_DOWN, function(e:*):void{
mouseDown = true;
lastPoint = new Point(stage.mouseX, stage.mouseY);
});
stage.addEventListener(MouseEvent.MOUSE_UP, function(e:*):void{
mouseDown = false;
lastPoint = new Point(stage.mouseX, stage.mouseY);
});
stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
}
private function onMouseMove(e:*):void{
if(!mouseDown)
return;
var xx:Number = stage.mouseX - lastPoint.x;
var yy:Number = -stage.mouseY + lastPoint.y;
if(yy == 00) return;
var rotAxis:Number3D = new Number3D();
rotAxis.z = 0;
rotAxis.x = yy;
rotAxis.y = -xx;
// calculate the amount of rotation
var rotAngle:Number = Math.sqrt(xx*xx + yy*yy)/200*Math.PI;
if(rotAngle == 0) return;
rotAxis.normalize();
childCube.transform =
Matrix3D.multiply(Matrix3D.rotationMatrix(rotAxis.x, rotAxis.y, 0, rotAngle),
childCube.transform);
lastPoint = new Point(stage.mouseX, stage.mouseY);
drawLines();
renderer.renderScene(scene, camera, viewport);
}
private function rotate(keyCode:int):void{
switch (keyCode){
case 37 :// ←
childCube.yaw(1);
break;
case 39 :// →
childCube.yaw(-1);
break;
case 38 :// ↑
childCube.pitch(1);
break;
case 40 :// ↓
childCube.pitch(-1);
break;
}
drawLines();
renderer.renderScene(scene, camera, viewport);
}
private function drawLines():void{
var points:Array =
[new Number3D(LEN, +LEN, LEN),
new Number3D(LEN, +LEN, -LEN),
new Number3D(-LEN, +LEN, -LEN),
new Number3D(-LEN, +LEN, LEN),
new Number3D(LEN, -LEN, LEN),
new Number3D(LEN, -LEN, -LEN),
new Number3D(-LEN, -LEN, -LEN),
new Number3D(-LEN, -LEN, LEN)
];
var pointsShadow:Array = [];
for each (var p:Number3D in points){
Matrix3D.multiplyVector3x3(childCube.transform, p);
pointsShadow.push(new Point(p.x + 400, 400 - p.z));
}
points = ConvexHull.getConvexHull(pointsShadow);
if(points.length < 4)
trace(points.length);
var sp:Sprite = new Sprite();
sp.graphics.lineStyle(5,0x0);
sp.graphics.beginFill(0x0);
bd.fillRect(new Rectangle(0,0,800,800), 0xeeeeee);
sp.graphics.moveTo(points[i].x, points[i].y);
for (var i:int = 1 ; i < points.length; i++){
sp.graphics.lineTo(points[i].x, points[i].y);
}
sp.graphics.lineTo(points[0].x, points[0].y);
sp.graphics.endFill();
bd.draw(sp);
bd.applyFilter(bd, new Rectangle(0,0,800,800), new Point(0,0), new BlurFilter(30,30,BitmapFilterQuality.HIGH));
}
}
}
import flash.geom.*;
internal class ConvexHull{
public static function getConvexHull(points:Array):Array {
var result:Array = [];
var index:int;
var topIndex:int;
// 先頭のインデックスを求める
var p1:Point = new Point(-100,-100);
var p2:Point = new Point(0,-100);
topIndex = index = getNextIndex(points, p2, p1);
var cnt:int = 0;
while(cnt++ <= points.length){
p1 = p2;
p2 = points[index];
result.push(p2);
index = getNextIndex(points, p2, p1);
if(index == topIndex)
break;
}
return result;
}
private static function distance( p1:Point, p2:Point ):Number{
var dx:Number = p2.x - p1.x;
var dy:Number = p2.y - p1.y;
return Math.sqrt( dx*dx+ dy*dy );
}
private static function getNextIndex(points:Array, p2:Point, p1:Point):int{
var minIndex:int = 0;
var min:Number = Math.PI*2;
var minLen:Number = -1;
var v1:Point = new Point(p2.x - p1.x, p2.y - p1.y);
for( var j:int =0; j < points.length; j++ ) {
if(!(points[j].x == p2.x && points[j].y == p2.y)){
var v2:Point = new Point(points[j].x - p2.x, points[j].y - p2.y);
var rad:Number = getTheta(v1, v2);
// 角度が同じ場合、近いほうを優先
if(rad == min){
if(distance(points[j], p2) < minLen){
minIndex = j;
min = rad;
minLen = distance(points[j], p2);
}
}else if(rad < min){
minIndex = j;
min = rad;
minLen = distance(points[j], p2);
}
}
}
return minIndex;
}
private static function getTheta(p1:Point, p2:Point):Number{
var len1:Number = Math.sqrt(p1.x*p1.x + p1.y*p1.y);
var len2:Number = Math.sqrt(p2.x*p2.x + p2.y*p2.y);
if(len1 == 0 || len2==0)
return 0;
p1.x = p1.x/len1;
p1.y = p1.y/len1;
p2.x = p2.x/len2;
p2.y = p2.y/len2;
var dot:Number = p1.x*p2.x + p1.y*p2.y;
var theta:Number = Math.acos(dot);
return theta;
}
}
Author:yamasv@gmail.com
コメント、トラックバック、リンクはお気軽に
-->
| 日 | 月 | 火 | 水 | 木 | 金 | 土 |
|---|---|---|---|---|---|---|
| - | - | - | - | - | 1 | 2 |
| 3 | 4 | 5 | 6 | 7 | 8 | 9 |
| 10 | 11 | 12 | 13 | 14 | 15 | 16 |
| 17 | 18 | 19 | 20 | 21 | 22 | 23 |
| 24 | 25 | 26 | 27 | 28 | 29 | 30 |
| 31 | - | - | - | - | - | - |