Beispiel #1
0
        protected Matrix4 straightMissileSpawnTxfm(ISSpaceMissileTarget target,
                                                   Vector3 launcherPos, Vector3 launcherVel,
                                                   int id, int clusterSize)
        {
            const float sideDispersal = 2f;
            float       angle         = (float)Math.PI * 2f / (float)clusterSize * id;
            Vector3     toTarget      = (target.position - launcherPos);
            float       length        = toTarget.Length;

            if (length < 0.0001f)
            {
                toTarget = -Vector3.UnitZ;
            }
            else
            {
                // normalize
                toTarget /= length;
            }
            Quaternion orientQuat  = OpenTKHelper.neededRotation(Vector3.UnitZ, toTarget);
            Matrix4    orientMat   = Matrix4.CreateFromQuaternion(orientQuat);
            Matrix4    disperalMat = Matrix4.CreateTranslation(sideDispersal * (float)Math.Cos(angle),
                                                               sideDispersal * (float)Math.Sin(angle), 0f);

            return(disperalMat * orientMat * Matrix4.CreateTranslation(launcherPos) * Matrix4.CreateTranslation(toTarget * 7f));
        }
Beispiel #2
0
        public override void updateExecution(float timeElapsed)
        {
            base.updateExecution(timeElapsed);

            if (timeElapsed <= 0f)
            {
                return;
            }

            var mParams = missile.parameters as SSpaceMissileVisualParameters;
            var target  = missile.target;

            // make visual direction "lean into" velocity
            Vector3 axis;
            float   angle;

            OpenTKHelper.neededRotation(missile.visualDirection, missile.velocity.Normalized(),
                                        out axis, out angle);
            float abs = Math.Abs(angle);

            if (abs > mParams.pursuitVisualRotationRate && abs > 0f)
            {
                angle = angle / abs * mParams.pursuitVisualRotationRate;
            }
            Quaternion quat = Quaternion.FromAxisAngle(axis, angle);

            missile.visualDirection = Vector3.Transform(missile.visualDirection, quat);

            missile.visualSmokeAmmount = missile.velocity.LengthFast / mParams.pursuitMaxVelocity;
        }
Beispiel #3
0
        protected void moveShips(float timeElapsed)
        {
            if (timeElapsed <= 0f)
            {
                return;
            }

            // make the target drone move from side to side
            localTime += timeElapsed;
            Vector3 pos = targetDrone.Pos;

            pos.Z           = 30f * (float)Math.Sin(localTime);
            targetDrone.Pos = pos;

            // make the vandal ship orbit missile target
            Vector3 desiredPos;
            Vector3 desiredDir;
            float   angle          = localTime * 0.5f;
            float   desiredXOffset = 100f * (float)Math.Cos(angle);
            float   desiredYOffset = 20f * (float)Math.Sin(angle * 0.77f);
            float   desiredZOffset = 80f * (float)Math.Sin(angle * 0.88f);
            Vector3 desiredOffset  = new Vector3(desiredXOffset, desiredYOffset, desiredZOffset);

            var target = getTargetObject();

            if (missileLauncher != MissileLaunchers.VandalShip || target == null || target == vandalShip)
            {
                desiredPos = new Vector3(100f, 0f, 0f);
                desiredDir = -Vector3.UnitX;
            }
            else if (target == main3dScene.ActiveCamera)
            {
                desiredPos = main3dScene.ActiveCamera.Pos + -main3dScene.ActiveCamera.Dir * 300f;
                Quaternion cameraOrient = OpenTKHelper.neededRotation(Vector3.UnitZ, -main3dScene.ActiveCamera.Up);
                desiredPos += Vector3.Transform(desiredOffset * 0.1f, cameraOrient);
                desiredDir  = (target.Pos - vandalShip.Pos).Normalized();
            }
            else
            {
                //float desiredZOffset = 5f * (float)Math.Sin(angle + 0.2f);
                desiredPos = target.Pos + desiredOffset;
                desiredDir = (target.Pos - vandalShip.Pos).Normalized();
            }

            Vector3     desiredMotion = desiredPos - vandalShip.Pos;
            const float vel           = 100f;
            float       displacement  = vel * timeElapsed;
            Vector3     vandalNewPos;

            if (displacement > desiredMotion.LengthFast)
            {
                vandalNewPos = desiredPos;
            }
            else
            {
                vandalNewPos = vandalShip.Pos + desiredMotion.Normalized() * displacement;
            }

            vandalVelocity = (vandalNewPos - vandalShip.Pos) / timeElapsed;
            vandalShip.Pos = vandalNewPos;

            Quaternion vandalOrient = OpenTKHelper.neededRotation(Vector3.UnitZ, desiredDir);

            vandalShip.Orient(desiredDir, Vector3.Transform(Vector3.UnitY, vandalOrient));
        }
