package com.as3dmod.modifiers { import com.as3dmod.IModifier; import com.as3dmod.core.MeshProxy; import com.as3dmod.core.Modifier; import com.as3dmod.core.VertexProxy; import com.as3dmod.util.ModConstant; import flash.geom.Matrix; import flash.geom.Point; /** * Bend modifier. Bends an object along an axis. *
*
Go here for a demo: * http://www.everydayflash.com/
*
* * @version 2.1 * @author Bartek Drozdz * * Changes: * 2.1 - Coordinate rotation now uses Matrix class * 2.0 - Angle bending added */ public class Bend extends Modifier implements IModifier { private var _force:Number; private var _offset:Number; private var _angle:Number; private var _diagAngle:Number; private var _constraint:int = ModConstant.NONE; private var max:int; private var min:int; private var mid:int; private var width:Number; private var height:Number; private var origin:Number; private var m1:Matrix; private var m2:Matrix; public var switchAxes:Boolean = false; public function Bend(f:Number=0, o:Number=.5, a:Number=0) { _force = f; _offset = o; angle = a; } override public function setModifiable(mod:MeshProxy):void { super.setModifiable(mod); max = (switchAxes) ? mod.midAxis : mod.maxAxis; min = mod.minAxis; mid = (switchAxes) ? mod.maxAxis : mod.midAxis; width = mod.getSize(max); height = mod.getSize(mid); origin = mod.getMin(max); _diagAngle = Math.atan(width / height); } /** * [0 - 2] where 0 = no bend, and 2 360 deg bend. * When > 2 will start rolling on itself, which does not look good. * (default - 0) */ public function set force(f:Number):void { _force = f; } public function get force():Number { return _force; } /** * Can be either ModConstants.LEFT, ModConstants.RIGHT or ModConstants.NONE * (default - NONE) */ public function set constraint(c:int):void { _constraint = c; } public function get constraint():int { return _constraint; } /** * [0 - 1] The start place of the bend. */ public function get offset():Number { return _offset; } public function set offset(offset:Number):void { _offset = offset; } /** * The angle of the diagonal of the mesh */ public function get diagAngle():Number { return _diagAngle; } /** * The angle of the bend. In rad. */ public function get angle():Number { return _angle; } public function set angle(a:Number):void { _angle = a; m1 = new Matrix(); m1.rotate(_angle); m2 = new Matrix(); m2.rotate(-_angle); } /** * Applies the modifier to the mesh */ public function apply():void { if(force == 0) return; var vs:Array = mod.getVertices(); var vc:int = vs.length; var distance:Number = origin + width * offset; var radius:Number = width / Math.PI / force; var bendAngle:Number = Math.PI * 2 * (width / (radius * Math.PI * 2)); for (var i:int = 0; i < vc; i++) { var v:VertexProxy = vs[i] as VertexProxy; var vmax:Number = v.getValue(max); var vmid:Number = v.getValue(mid); var vmin:Number = v.getValue(min); var np:Point = m1.transformPoint(new Point(vmax, vmid)); vmax = np.x; vmid = np.y; var p:Number = (vmax - origin) / width; if ((constraint == ModConstant.LEFT && p <= offset) || (constraint == ModConstant.RIGHT && p >= offset)) { } else { var fa:Number = ((Math.PI / 2) - bendAngle * offset) + (bendAngle * p); var op:Number = Math.sin(fa) * (radius + vmin); var ow:Number = Math.cos(fa) * (radius + vmin); vmin = op - radius; vmax = distance - ow; } var np2:Point = m2.transformPoint(new Point(vmax, vmid)); vmax = np2.x; vmid = np2.y; v.setValue(max, vmax); v.setValue(mid, vmid); v.setValue(min, vmin); } } } }