actionscript-33drotationaway3d

Lerping 3d rotation (away3d)


I'm creating a 3d game using away3d and awayphysics.

I've created a rotation formula that will rotate my model with a "smooth factor".

private var chRotation:Number = 0;

public override function update(delta:uint):void
{
    if(target){
        var smooth:Number = 0.95;
        var tp:Vector3D  = target.ghostObject.position;
        var cp:Vector3D  = entity.ghostObject.position;
        var targetAngle:Number = -((180 / Math.PI) * Math.atan2(cp.z - tp.z, cp.x - tp.x));

        if(oldTgRotation - targetAngle != 0){
            if((oldTgRotation - targetAngle) > 300){
                chRotation = -180;
            }else if((oldTgRotation - targetAngle) < -300){
                chRotation = 180;
            }
        }

        chRotation += (targetAngle + (chRotation - targetAngle) * (smooth - (delta / 800))) - chRotation;

        entity.ghostObject.rotation = new Vector3D(0, chRotation, 0);
        oldTgRotation = targetAngle;
    }
}

this works partly, it works until the mesh rotates from -180 to 180 cus the code will then rotate the mesh backwards, so: -180 -90 0 90 180

It should go from -180 to 180 forward. but how?

Edit: I've added kind of a solution but this still isn't perfect:

if(oldTgRotation - targetAngle != 0){
    if((oldTgRotation - targetAngle) > 300){
        chRotation = -180;
    }else if((oldTgRotation - targetAngle) < -300){
        chRotation = 180;
    }
}

Solution

  • Ok, so to fix this problem I've added a boolean switch:

    private var chRotation:Number = 0;
    private var switchf:Boolean = false;
    private var switchb:Boolean = false;
    
    public override function update(delta:uint):void
    {
        if(target){
            var smooth:Number = 0.95;
            var tp:Vector3D  = target.ghostObject.position;
            var cp:Vector3D  = entity.ghostObject.position;
            var targetAngle:Number = -((180 / Math.PI) * Math.atan2(cp.z - tp.z, cp.x - tp.x));
    
            if(oldTgRotation - targetAngle != 0){
                if((oldTgRotation - targetAngle) > 300){
                    switchf = true;
                }else if((oldTgRotation - targetAngle) < -300){
                    switchb = true;
                }
            }
    
            if(switchf){
                if(chRotation >= 177){
                    switchf = false;
                    chRotation = -180;
                }else{
                    targetAngle = 190;
                }
            }
            if(switchb){
                if(chRotation <= -177){
                    switchb = false;
                    chRotation = 180;
                }else{
                    targetAngle = -190;
                }
            }
    
            chRotation += (targetAngle + (chRotation - targetAngle) * (smooth - (delta / 800))) - chRotation;
    
            entity.ghostObject.rotation = new Vector3D(0, chRotation, 0);
            oldTgRotation = targetAngle;
        }
    }