Bend-pv3d中可使3D物体弯曲的类
2009-10-19 00:00:00 来源:WEB开发网package com.everydayflash.pv3d.modifiers {
import org.papervision3d.objects.DisplayObject3D;
import org.papervision3d.objects.parsers.Collada;
import org.papervision3d.objects.primitives.Cone;
import org.papervision3d.objects.primitives.Cube;
import org.papervision3d.objects.primitives.Cylinder;
import org.papervision3d.objects.primitives.Plane;
import org.papervision3d.core.proto.MaterialObject3D;
import org.papervision3d.core.geom.renderables.Vertex3D;
import org.papervision3d.objects.primitives.Sphere;
public class Bend {
private var target:DisplayObject3D;
private var w:Number;
private var h:Number;
private var d:Number;
private var mx:Number;
private var my:Number;
private var mz:Number;
public static var X:int = 0;
public static var Y:int = 1;
public static var Z:int = 2;
public static var NONE:int = 0;
public static var LEFT:int = 1;
public static var RIGHT:int = 2;
public var constraint:int = NONE;
private var base:Array;
private var _force:Number;
private var _offset:Number;
public var U_AXIS:int;
public var V_AXIS:int;
public var shadowMode:Boolean = false;
public function Bend(_target:DisplayObject3D) {
target = _target;
_force = 0;
_offset = .5;
if (_target is Collada) throw new Error("Bend does not work with Collada objects.");
freezeVertices();
}
public function freezeVertices():void {
base = new Array();
var vs:Array = target.geometry.vertices;
var vc:int = vs.length;
for (var i:int = 0; i < vc; i++) {
var v:Vertex3D = vs[i] as Vertex3D;
base.push([v.x, v.y, v.z]);
if (i == 0) {
mx = w = v.x;
my = h = v.y;
mz = d = v.z;
} else {
mx = Math.min(mx, v.x);
my = Math.min(my, v.y);
mz = Math.min(mz, v.z);
w = Math.max(w, v.x);
h = Math.max(h, v.y);
d = Math.max(d, v.z);
}
}
w = w - mx;
h = h - my;
d = d - mz;
var maxe:Number = Math.max(d, Math.max(w, h));
if (d == h && d == w) {
// This is a sphere, bending spheres look weird for any option
U_AXIS = 2;
V_AXIS = 2;
} else if (maxe == w) {
U_AXIS = 0;
V_AXIS = 2;
} else if (maxe == h) {
U_AXIS = 1;
V_AXIS = 2;
} else if (maxe == d) {
U_AXIS = 2;
V_AXIS = 1;
}
}
public function reset():void {
var vs:Array = target.geometry.vertices;
var vc:int = vs.length;
for (var i:int = 0; i < vc; i++) {
var v:Vertex3D = vs[i] as Vertex3D;
v.x = base[i][0] as Number;
v.y = base[i][1] as Number;
v.z = base[i][2] as Number;
}
}
public function quickBend(force:Number, offset:Number):void {
bend(U_AXIS, V_AXIS, force, offset);
}
public function bend(uaxis:int, vaxis:int, force:Number, offset:Number):void {
reset();
if (force == 0) {
return;
}
offset = Math.max(0, offset);
offset = Math.min(1, offset);
_bend(uaxis, vaxis, force, offset);
}
private function _bend(uaxis:int, vaxis:int, force:Number, offset:Number):void {
var pto:Number;
var ptd:Number;
if (uaxis == 0) {
pto = mx;
ptd = w;
} else if (uaxis == 1) {
pto = my;
ptd = h;
} else if (uaxis == 2) {
pto = mz;
ptd = d;
}
var vs:Array = target.geometry.vertices;
var vc:int = vs.length;
var distance:Number = pto + ptd * offset;
var radius:Number = ptd / Math.PI / force;
var angle:Number = Math.PI * 2 * (ptd / (radius * Math.PI * 2));
for (var i:int = 0; i < vc; i++) {
var v:Vertex3D = vs[i] as Vertex3D;
var portion:Number = (base[i][uaxis] - pto) / ptd;
var fa:Number = ((Math.PI / 2) - angle * offset) + (angle * portion);
if (constraint == LEFT && portion <= offset) continue;
if (constraint == RIGHT && portion >= offset) continue;
var op:Number = Math.sin(fa) * (radius + base[i][vaxis]) - radius;
var ow:Number = distance - Math.cos(fa) * (radius + base[i][vaxis]);
if (!shadowMode) {
if (vaxis == X) v.x = op;
else if (vaxis == Y) v.y = op;
else if (vaxis == Z) v.z = op;
}
if(uaxis == X) v.x = ow;
else if (uaxis == Y) v.y = ow;
else if(uaxis == Z) v.z = ow;
}
}
public function get force():Number {
return _force;
}
public function set force(f:Number):void {
_force = f;
bend(U_AXIS, V_AXIS, _force, _offset);
}
public function get offset():Number {
return _offset;
}
public function set offset(o:Number):void {
_offset = o;
bend(U_AXIS, V_AXIS, _force, _offset);
}
}
}
赞助商链接