001package com.fs.starfarer.api.util;
002
003public class SmoothFacingUtil {
004
005        private float turnAcceleration, maxTurnRate;
006        private float turnRate;
007        
008        private float facing;
009        
010        public SmoothFacingUtil(float turnAcceleration, float maxTurnRate) {
011                this.turnAcceleration = turnAcceleration;
012                this.maxTurnRate = maxTurnRate;
013        }
014
015        
016        public void advance(float desiredFacing, float amount) {
017                float absTurnRate = Math.abs(turnRate);
018                
019                // v t - 0.5 a t t = dist
020                // dv = a t;  t = v / a
021                float decelTime = absTurnRate / turnAcceleration; 
022                float decelDistance = absTurnRate * decelTime - 0.5f * turnAcceleration * decelTime * decelTime;
023                
024                float diffWithCurrFacing = Misc.getAngleDiff(facing, desiredFacing);
025
026                float turnDir = Misc.getClosestTurnDirection(facing, desiredFacing);
027                if (Math.signum(turnRate) == Math.signum(turnDir)) {
028                        if (decelDistance >= diffWithCurrFacing) {
029                                turnDir = -turnDir;
030                        }
031                }
032                
033                turnRate += turnDir * turnAcceleration * amount;
034                //turnRate = maxTurnRate * turnDir;
035                if (Math.abs(turnRate) > maxTurnRate) {
036                        turnRate = maxTurnRate * Math.signum(turnRate);
037                        //System.out.println("capped at " + maxTurnRate);
038                }
039                
040                
041                facing += turnRate * amount;
042                facing = Misc.normalizeAngle(facing);
043                
044                if (diffWithCurrFacing < turnRate * amount * 1.5f) {
045                        facing = desiredFacing;
046                }
047                
048        }
049        
050
051        public float getFacing() {
052                return facing;
053        }
054
055        public void setFacing(float facing) {
056                this.facing = facing;
057        }
058
059
060        public float getTurnAcceleration() {
061                return turnAcceleration;
062        }
063
064        public void setTurnAcceleration(float turnAcceleration) {
065                this.turnAcceleration = turnAcceleration;
066        }
067
068        public float getMaxTurnRate() {
069                return maxTurnRate;
070        }
071
072        public void setMaxTurnRate(float maxTurnRate) {
073                this.maxTurnRate = maxTurnRate;
074        }
075
076        public float getTurnRate() {
077                return turnRate;
078        }
079
080        public void setTurnRate(float turnRate) {
081                this.turnRate = turnRate;
082        }
083
084        
085}