topical media & game development

talk show tell print

student-ar-org-papervision3d-core-render-command-RenderLine.ax

student-ar-org-papervision3d-core-render-command-RenderLine.ax [swf] [flash] flex


  package org.papervision3d.core.render.command
  {
          
          
@Author Ralph Hauwert

  
           
          import flash.display.Graphics;
          import flash.geom.Point;
          
          import org.papervision3d.core.geom.renderables.Line3D;
          import org.papervision3d.core.geom.renderables.Vertex3DInstance;
          import org.papervision3d.core.math.Number2D;
          import org.papervision3d.core.math.Number3D;
          import org.papervision3d.core.render.data.RenderHitData;
          import org.papervision3d.core.render.data.RenderSessionData;
          import org.papervision3d.materials.special.LineMaterial;        
          
          public class @ax-student-ar-org-papervision3d-core-render-command-RenderLine extends RenderableListItem implements IRenderListItem
          {
                  
                  public var line:Line3D;
                  public var renderer:LineMaterial;
                  
                  // rather that create and clean up vector objects, we'll store all our temp working vectors as statics
                  private static var lineVector:Number3D = Number3D.ZERO; 
                  private static var mouseVector:Number3D = Number3D.ZERO;
                  
                  //premade Number2Ds for hittest function
                private var p : Number2D;
                  private var l1 : Number2D;
                  private var l2 : Number2D;
                  private var v : Number2D;
                  private var cp3d : Number3D; 
  
                  public var v0:Vertex3DInstance;
          public var v1:Vertex3DInstance;
          public var cV:Vertex3DInstance;
                  
                  public var size:Number;
                  public var length:Number;
  
                  public function @ax-student-ar-org-papervision3d-core-render-command-RenderLine(line:Line3D)
                  {
                          super();
                          this.renderable = Line3D;
                          this.renderableInstance = line;
                          this.line = line;
                          
                          v0 = line.v0.vertex3DInstance;
                          v1 = line.v1.vertex3DInstance;
                          cV = line.cV.vertex3DInstance;
                          
                          // pre-made for hittest
                          p = new Number2D(); 
                          l1 = new Number2D(); 
                          l2 = new Number2D(); 
                          v = new Number2D();         
                          cp3d = new Number3D();                 
                          
                  }
                  
                  override public function render(renderSessionData:RenderSessionData, graphics:Graphics):void
                  {
  
                          renderer.drawLine(this, graphics, renderSessionData);
                          
                  }
                  
                  override public function hitTestPoint2D(point:Point, rhd:RenderHitData):RenderHitData
                  {
                          if(renderer.interactive)
                          {
                                  var linewidth:Number = line.size; 
                                  
                                  p.reset(point.x, point.y); 
                                  
                                  l1.reset(line.v0.vertex3DInstance.x, line.v0.vertex3DInstance.y);
                                  l2.reset(line.v1.vertex3DInstance.x, line.v1.vertex3DInstance.y);
                  
                                  // get the vector for the line
                                  v.copyFrom(l2); 
                                  v.minusEq(l1); 
                                  
                                  // magic formula for calculating how how far along the line a perpendicular 
                                  // coming from the line to the point would hit. If this number is between 0 and 1 
                                  // the point is closest to a part of the line that exists.
                                  var u:Number = (((p.x - l1.x)*(l2.x - l1.x)) + ((p.y-l1.y)*(l2.y - l1.y)))/((v.x*v.x)+(v.y*v.y)); 
                                  
                                  if((u>0)&&(u<1)) 
                                  {
                                  
                                          // so then to work out that collision point multiply v by u and add it to l1
                                          v.multiplyEq(u); 
                                          v.plusEq(l1); 
                                          
                                          // then get the vector between the collision point and the mousepoint
                                          v.minusEq(p); 
                                          //var dist:Number2D = Number2D.subtract(cp, p); 
                                          
                                          // and get the magnitude of that distance vector, squared
                                          var d:Number =  (v.x*v.x)+(v.y*v.y);
                                          
                                          // and if it's less than the linewidth squared we have a hit
                                          if(d<(linewidth*linewidth))
                                          {
                                                  rhd.displayObject3D = line.instance; 
                                                  rhd.material = renderer;
                                                  rhd.renderable = line; 
                                                  rhd.hasHit = true;
                                                  
                                                  //TODO UPDATE 3D hit point and UV
                                                  // currently we're just moving u along the 3D line, but this isn't accurate.
                                                  cp3d.reset(line.v1.x-line.v0.x, line.v1.y-line.v0.y, line.v1.x-line.v0.x);
                                                  cp3d.x*=u; 
                                                  cp3d.y*=u; 
                                                  cp3d.z*=u; 
                                                  cp3d.x+=line.v0.x; 
                                                  cp3d.y+=line.v0.y; 
                                                  cp3d.z+=line.v0.z; 
                                                  
                                                  rhd.x = cp3d.x; 
                                                  rhd.y = cp3d.y; 
                                                  rhd.z = cp3d.z; 
                                                  rhd.u = 0;
                                                  rhd.v = 0; 
                                                  return rhd; 
                                          }
                                          
                                  }
                          }
                          return rhd;
                  }
                  
                  
                  override public function getZ(x:Number, y:Number, focus:Number):Number{
                
              ax = v0.x;
              ay = v0.y;
              az = v0.z;
              bx = v1.x;
              by = v1.y;
              bz = v1.z;
  
              if ((ax == x) && (ay == y))
                  return az;
  
              if ((bx == x) && (by == y))
                  return bz;
  
              dx = bx - ax;
              dy = by - ay;
  
              azf = az / focus;
              bzf = bz / focus;
  
              faz = 1 + azf;
              fbz = 1 + bzf;
  
              xfocus = x;
              yfocus = y;
  
              axf = ax*faz - x*azf;
              bxf = bx*fbz - x*bzf;
              ayf = ay*faz - y*azf;
              byf = by*fbz - y*bzf;
  
              det = dx*(axf - bxf) + dy*(ayf - byf);
              db = dx*(axf - x) + dy*(ayf - y);
              da = dx*(x - bxf) + dy*(y - byf);
  
              return (da*az + db*bz) / det;
                  }
                  
                  
                  /*
                  Quad Vars Don't Touch
  		*/
                  private var ax:Number;
          private var ay:Number;
          private var az:Number;
          private var bx:Number;
          private var by:Number;
          private var bz:Number;
          private var dx:Number;
          private var dy:Number;
          private var azf:Number;
          private var bzf:Number;
          private var faz:Number;
          private var fbz:Number;
          private var xfocus:Number;
          private var yfocus:Number;
          private var axf:Number;
          private var bxf:Number;
          private var ayf:Number;
          private var byf:Number;
          private var det:Number;
          private var db:Number;
          private var da:Number;
          
         
                  
          }
  }


(C) Æliens 04/09/2009

You may not copy or print any of this material without explicit permission of the author or the publisher. In case of other copyright issues, contact the author.