topical media & game development

talk show tell print

student-ar-org-papervision3d-core-clipping-FrustumClipping.ax

student-ar-org-papervision3d-core-clipping-FrustumClipping.ax [swf] flex


  package org.papervision3d.core.clipping
  {
          import org.papervision3d.cameras.Camera3D;
          import org.papervision3d.core.geom.renderables.Triangle3D;
          import org.papervision3d.core.math.Matrix3D;
          import org.papervision3d.core.math.Number3D;
          import org.papervision3d.core.math.Plane3D;
          import org.papervision3d.core.math.util.ClassificationUtil;
          import org.papervision3d.core.math.util.TriangleUtil;
          import org.papervision3d.core.proto.MaterialObject3D;
          import org.papervision3d.core.render.data.RenderSessionData;
          import org.papervision3d.objects.DisplayObject3D;
          
          public class @ax-student-ar-org-papervision3d-core-clipping-FrustumClipping extends DefaultClipping
          {
                  
                  public var selectedPlanes:int = 0;
                  private var project_scale:Number = 1;
                  private var angle_horizontal:Number =  0;
                  private var angle_vertical:Number   =  0;
                  private var sh:Number               =  0;
                  private var sv:Number               =  0;
                  private var ch:Number               =  0;
                  private var cv:Number               =  0;
                  
  
                  private var _bottomPlane:Plane3D = new Plane3D();
                  private var _topPlane:Plane3D = new Plane3D();
                  private var _leftPlane:Plane3D = new Plane3D();
                  private var _rightPlane:Plane3D = new Plane3D();
                  private var _nearPlane:Plane3D = new Plane3D();
                  
                  private var bNormal:Number3D = new Number3D();
                  private var tNormal:Number3D = new Number3D(); 
                  private var lNormal:Number3D = new Number3D();
                  private var rNormal:Number3D = new Number3D();
                  private var nNormal:Number3D = new Number3D();
                  
                  private var _forward:Number3D = new Number3D();
                  
                  private var repo:Array = new Array();
                  private var cTriangle:Number = 0;
                  
                  public function @ax-student-ar-org-papervision3d-core-clipping-FrustumClipping(planes:Number = 2)
                  {
                          super();
                          
                          selectedPlanes = planes;
                          
                  }
                  
                  public override function reset(renderSessionData:RenderSessionData):void{
                           
                            project_scale = 265;//renderSessionData.camera.fov*(renderSessionData.camera.zoom/10);
                           
                            angle_horizontal =  Math.atan2(renderSessionData.viewPort.viewportWidth/2,project_scale)-0.0001;
                            angle_vertical  =  Math.atan2(renderSessionData.viewPort.viewportHeight/2,project_scale)-0.0001;
                            sh          =  Math.sin(angle_horizontal);
                            sv            =  Math.sin(angle_vertical);
                            ch           =  Math.cos(angle_horizontal);
                            cv          =  Math.cos(angle_vertical);
                            
                            cTriangle = 0;
  
                  }
                  
                  public override function setDisplayObject(object:DisplayObject3D, renderSessionData:RenderSessionData):void{
                          getPlanes(Camera3D(renderSessionData.camera), object);
                  }
                  
                  public override function testFace(triangle:Triangle3D, object:DisplayObject3D, renderSessionData:RenderSessionData):Boolean{
  
                          /* var classification:Number = 0;
                          
                          if((selectedPlanes & NEAR)){
                                  classification =ClassificationUtil.classifyTriangle(triangle, _nearPlane);
                                  if(classification == ClassificationUtil.STRADDLE || classification == ClassificationUtil.BACK)
                                          return true;
                                  
                          }
                                  
                          if((selectedPlanes & BOTTOM)){
                                  classification = ClassificationUtil.classifyTriangle(triangle, _bottomPlane);
                                  if(classification == ClassificationUtil.STRADDLE || classification == ClassificationUtil.BACK)
                                          return true;
                          }
                          
                          if((selectedPlanes & TOP)){
                                  classification = ClassificationUtil.classifyTriangle(triangle, _topPlane);
                                  if(classification == ClassificationUtil.STRADDLE || classification == ClassificationUtil.BACK)
                                          return true;        
                          }
                          
                          if((selectedPlanes & LEFT)){
                                  classification = ClassificationUtil.classifyTriangle(triangle, _leftPlane);
                                  if(classification == ClassificationUtil.STRADDLE || classification == ClassificationUtil.BACK)
                                          return true;
                          }
                          
                          if((selectedPlanes & RIGHT)){
                                  classification = ClassificationUtil.classifyTriangle(triangle, _rightPlane);
                                  if(classification == ClassificationUtil.STRADDLE || classification == ClassificationUtil.BACK)
                                          return true;
                          }
                                  
                          return false; */
                          
                          //testing is now needed in the actual loop, so lets not waste time
                          return true;
  
                  }
                  
                  private function getPlanes(camera:Camera3D, object:DisplayObject3D):void{
                          
                          
                          var cMatrix:Matrix3D = Matrix3D.inverse(object.view);
                          var cPos:Number3D = new Number3D(cMatrix.n14, cMatrix.n24, cMatrix.n34);
                          
                          setNearPlane(cPos, cMatrix, camera);
                          setPlane(_bottomPlane, bNormal, cPos, cMatrix, 0, -cv, sv);
                          setPlane(_topPlane, tNormal, cPos, cMatrix, 0, cv, sv);
                          setPlane(_leftPlane, lNormal, cPos, cMatrix, ch, 0, sh);
                          setPlane(_rightPlane, rNormal, cPos, cMatrix, -ch, 0, sh);
                          
                  }
                  
                  private function setNearPlane(pos:Number3D, view:Matrix3D, camera:Camera3D):void{
                          
                          
                          nNormal.reset(view.n13, view.n23, view.n33);
                          
                          _forward.reset(view.n13, view.n23, view.n33);
                          _forward.multiplyEq(camera.near);
                          _forward = Number3D.add(_forward, pos);
                          
                          _nearPlane.setNormalAndPoint(nNormal, _forward);
                          
                  }
                  
                  private function setPlane(plane:Plane3D, norm:Number3D, pos:Number3D, view:Matrix3D, x:Number, y:Number, z:Number, d:Number=0):void{
                          norm.reset(x, y, z);
                          Matrix3D.multiplyVector3x3(view, norm);
                          plane.setNormalAndPoint(norm, pos);
                          
                  }
                  
                  private function getNextTri():Triangle3D{
                          
                          var t:Triangle3D;
                          
                          if(repo.length == cTriangle){
                                  t = new Triangle3D(null, null);
                                  repo.push(t);
                                  cTriangle++;
                                  return t;
                          }
                          
                          t = repo[cTriangle];
                          cTriangle++;
                          return t;
                          
                          
                  }
                  
                  
                  private function testClipped(plane:Plane3D, triangle:Triangle3D, object:DisplayObject3D, outputs:Array):void{
                          
                          //var tests:Array = outputs;
                          var results:Array = [];
                          
                          var length:Number = outputs.length;
                          
                          for(var i:int=length-1;i>=0;i--){
                                  
                                  var t:Triangle3D = outputs[i];
                                  
                                  var classification:Number = ClassificationUtil.classifyTriangle(t, plane);
                                  
                                  if(classification != ClassificationUtil.STRADDLE){
                                           if(classification == ClassificationUtil.BACK || classification == ClassificationUtil.COINCIDING )
                                                  outputs.splice(i, 1); 
                                          continue;
                                  }
                                          
                                  outputs.splice(i, 1);
                                  
                                  var d:Number = plane.d;
                                  results = TriangleUtil.clipTriangleWithPlaneTris(t, plane, 0.01, getNextTri(), getNextTri());
                                  
                                  for each(var tt:Triangle3D in results)
                                          outputs.push(tt);
                                  
                                  if(plane.d != d)
                                          plane.d = d;
                          }
                          
                          
                  } 
                  
                  
                  
                  public override function clipFace(triangle:Triangle3D, object:DisplayObject3D, material:MaterialObject3D, renderSessionData:RenderSessionData, outputArray:Array):Number{
                          
                          var screenZ:Number = 0;
                          var outputs:Array = [triangle];
                          
                          
                          if(selectedPlanes & LEFT) testClipped(_leftPlane, triangle, object, outputs);
                          if(selectedPlanes & TOP) testClipped(_topPlane, triangle, object, outputs);
                          if(selectedPlanes & BOTTOM) testClipped(_bottomPlane, triangle, object, outputs);
                          
                          if(selectedPlanes & RIGHT) testClipped(_rightPlane, triangle, object, outputs);
                          if(selectedPlanes & NEAR) testClipped(_nearPlane, triangle, object, outputs);
                                  
                          
                          for each(var f:Triangle3D in outputs)
                                  outputArray.push(f);
                                  
                          return 0;
                          
                  }
                  
                  
                  
FAR PLANE - not used atm...

  
                  //static public var FAR  :int = 0x01;
          
                  
NEAR PLANE

  
                  static public var NEAR   :int = 0x02;
          
                  
RIGHT PLANE selection

  
                  static public var RIGHT  :int = 0x04;
          
                  
Left plane selection

  
                  static public var LEFT   :int = 0x08;
          
                  
Top plane selection

  
                  static public var TOP    :int = 0x10;
          
                  
Bottom plane selection

  
                  static public var BOTTOM :int = 0x20;
          
                  
All planes selected.

  
                  static public var ALL    :int = NEAR + RIGHT + LEFT + TOP + BOTTOM;
                  
                  
no planes

  
                  static public var NONE         :int  = 0;
                  
                  
                  
                  
          }
  }


(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.