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 com.as3dmod.util.XMath;
/**
* Skew modifier.
*
* A demo of all functionalities of the modifier is here.
*
* @author Bartek Drozdz
*/
public class Skew extends Modifier implements IModifier
{
private var _force:Number;
private var _skewAxis:int;
private var _offset:Number = .5;
private var _constraint:int = ModConstant.NONE;
private var _power:Number = 1;
private var _falloff:Number = 1;
private var _inverseFalloff:Boolean = false;
private var _oneSide:Boolean = false;
private var _swapAxes:Boolean = false;
public function Skew(f:Number=0) {
_force = f;
}
override public function setModifiable(mod:MeshProxy):void {
super.setModifiable(mod);
_skewAxis = _skewAxis || mod.maxAxis;
}
public function apply():void {
var vs:Array = mod.getVertices();
var vc:int = vs.length;
for (var i:int = 0; i < vc; i++) {
var v:VertexProxy = vs[i] as VertexProxy;
if(_constraint == ModConstant.LEFT && v.getRatio(_skewAxis) <= _offset) continue;
if(_constraint == ModConstant.RIGHT && v.getRatio(_skewAxis) > _offset) continue;
var r:Number = v.getRatio(_skewAxis) - _offset;
if(_oneSide) r = Math.abs(r);
var dr:Number = v.getRatio(displaceAxis);
if(_inverseFalloff) dr = 1 - dr;
var f:Number = _falloff + dr * (1-_falloff);
var p:Number = Math.pow(Math.abs(r), _power) * XMath.sign(r, 1);
var vl:Number = v.getValue(displaceAxis) + force * p * f;
v.setValue(displaceAxis, vl);
}
}
private function get displaceAxis():int {
switch(_skewAxis) {
case ModConstant.X:
return (_swapAxes) ? ModConstant.Z : ModConstant.Y;
case ModConstant.Y:
return (_swapAxes) ? ModConstant.Z : ModConstant.X;
case ModConstant.Z:
return (_swapAxes) ? ModConstant.Y : ModConstant.X;
default:
return 0;
}
}
public function set force(f:Number):void {
_force = f;
}
public function get force():Number {
return _force;
}
public function get constraint():int {
return _constraint;
}
public function set constraint(c:int):void {
_constraint = c;
}
public function get offset():Number {
return _offset;
}
public function set offset(o:Number):void {
_offset = XMath.trim(0, 1, o);
}
public function get power():Number {
return _power;
}
public function set power(power:Number):void {
_power = Math.max(1, power);
}
public function get falloff():Number {
return _falloff;
}
public function set falloff(falloff:Number):void {
_falloff = XMath.trim(0, 1, falloff);
}
public function get oneSide():Boolean {
return _oneSide;
}
public function set oneSide(oneSide:Boolean):void {
_oneSide = oneSide;
}
public function get skewAxis():int {
return _skewAxis;
}
public function set skewAxis(skewAxis:int):void {
_skewAxis = skewAxis;
}
public function get swapAxes():Boolean {
return _swapAxes;
}
public function set swapAxes(spawAxes:Boolean):void {
_swapAxes = spawAxes;
}
public function get inverseFalloff():Boolean {
return _inverseFalloff;
}
public function set inverseFalloff(inverseFalloff:Boolean):void {
_inverseFalloff = inverseFalloff;
}
public function debug():String {
var debugInfo:String = "Skew.debug:\n";
debugInfo += "_force: " + _force + "\n";
debugInfo += "_skewAxis: " + _skewAxis + "\n";
debugInfo += "_offset: " + _offset + "\n";
debugInfo += "_constraint: " + _constraint + "\n";
debugInfo += "_power: " + _power + "\n";
debugInfo += "_falloff: " + _falloff + "\n";
debugInfo += "_inverseFalloff: " + _inverseFalloff + "\n";
debugInfo += "_oneSide: " + _oneSide + "\n";
debugInfo += "_swapAxes: " + _swapAxes + "\n";
debugInfo += "displaceAxis: " + displaceAxis + "\n";
return debugInfo;
}
}
}