/* * Copyright 2009 Freedom + Partners. * * Licensed under the The GNU General Public License (GPL), Version 2, June 1991; * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.openso$rectce.org/licenses/gpl-license.php * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.freedomandpartners.pv3d.utils { /** @description Utility class to dynamically adjust UV mapping for DislayObject3Ds @author Brian Kadar */ import org.papervision3d.objects.primitives.Plane; import org.papervision3d.objects.primitives.Cube; import org.papervision3d.objects.DisplayObject3D; import org.papervision3d.core.math.NumberUV; import flash.geom.Rectangle; import flash.geom.Point; public class UtilsUV { public static function applyUV( $o:DisplayObject3D, $rect:Rectangle, $gridU:Number=1, $gridV:Number=1, $initFace:Number=0, $invertV:Boolean=true ): void { var facePos:Number = $initFace-1; var uvA:NumberUV; var uvB:NumberUV; var uvC:NumberUV; var u:String = "x"; var v:String = "y"; var usize:String = "width"; var vsize:String = "height"; for ( var iu:int=0; iu < $gridU; iu++ ) { for ( var iv:int=0; iv < $gridV; iv++ ) { var initv:Number = $rect[v]+$rect[vsize]; if ( $invertV ) initv = 1-initv; uvA = new NumberUV( $rect[u] + ($rect[usize]/$gridU)*iu, initv + ($rect[vsize]/$gridV)*iv ); uvB = new NumberUV( $rect[u] + ($rect[usize]/$gridU)*(iu+1), initv + ($rect[vsize]/$gridV)*iv ); uvC = new NumberUV( $rect[u] + ($rect[usize]/$gridU)*iu, initv + ($rect[vsize]/$gridV)*(iv+1) ); $o.geometry.faces[++facePos].uv = [uvA,uvB,uvC] uvA = new NumberUV( $rect[u] + ($rect[usize]/$gridU)*(iu+1), initv + ($rect[vsize]/$gridV)*(iv+1) ); uvB = new NumberUV( $rect[u] + ($rect[usize]/$gridU)*iu, initv + ($rect[vsize]/$gridV)*(iv+1) ); uvC = new NumberUV( $rect[u] + ($rect[usize]/$gridU)*(iu+1), initv + ($rect[vsize]/$gridV)*iv ); $o.geometry.faces[++facePos].uv = [uvA,uvB,uvC] } } } public static function applyPlaneUV( $p:Plane, $rect:Rectangle ): void { applyUV( $p, $rect, $p.segmentsW, $p.segmentsH ); } public static function applyCubeUV( $c:Cube, $rect:Rectangle, $side:int ): void { var segW:int; var segH:int; var initFace:int = 0; // cube order: front, back, right, left, top, bottom var sides:Array = [Cube.FRONT, Cube.BACK, Cube.RIGHT, Cube.LEFT, Cube.TOP, Cube.BOTTOM]; var slen:int = sides.length; var side:int; /* Calculate start point in face array, based on cube side Note: Does not take into account excluded sides */ for ( var i:int=0; i < slen; i++ ) { side = sides[i]; if ( $side == side ) break; if ( side == Cube.FRONT || side == Cube.BACK ) { initFace += $c.segments.x*$c.segments.y*2; } else if ( side == Cube.RIGHT || side == Cube.LEFT ) { initFace += $c.segments.z*$c.segments.y*2; } else if ( side == Cube.TOP || side == Cube.BOTTOM ) { initFace += $c.segments.x*$c.segments.z*2; } } var segs:Point = _getCubeSideSegments( $c, $side ); var gridU:Number = segs.x; var gridV:Number = segs.y; var facePos:Number = initFace-1; applyUV( $c, $rect, gridU, gridV, initFace ); // custom uv positioning for every other triangle for ( var iu:int=0; iu < gridU; iu++ ) { for ( var iv:int=0; iv < gridV; iv++ ) { facePos+=2; var a:Array = $c.geometry.faces[facePos].uv; $c.geometry.faces[facePos].uv = new Array( a[2], a[0], a[1] ); } } } // returns segment information for Cube side private static function _getCubeSideSegments( $c:Cube, $side:int ): Point { var segW:Number; var segH:Number; switch ( $side ) { case Cube.FRONT || Cube.BACK: segW = $c.segments.x; segH = $c.segments.y; break; case Cube.TOP || Cube.BOTTOM: segW = $c.segments.x; segH = $c.segments.z; break; case Cube.LEFT || Cube.RIGHT: segW = $c.segments.z; segH = $c.segments.y; break; default: segW = segH = $c.segments.x; } return new Point( segW, segH ); } } }