/**
* Copyright hankuro ( http://wonderfl.net/user/hankuro )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/lzOv
*/
package
{
import flash.display.Sprite;
import flash.events.Event;
import flash.filters.ColorMatrixFilter;
import org.papervision3d.core.geom.renderables.Triangle3D;
import org.papervision3d.core.geom.renderables.Vertex3D;
import org.papervision3d.core.geom.TriangleMesh3D;
import org.papervision3d.core.math.Number3D;
import org.papervision3d.core.math.NumberUV;
import org.papervision3d.core.utils.MeshUtil;
import org.papervision3d.materials.ColorMaterial;
import org.papervision3d.objects.primitives.Sphere;
import org.papervision3d.view.BasicView;
import org.papervision3d.core.math.Matrix3D;
[SWF(width = 500, height = 500, backgroundColor = 0x000000)]
/**
*
* TriangleMesh3D 法線試験
* 「ひとりごと」
* papervision3dがだんだん納得出来てきたぞ!
*
*/
public class Main extends BasicView
{
public var light:Light = new Light();
public var point3D:Array;
public var sphere:Sphere;
public var mesh:Array;
public var tria:Triangle3D;
private var uvA:NumberUV;
private var uvC:NumberUV;
private var uvB:NumberUV;
private var v0:Vertex3D;
private var v1:Vertex3D;
private var v2:Vertex3D;
private var color_m:ColorMaterial;
public function Main()
{
super (500, 500, false, false);
camera.z = -400;
sphere = new Sphere(new ColorMaterial(0xFFFFFF, 0), 150, 20, 20);
mesh = new Array(sphere.geometry.faces.length);
for ( var i:Number = 0; i < mesh.length; i++) {
tria = sphere.geometry.faces[i];
mesh[i] = new TriangleMesh3D(new ColorMaterial(0xFF0000,0), new Array(), new Array(), null );
v0 = new Vertex3D( tria.vertices[0].x, tria.vertices[0].y, tria.vertices[0].z );
v1 = new Vertex3D( tria.vertices[1].x, tria.vertices[1].y, tria.vertices[1].z );
v2 = new Vertex3D( tria.vertices[2].x, tria.vertices[2].y, tria.vertices[2].z );
mesh[i].geometry.vertices.push( v0 );
mesh[i].geometry.vertices.push( v1 );
mesh[i].geometry.vertices.push( v2 );
uvA = new NumberUV( 0, 0 );
uvC = new NumberUV( 1, 0 );
uvB = new NumberUV( 0, 1 );
mesh[i].geometry.faces.push( new Triangle3D( mesh[i], new Array(v0,v1,v2), null, new Array(uvA,uvC,uvB) ));
mesh[i].geometry.ready = true;
scene.addChild(mesh[i]);
}
startRendering();
addEventListener(Event.ENTER_FRAME, onLoop);
}
public function onLoop(evt:Event):void {
light.set_Light_point(mouseX - stage.stageWidth / 2, (mouseY - stage.stageHeight / 2)*-1,-150);
var c:uint;
for (var i:Number = 0; i < mesh.length; i++) {
mesh[i].rotationY += 1;
point3D = new Array(3);
var s:TriangleMesh3D;
for (var n:Number = 0; n < 3; n++) {
point3D[n] = new Number3D(mesh[i].geometry.vertices[n].x, mesh[i].geometry.vertices[n].y, mesh[i].geometry.vertices[n].z);
Matrix3D.multiplyVector3x3(mesh[i].transform, point3D[n]);
}
c = light.getAdjustedColor( { p0_x: point3D[0].x, p0_y: point3D[0].y , p0_z: point3D[0].z,
p1_x: point3D[1].x, p1_y: point3D[1].y , p1_z: point3D[1].z,
p2_x: point3D[2].x, p2_y: point3D[2].y , p2_z: point3D[2].z },
0x00FFFF);
color_m = new ColorMaterial(c);
mesh[i].material = color_m;
}
}
}
}
class Light
{
public var x:Number;
public var y:Number;
public var z:Number;
private var _brightness:Number;
public var triangle_data:Object;
private var color:uint;
public function Light(x:Number = -100, y:Number = -100, z:Number = -100, brightness:Number = 1)
{
this.x = x;
this.y = y;
this.z = z;
this.brightness = brightness;
}
public function set_Light_point(x:Number , y:Number , z:Number):void{
this.x = x;
this.y = y;
this.z = z;
}
public function set brightness(b:Number):void
{
_brightness = Math.max(b, 0);
_brightness = Math.min(_brightness, 1);
}
public function get brightness():Number
{
return _brightness;
}
public function getAdjustedColor(p:Object,color:uint = 0xFF0000):uint
{
triangle_data = p;
this.color = color;
var red:Number = color >> 16;
var green:Number = color >> 8 & 0xff;
var blue:Number =color & 0xff;
var lightFactor:Number = getLightFactor();
red *= lightFactor;
green *= lightFactor;
blue *= lightFactor;
return red << 16 | green << 8 | blue;
}
private function getLightFactor():Number
{
var ab:Object = new Object();
ab.x = triangle_data.p0_x - triangle_data.p1_x;
ab.y = triangle_data.p0_y - triangle_data.p1_y;
ab.z = triangle_data.p0_z - triangle_data.p1_z;
var bc:Object = new Object();
bc.x = triangle_data.p1_x - triangle_data.p2_x;
bc.y = triangle_data.p1_y - triangle_data.p2_y;
bc.z = triangle_data.p1_z - triangle_data.p2_z;
var norm:Object = new Object();
norm.x = (ab.y * bc.z) - (ab.z * bc.y);
norm.y = -((ab.x * bc.z) - (ab.z * bc.x));
norm.z = (ab.x * bc.y) - (ab.y * bc.x);
var dotProd:Number = norm.x * x +
norm.y * y +
norm.z * z;
var normMag:Number = Math.sqrt(norm.x * norm.x +
norm.y * norm.y +
norm.z * norm.z);
var lightMag:Number = Math.sqrt(x * x +
y * y +
z * z);
return (Math.acos(dotProd / (normMag * lightMag)) / Math.PI)
* _brightness;
}
}