WEB开发网
开发学院图形图像Flash Bend-pv3d中可使3D物体弯曲的类 阅读

Bend-pv3d中可使3D物体弯曲的类

 2009-10-19 00:00:00 来源:WEB开发网   
核心提示:packagecom.everydayflash.pv3d.modifiers{importorg.papervision3d.objects.DisplayObject3D;importorg.papervision3d.objects.parsers.Collada;importorg.papervision3d.

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);
  }
 }
}

Tags:Bend pv 物体

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接