Beispiel #4
0
        public void updateExecution(float timeElapsed)
        {
            if (timeElapsed <= 0f)
            {
                return;
            }

            var mParams = _missile.cluster.parameters;
            var target  = _missile.cluster.target;

            // basic proportional navigation. see wikipedia
            Vector3 Vr    = target.velocity - _missile.velocity;
            Vector3 R     = target.position - _missile.position;
            Vector3 omega = Vector3.Cross(R, Vr) / R.LengthSquared;
            Vector3 latax = mParams.pursuitNavigationGain * Vector3.Cross(Vr, omega);

            if (mParams.pursuitAugmentedPN == true)
            {
                // this code is not tested as there are currently no targets with well defined accelerations
                Vector3 losDir       = R.Normalized();
                float   targetAccLos = Vector3.Dot(target.acceleration, losDir);
                Vector3 targetLatAx  = target.acceleration - targetAccLos * losDir;
                latax += mParams.pursuitNavigationGain * targetLatAx / 2f;
            }
            _missile._lataxDebug = latax;

            // apply latax
            var oldVelMag = _missile.velocity.LengthFast;

            _missile.velocity += latax * timeElapsed;
            float tempVelMag = _missile.velocity.LengthFast;

            if (oldVelMag != 0f)
            {
                float r = tempVelMag / oldVelMag;
                if (r > 1f)
                {
                    _missile.velocity /= r;
                }
            }

            if (mParams.pursuitHitTimeCorrection)
            {
                // apply pursuit hit time correction
                float dist = R.LengthFast;
                if (dist != 0f)
                {
                    Vector3 targetDir        = R / dist;
                    float   v0               = -Vector3.Dot(Vr, targetDir);
                    float   t                = _missile.cluster.timeToHit;
                    float   correctionAccMag = 2f * (dist - v0 * t) / t / t;
                    Vector3 corrAcc          = correctionAccMag * targetDir;
                    _missile.velocity            += corrAcc * timeElapsed;
                    _missile._hitTimeCorrAccDebug = corrAcc;
                }
            }
            else
            {
                // hit time correction inactive. allow accelerating to achieve optimal velocity or forever
                oldVelMag = _missile.velocity.LengthFast;
                float velDelta  = mParams.pursuitMaxAcc * timeElapsed;
                float newVelMag = Math.Min(oldVelMag + velDelta, mParams.pursuitMaxVelocity);
                if (oldVelMag != 0f)
                {
                    _missile.velocity *= (newVelMag / oldVelMag);
                }
            }

            // make visual direction "lean into" velocity
            Vector3 axis;
            float   angle;

            OpenTKHelper.neededRotation(_missile.visualDirection, _missile.velocity.Normalized(),
                                        out axis, out angle);
            float abs = Math.Abs(angle);

            if (abs > mParams.pursuitVisualRotationRate && abs > 0f)
            {
                angle = angle / abs * mParams.pursuitVisualRotationRate;
            }
            Quaternion quat = Quaternion.FromAxisAngle(axis, angle);

            _missile.visualDirection = Vector3.Transform(_missile.visualDirection, quat);
        }