Пример #1
0
        private void CalcRotate_InGravity(RelativeDirection3F direction)
        {
            //Log.DebugLog("entered CalcRotate_InGravity(RelativeDirection3F direction)", "CalcRotate_InGravity()");

            float secondaryAccel = Thrust.SecondaryForce / Block.Physics.Mass;

            RelativeDirection3F fightGrav = RelativeDirection3F.FromLocal(Block.CubeGrid, -Thrust.LocalGravity.vector);

            if (secondaryAccel > Thrust.GravityStrength)
            {
                // secondary thrusters are strong enough to fight gravity
                if (Vector3.Dot(direction.ToLocalNormalized(), fightGrav.ToLocalNormalized()) > 0f)
                {
                    // direction is away from gravity
                    Log.DebugLog("Facing primary towards direction(" + direction.ToLocalNormalized() + "), rolling secondary away from gravity(" + fightGrav.ToLocalNormalized() + ")");
                    CalcRotate(Thrust.Standard.LocalMatrix, direction, fightGrav, gravityAdjusted: true);
                    return;
                }
                else
                {
                    // direction is towards gravity
                    Log.DebugLog("Facing secondary away from gravity(" + fightGrav.ToLocalNormalized() + "), rolling primary towards direction(" + direction.ToLocalNormalized() + ")");
                    CalcRotate(Thrust.Gravity.LocalMatrix, fightGrav, direction, gravityAdjusted: true);
                    return;
                }
            }

            // secondary thrusters are not strong enough to fight gravity

            if (secondaryAccel > 1f)
            {
                Log.DebugLog("Facing primary towards gravity(" + fightGrav.ToLocalNormalized() + "), rolling secondary towards direction(" + direction.ToLocalNormalized() + ")");
                CalcRotate(Thrust.Standard.LocalMatrix, fightGrav, direction, gravityAdjusted: true);
                return;
            }

            // helicopter

            float primaryAccel = Math.Max(Thrust.PrimaryForce / Block.Physics.Mass - Thrust.GravityStrength, 1f);             // obviously less than actual value but we do not need maximum theoretical acceleration

            DirectionGrid moveAccel = m_moveAccel != Vector3.Zero ? ((DirectionBlock)m_moveAccel).ToGrid(Block.CubeBlock) : LinearVelocity.ToGrid(Block.CubeGrid) * -0.5f;

            if (moveAccel.vector.LengthSquared() > primaryAccel * primaryAccel)
            {
                //Log.DebugLog("move accel is over available acceleration: " + moveAccel.vector.Length() + " > " + primaryAccel, "CalcRotate_InGravity()");
                moveAccel = Vector3.Normalize(moveAccel.vector) * primaryAccel;
            }

            //Log.DebugLog("Facing primary away from gravity and towards direction, moveAccel: " + moveAccel + ", fight gravity: " + fightGrav.ToLocal() + ", direction: " + direction.ToLocalNormalized() + ", new direction: " + (moveAccel + fightGrav.ToLocal()));

            Vector3 dirV = moveAccel + fightGrav.ToLocal();

            direction = RelativeDirection3F.FromLocal(Block.CubeGrid, dirV);
            CalcRotate(Thrust.Standard.LocalMatrix, direction, gravityAdjusted: true);

            Vector3 fightGravDirection = fightGrav.ToLocal() / Thrust.GravityStrength;

            // determine acceleration needed in forward direction to move to desired altitude or remain at current altitude
            float   projectionMagnitude = Vector3.Dot(dirV, fightGravDirection) / Vector3.Dot(Thrust.Standard.LocalMatrix.Forward, fightGravDirection);
            Vector3 projectionDirection = ((DirectionGrid)Thrust.Standard.LocalMatrix.Forward).ToBlock(Block.CubeBlock);

            m_moveForceRatio = projectionDirection * projectionMagnitude * Block.CubeGrid.Physics.Mass / Thrust.PrimaryForce;
            Log.DebugLog("changed moveForceRatio, projectionMagnitude: " + projectionMagnitude + ", projectionDirection: " + projectionDirection + ", moveForceRatio: " + m_moveForceRatio);
        }