예제 #1
0
        protected override void Tick(float deltaTimeSeconds)
        {
            base.Tick(deltaTimeSeconds);
            var angularDisplacement = GetAngularDisplacementForTick(deltaTimeSeconds);

            AssetLocator.MainGeometryPass._EGGHACK_ROT *= angularDisplacement;
            //AngularVelocity = new Vector3(angularDisplacement.RotAroundX, angularDisplacement.RotAroundY, angularDisplacement.RotAroundZ);
            AngularVelocity = Vector3.ZERO;

            //float downwardVeloComponent = Velocity.ProjectedOnto(GameCoordinator.BoardDownDir).Length;
            //Velocity -= GameCoordinator.BoardDownDir.WithLength(downwardVeloComponent);

            // OPTION 1
            //var veloChangeAngle = Vector3.AngleBetween(
            //	velocityLastFrame.ProjectedOnto(GameCoordinator.BoardDownDir),
            //	Velocity.ProjectedOnto(GameCoordinator.BoardDownDir)
            //);

            //if (veloChangeAngle > MathUtils.PI_OVER_TWO) {
            //	if (Vector3.AngleBetween(velocityLastFrame, GameCoordinator.BoardDownDir) < Vector3.AngleBetween(Velocity, GameCoordinator.BoardDownDir)) {
            //		SetTranslation(lastPositions[((nextPositionSlot - 2) % lastPositions.Length)]);
            //		Velocity = TrueVelocity;
            //		HUDSound.UISelectNegativeOption.Play();
            //	}
            //}

            // OPTION 2

            var downDir     = GameCoordinator.BoardDownDir;
            Ray rollTestRay = new Ray(
                Transform.Translation - downDir.WithLength(GameplayConstants.EGG_COLLISION_RADIUS),
                downDir,
                GameplayConstants.EGG_COLLISION_RADIUS * 3f
                );

            EntityModule.RayTestAllLessGarbage(rollTestRay, bulletBugRayTestReusableList, 5U);
            for (int i = 0; i < bulletBugRayTestReusableList.Count; ++i)
            {
                GeometryEntity touchedEntity = bulletBugRayTestReusableList[i].Entity as GeometryEntity;
                if (touchedEntity != null)
                {
                    BulletBugRayHandle(touchedEntity);
                }
            }

            CheckForAndCorrectBulletBug(deltaTimeSeconds);

            lastPositions[(nextPositionSlot % lastPositions.Length)] = Transform.Translation;
            elapsedTimes[(nextPositionSlot % lastPositions.Length)]  = EntityModule.ElapsedTime;
            ++nextPositionSlot;

            velocityLastFrame = Velocity;

            if (GameCoordinator.CurrentGameState == GameCoordinator.OverallGameState.LevelPlaying)
            {
                airtime += deltaTimeSeconds;
                topSpeed = Math.Max(topSpeed, TrueVelocity.Length);
            }
        }
예제 #2
0
        private static void TickSound(float deltaTime)
        {
            Vector3 ballVelo       = egg.Velocity;
            float   ballSpeed      = ballVelo.Length;
            float   speedLastFrame = velocityLastFrame.Length;

            const int TICK_SOUND_EARLINESS_MS = 200;

            // Tick
            int adjustedTimeRemainingMs = timeRemainingMs - TICK_SOUND_EARLINESS_MS;
            int timeRemainingSecs       = adjustedTimeRemainingMs / 1000;

            if (timeRemainingSecs != 0 && timeRemainingSecs != (int)(adjustedTimeRemainingMs + deltaTime * 1000f) / 1000)
            {
                int instanceId = AudioModule.CreateSoundInstance(AssetLocator.TickSound);
                AudioModule.PlaySoundInstance(
                    instanceId,
                    false,
                    0.2f * Config.SoundEffectVolume,
                    adjustedTimeRemainingMs > Config.TimePitchRaiseMs ? 1f : (adjustedTimeRemainingMs > Config.TimeWarningMs ? 1.1f : 1.2f)
                    );
            }

            // Bounce
            if (velocityLastFrame != Vector3.ZERO && ballSpeed >= MIN_SPEED_FOR_DIFFERENTIAL_ANGLE_BOUNCE_SOUND && Vector3.AngleBetween(ballVelo, velocityLastFrame) >= MIN_VELO_DIFFERENTIAL_ANGLE_FOR_BOUNCE_SOUND)
            {
                if (lastBounceSoundTime - timeRemainingMs >= BOUNCE_SOUND_MIN_INTERVAL)
                {
                    int instanceId = AudioModule.CreateSoundInstance(AssetLocator.ObtuseBounceSound);
                    AudioModule.PlaySoundInstance(
                        instanceId,
                        false,
                        BOUNCE_VOLUME * Config.SoundEffectVolume,
                        RandomProvider.Next(BOUNCE_PITCH_MIN, BOUNCE_PITCH_MAX)
                        );
                    instanceId = AudioModule.CreateSoundInstance(AssetLocator.ImpactSounds[RandomProvider.Next(0, AssetLocator.ImpactSounds.Length)]);
                    AudioModule.PlaySoundInstance(
                        instanceId,
                        false,
                        IMPACT_VOLUME * Config.SoundEffectVolume,
                        RandomProvider.Next(IMPACT_PITCH_MIN, IMPACT_PITCH_MAX)
                        );
                    lastBounceSoundTime = timeRemainingMs;
                }

                float speedDiff     = Math.Abs(speedLastFrame - ballSpeed);
                int   baseBitsCount = 3;
                if (speedDiff >= PhysicsManager.ONE_METRE_SCALED * 10f)
                {
                    baseBitsCount = 13;
                }
                else if (speedDiff >= PhysicsManager.ONE_METRE_SCALED * 8f)
                {
                    baseBitsCount = 11;
                }
                else if (speedDiff >= PhysicsManager.ONE_METRE_SCALED * 6f)
                {
                    baseBitsCount = 7;
                }
                else if (speedDiff >= PhysicsManager.ONE_METRE_SCALED * 4f)
                {
                    baseBitsCount = 5;
                }
                CollisionBitPool.DisseminateBits(egg.Transform.Translation, -boardDownDir.WithLength(speedDiff * 0.65f), baseBitsCount * (int)Config.PhysicsLevel);
                MaybePlayAllBounce(speedDiff);
            }
            else if (Math.Abs(ballSpeed - speedLastFrame) >= MIN_SPEED_CHANGE_FOR_BOUNCE_SOUND)               // bounce in same direction
            {
                if (lastBounceSoundTime - timeRemainingMs >= BOUNCE_SOUND_MIN_INTERVAL)
                {
                    int instanceId = AudioModule.CreateSoundInstance(AssetLocator.AcuteBounceSound);
                    AudioModule.PlaySoundInstance(
                        instanceId,
                        false,
                        BOUNCE_VOLUME * Config.SoundEffectVolume,
                        RandomProvider.Next(BOUNCE_PITCH_MIN, BOUNCE_PITCH_MAX)
                        );
                    instanceId = AudioModule.CreateSoundInstance(AssetLocator.ImpactSounds[RandomProvider.Next(0, AssetLocator.ImpactSounds.Length)]);
                    AudioModule.PlaySoundInstance(
                        instanceId,
                        false,
                        IMPACT_VOLUME * Config.SoundEffectVolume,
                        RandomProvider.Next(IMPACT_PITCH_MIN, IMPACT_PITCH_MAX)
                        );
                    lastBounceSoundTime = timeRemainingMs;
                }

                float speedDiff     = Math.Abs(speedLastFrame - ballSpeed);
                int   baseBitsCount = 2;
                if (speedDiff >= PhysicsManager.ONE_METRE_SCALED * 10f)
                {
                    baseBitsCount = 13;
                }
                else if (speedDiff >= PhysicsManager.ONE_METRE_SCALED * 8f)
                {
                    baseBitsCount = 11;
                }
                else if (speedDiff >= PhysicsManager.ONE_METRE_SCALED * 6f)
                {
                    baseBitsCount = 7;
                }
                else if (speedDiff >= PhysicsManager.ONE_METRE_SCALED * 4f)
                {
                    baseBitsCount = 3;
                }
                CollisionBitPool.DisseminateBits(egg.Transform.Translation, -boardDownDir.WithLength(speedDiff * 0.65f), baseBitsCount * (int)Config.PhysicsLevel);
                MaybePlayAllBounce(speedDiff);
            }

            // Roll
            float   rollVolFraction  = (ballSpeed - GameplayConstants.EGG_SPEED_FOR_MIN_ROLL_VOL) / (GameplayConstants.EGG_SPEED_FOR_MAX_ROLL_VOL - GameplayConstants.EGG_SPEED_FOR_MIN_ROLL_VOL);
            float   rollFreqFraction = (ballSpeed - GameplayConstants.EGG_SPEED_FOR_MIN_ROLL_FREQ) / (GameplayConstants.EGG_SPEED_FOR_MAX_ROLL_FREQ - GameplayConstants.EGG_SPEED_FOR_MIN_ROLL_FREQ);
            Vector3 eggPos           = egg.Transform.Translation;
            Ray     rollTestRay      = Ray.FromStartAndEndPoint(
                eggPos,
                eggPos + boardDownDir.WithLength(GameplayConstants.EGG_COLLISION_RADIUS + ROLL_MARGIN)
                );

            EntityModule.RayTestAllLessGarbage(rollTestRay, reusableRayTestResultsList);
            bool isRolling = false;

            for (int i = 0; i < reusableRayTestResultsList.Count; ++i)
            {
                if (reusableRayTestResultsList[i].Entity != egg)
                {
                    isRolling = true;
                    break;
                }
            }
            if (isRolling)
            {
                if (unbrokenRollTime == 0)
                {
                    unbrokenRollTime = (int)(deltaTime * 1000f);
                }
                else
                {
                    unbrokenRollTime += lastRollTime - timeRemainingMs;
                }
                lastRollTime = timeRemainingMs;
            }
            else
            {
                if (unbrokenRollTime < UNBROKEN_ROLL_TIME_BEFORE_ROLL_SOUND ||
                    lastRollTime - timeRemainingMs > ROLL_RAY_FAIL_MAX_TIME_BEFORE_UNBROKEN_ROLL_RESET)
                {
                    unbrokenRollTime = 0;
                }
            }

            if (unbrokenRollTime < UNBROKEN_ROLL_TIME_BEFORE_ROLL_SOUND ||
                lastRollTime - timeRemainingMs > ROLL_RAY_FAIL_MAX_TIME_BEFORE_NO_SOUND_MS ||
                rollVolFraction <= 0f ||
                rollFreqFraction <= 0f)
            {
                AudioModule.SetSoundInstanceVolume(AssetLocator.RollSound.SoundInstanceIds.First(), 0f);
            }
            else
            {
                if (rollVolFraction > 1f)
                {
                    rollVolFraction = 1f;
                }
                if (rollFreqFraction > 1f)
                {
                    rollFreqFraction = 1f;
                }
                AudioModule.SetSoundInstanceFrequency(AssetLocator.RollSound.SoundInstanceIds.First(), ROLL_FREQ_MIN + (ROLL_FREQ_MAX - ROLL_FREQ_MIN) * rollFreqFraction);
                AudioModule.SetSoundInstanceVolume(AssetLocator.RollSound.SoundInstanceIds.First(), ROLL_VOLUME_MIN + (ROLL_VOLUME_MAX - ROLL_VOLUME_MIN) * rollVolFraction * Config.SoundEffectVolume);
            }

            // Highspeed
            if (ballSpeed >= HIGHSPEED_SOUND_MIN_SPEED)
            {
                float angleToUp   = Vector3.AngleBetween(ballVelo, -boardDownDir);
                float angleToDown = Vector3.AngleBetween(ballVelo, boardDownDir);

                if (angleToUp <= MathUtils.PI_OVER_TWO * 0.5f)
                {
                    if (highspeedUpMetadata.TimeAtLastSound - timeRemainingMs >= MIN_INTERVAL_BETWEEN_HIGHSPEED_SOUNDS_MS &&
                        highspeedUpMetadata.CollidedSinceLastSound && highspeedUpMetadata.SlowedSinceLastSound)
                    {
                        int instanceId = AudioModule.CreateSoundInstance(AssetLocator.HighSpeedUpSounds[RandomProvider.Next(0, AssetLocator.HighSpeedUpSounds.Length)]);
                        AudioModule.PlaySoundInstance(
                            instanceId,
                            false,
                            HIGHSPEED_VOLUME * Config.SoundEffectVolume,
                            RandomProvider.Next(HIGHSPEED_PITCH_MIN, HIGHSPEED_PITCH_MAX)
                            );
                        highspeedUpMetadata.CollidedSinceLastSound = highspeedUpMetadata.SlowedSinceLastSound = false;
                        highspeedUpMetadata.TimeAtLastSound        = timeRemainingMs;
                    }
                }
                else if (angleToDown <= MathUtils.PI_OVER_TWO * 0.5f)
                {
                    Ray  downRay          = Ray.FromStartAndEndPoint(eggPos, eggPos + boardDownDir.WithLength(PARALLEL_HIGHSPEED_DOWN_BUFFER));
                    bool somethingBeneath = EntityModule.RayTestAll(downRay).Any(rtc => rtc.Entity != egg);
                    if (highspeedDownMetadata.TimeAtLastSound - timeRemainingMs >= MIN_INTERVAL_BETWEEN_HIGHSPEED_SOUNDS_MS &&
                        highspeedDownMetadata.CollidedSinceLastSound && highspeedDownMetadata.SlowedSinceLastSound &&
                        !somethingBeneath)
                    {
                        int instanceId = AudioModule.CreateSoundInstance(AssetLocator.HighSpeedDownSounds[RandomProvider.Next(0, AssetLocator.HighSpeedDownSounds.Length)]);
                        AudioModule.PlaySoundInstance(
                            instanceId,
                            false,
                            HIGHSPEED_VOLUME * Config.SoundEffectVolume,
                            RandomProvider.Next(HIGHSPEED_PITCH_MIN, HIGHSPEED_PITCH_MAX)
                            );
                        highspeedDownMetadata.CollidedSinceLastSound = highspeedDownMetadata.SlowedSinceLastSound = false;
                        highspeedDownMetadata.TimeAtLastSound        = timeRemainingMs;
                    }
                }
                else if (ballSpeed >= HIGHSPEED_SOUND_MIN_SPEED + HIGHSPEED_SOUND_ADDITIONAL_SPEED_FOR_PARALLEL)
                {
                    if (highspeedParallelMetadata.TimeAtLastSound - timeRemainingMs >= MIN_INTERVAL_BETWEEN_HIGHSPEED_SOUNDS_MS &&
                        highspeedParallelMetadata.CollidedSinceLastSound && highspeedParallelMetadata.SlowedSinceLastSound)
                    {
                        int instanceId = AudioModule.CreateSoundInstance(AssetLocator.HighSpeedParallelSounds[RandomProvider.Next(0, AssetLocator.HighSpeedParallelSounds.Length)]);
                        AudioModule.PlaySoundInstance(
                            instanceId,
                            false,
                            HIGHSPEED_VOLUME * Config.SoundEffectVolume,
                            RandomProvider.Next(HIGHSPEED_PITCH_MIN, HIGHSPEED_PITCH_MAX)
                            );
                        highspeedParallelMetadata.CollidedSinceLastSound = highspeedParallelMetadata.SlowedSinceLastSound = false;
                        highspeedParallelMetadata.TimeAtLastSound        = timeRemainingMs;
                    }
                }
            }
            else
            {
                highspeedUpMetadata.SlowedSinceLastSound = highspeedDownMetadata.SlowedSinceLastSound = highspeedParallelMetadata.SlowedSinceLastSound = true;
            }

            // Countdown Timer
            if (!playingCountdownTimer && timeRemainingMs <= COUNTDOWN_TIMER_START_TIME_MS)
            {
                int instanceId = AudioModule.CreateSoundInstance(AssetLocator.CountdownLoopSound.File);
                AssetLocator.CountdownLoopSound.AddInstance(instanceId);
                AudioModule.PlaySoundInstance(instanceId, true, COUNTDOWN_VOLUME);
                playingCountdownTimer = true;
            }

            velocityLastFrame = ballVelo;
        }
예제 #3
0
        protected override void Tick(float deltaTimeSeconds)
        {
            base.Tick(deltaTimeSeconds);
            if (Egg.IsDisposed || Camera.IsDisposed || GameCoordinator.CurrentGameState != GameCoordinator.OverallGameState.LevelPlaying)
            {
                return;
            }

            // Declare some variables that we'll use below
            Vector3    eggPos                   = Egg.Transform.Translation;
            Vector3    eggVelo                  = Egg.TrueVelocity;
            Vector3    camPos                   = UnalteredCamPosition;
            Vector3    camOrientation           = UnalteredCamOrientation;
            Vector3    boardDownDir             = GameCoordinator.BoardDownDir;
            Plane      groundPlane              = GameCoordinator.GroundPlane;
            Quaternion boardTilt                = GameCoordinator.CurrentGameboardTilt;
            float      flopsErrorMargin         = MathUtils.FlopsErrorMargin;
            Vector3    verticalEggPos           = eggPos.ProjectedOnto(boardDownDir);
            Vector3    horizontalEggPos         = groundPlane.PointProjection(eggPos);
            Vector3    verticalEggVelo          = eggVelo.ProjectedOnto(boardDownDir);
            Vector3    horizontalEggVelo        = groundPlane.OrientationProjection(eggVelo);
            Vector3    verticalCamPos           = camPos.ProjectedOnto(boardDownDir);
            Vector3    horizontalCamPos         = groundPlane.PointProjection(camPos);
            Vector3    horizontalCamOrientation = groundPlane.OrientationProjection(camOrientation);
            Vector3    verticalCamOrientation   = camOrientation.ProjectedOnto(boardDownDir);
            Vector3    curUpDir                 = Camera.UpDirection;
            Vector3    targetUpDir              = -boardDownDir;

            Camera.Position = UnalteredCamPosition;

            // Find where the camera "wants" to be (only according to the egg velo)
            Vector3 reverseEggVelo = horizontalEggVelo.LengthSquared > GameplayConstants.MIN_EGG_SPEED_FOR_VELO_BASED_CAM_SQ ? -horizontalEggVelo : -horizontalCamOrientation;
            Vector3 targetPos      = eggPos + reverseEggVelo.WithLength(cameraDistance);

            // Add the height addition to the target pos
            float verticalAddition =
                verticalEggVelo.LengthSquared > horizontalEggVelo.LengthSquared &&
                verticalEggVelo.LengthSquared > GameplayConstants.MIN_FALL_SPEED_FOR_FALLING_CAM_SQ
                                ? cameraHeight + GameplayConstants.CAMERA_FALLING_HEIGHT_EXTRA
                                : cameraHeight;

            targetPos += -boardDownDir.WithLength(verticalAddition);

            // Calculate the rotation around the egg that the boom is making (in 3 dimensions!), and calculate the amount to rotate this frame
            Vector3 eggToTarget = targetPos - eggPos;

            eggToTarget *= boardTilt.Subrotation(GameplayConstants.CAM_BOARD_TILT_FACTOR);
            Vector3    eggToCam       = camPos - eggPos;
            float      eggToTargetLen = eggToTarget.Length;
            Quaternion cameraRot      = Quaternion.FromVectorTransition(eggToCam.ToUnit(), eggToTarget.ToUnit());

            eggToTarget = eggToCam * cameraRot.Subrotation(Math.Min(GameplayConstants.CAM_MOVE_SPEED_ANGULAR * deltaTimeSeconds, 1f));
            targetPos   = eggPos + (eggToTargetLen > flopsErrorMargin ? eggToTarget.WithLength(eggToTargetLen) : Vector3.ZERO);

            // Get the distance from the current pos to the target pos, calculate the amount to move closer this frame, and move the camera
            Vector3 camToTarget  = targetPos - camPos;
            float   movementDist =
                (float)Math.Pow(camToTarget.LengthSquared, GameplayConstants.CAM_MOVE_SPEED_EXPONENT_LINEAR)
                * deltaTimeSeconds;

            if (camToTarget.LengthSquared > flopsErrorMargin)
            {
                Camera.Move(camToTarget.WithLength(Math.Min(movementDist, camToTarget.Length)));
            }

            // Calculate the rotation of orientation, and then rotate the camera according to the rotation speed
            Vector3    newOrientation = (eggPos - camPos).ToUnit();
            Quaternion orientRot      = Quaternion.FromVectorTransition(camOrientation, newOrientation);
            Vector3    newCamUp;

            if (curUpDir == targetUpDir)
            {
                newCamUp = targetUpDir;
            }
            else
            {
                Quaternion curToTargetRot = Quaternion.FromVectorTransition(curUpDir, targetUpDir);
                newCamUp = curUpDir * curToTargetRot.Subrotation(GameplayConstants.CAM_UP_SUBROT_PER_SEC * deltaTimeSeconds);
            }
            Camera.Orient(
                camOrientation * orientRot.Subrotation(Math.Min(GameplayConstants.CAM_ORIENT_SPEED * deltaTimeSeconds, 1f)),
                newCamUp
                );

            // Adjust camera orientation and position according to right-stick
            float xDiff  = camOrientAltXTarget - camOrientAltXActual;
            float xDelta = xDiff * GameplayConstants.CAM_ORIENTATION_ADJUSTMENT_DELTA_FRAC_PER_SEC_X * deltaTimeSeconds;

            if (Math.Abs(camOrientAltXTarget) < Math.Abs(camOrientAltXActual))
            {
                xDelta = xDiff * GameplayConstants.CAM_ORIENTATION_ADJUSTMENT_DELTA_FRAC_PER_SEC_X_STOPPING * deltaTimeSeconds;
            }
            else
            {
                xDelta = Math.Max(
                    Math.Abs(xDelta),
                    Math.Min(
                        GameplayConstants.CAM_ORIENTATION_ADJUSTMENT_DELTA_ABS_MIN_PER_SEC_X * deltaTimeSeconds,
                        Math.Abs(xDiff)
                        )
                    ) * (xDiff < 0f ? -1f : 1f);
            }
            camOrientAltXActual = camOrientAltXActual + xDelta;

            float yDiff  = camOrientAltYTarget - camOrientAltYActual;
            float yDelta = yDiff * GameplayConstants.CAM_ORIENTATION_ADJUSTMENT_DELTA_FRAC_PER_SEC_Y * deltaTimeSeconds;

            if (Math.Abs(camOrientAltYTarget) < Math.Abs(camOrientAltYActual))
            {
                yDelta = yDiff * GameplayConstants.CAM_ORIENTATION_ADJUSTMENT_DELTA_FRAC_PER_SEC_Y_STOPPING * deltaTimeSeconds;
            }
            else
            {
                yDelta = Math.Max(
                    Math.Abs(yDelta),
                    Math.Min(
                        GameplayConstants.CAM_ORIENTATION_ADJUSTMENT_DELTA_ABS_MIN_PER_SEC_Y * deltaTimeSeconds,
                        Math.Abs(yDiff)
                        )
                    ) * (yDiff < 0f ? -1f : 1f);
            }
            camOrientAltYActual = camOrientAltYActual + yDelta;

            unalteredCamOrientation = Camera.Orientation;
            Vector3 alteredOrientation = unalteredCamOrientation;

            Quaternion forwardToUpRot = Quaternion
                                        .FromVectorTransition(alteredOrientation, -boardDownDir)
                                        .Subrotation(GameplayConstants.MAX_CAM_ORIENTATION_ADJUSTMENT_Y * camOrientAltYActual);

            var  verticalOrient    = alteredOrientation * forwardToUpRot;
            var  angleToFloor      = new Plane(-boardDownDir, eggPos).IncidentAngleWith(new Ray(camPos, verticalOrient));       // not sure why the 0.2f is needed but it is...
            bool useVerticalOrient =
                angleToFloor >= GameplayConstants.CAM_Y_ADJUSTMENT_HORIZONTAL_BUFFER_RADIANS_BOTTOM &&
                angleToFloor <= MathUtils.PI_OVER_TWO - GameplayConstants.CAM_Y_ADJUSTMENT_HORIZONTAL_BUFFER_RADIANS_TOP &&
                alteredOrientation.ProjectedOnto(-boardDownDir).ToUnit() != -boardDownDir;

            Quaternion forwardToLeftRot = Quaternion
                                          .FromAxialRotation(-boardDownDir, -MathUtils.PI_OVER_TWO)
                                          .Subrotation(GameplayConstants.MAX_CAM_ORIENTATION_ADJUSTMENT_X * camOrientAltXActual);

            alteredOrientation = (useVerticalOrient ? verticalOrient : unalteredCamOrientation) * forwardToLeftRot;
            Camera.Orient(alteredOrientation, useVerticalOrient ? Camera.UpDirection * forwardToUpRot : Camera.UpDirection);

            unalteredCamPosition = Camera.Position;
            Vector3 alteredPosition = unalteredCamPosition.Value;
            Vector3 downVec         = boardDownDir;
            Vector3 leftVec         = groundPlane.OrientationProjection(unalteredCamOrientation).ToUnit() * Quaternion.FromAxialRotation(boardDownDir, -MathUtils.PI_OVER_TWO);

            if (useVerticalOrient)
            {
                alteredPosition += downVec.WithLength(GameplayConstants.CAM_ADJUSTMENT_TRANSLATION_MAX_Y * camOrientAltYActual);
            }
            alteredPosition += leftVec.WithLength(GameplayConstants.CAM_ADJUSTMENT_TRANSLATION_MAX_X * camOrientAltXActual);

            Camera.Position = alteredPosition;

            unalteredCamPosition    = alteredPosition;
            unalteredCamOrientation = alteredOrientation;

            // Finally, make any geometry entities that are obscuring the view of the egg transparent
            var curLevel = GameCoordinator.CurrentlyLoadedLevel;

            hiddenEntityAccountingSpace.Clear();
            foreach (var key in hiddenEntities.Keys)
            {
                hiddenEntityAccountingSpace.Add(key);
            }
            EntityModule.RayTestAllLessGarbage(Ray.FromStartAndEndPoint(Camera.Position, eggPos), reusableRTCList);
            foreach (RayTestCollision rtc in reusableRTCList)
            {
                var geomEntity = rtc.Entity as GeometryEntity;
                if (geomEntity == null)
                {
                    continue;
                }

                if (hiddenEntities.ContainsKey(geomEntity))
                {
                    hiddenEntityAccountingSpace.Remove(geomEntity);
                    continue;
                }
                LevelGeometryEntity entityLevelRep = curLevel.GetLevelEntityRepresentation(geomEntity);
                Material            alphaMat       = new Material(entityLevelRep.Material.Name + " + Alpha", AssetLocator.AlphaFragmentShader);
                alphaMat.SetMaterialConstantValue(alphaMatColorBinding, new Vector4(
                                                      GameplayConstants.OBSCURING_GEOM_BRIGHTNESS,
                                                      GameplayConstants.OBSCURING_GEOM_BRIGHTNESS,
                                                      GameplayConstants.OBSCURING_GEOM_BRIGHTNESS,
                                                      GameplayConstants.OBSCURING_GEOM_MIN_ALPHA
                                                      ));
                ShaderResourceView texSRV = AssetLocator.LoadTexture(entityLevelRep.Material.TextureFileName).CreateView();
                alphaMat.SetMaterialResource(alphaMatTextureBinding, texSRV);
                hiddenEntities.Add(geomEntity, new HiddenEntityMetadata(
                                       alphaMat, texSRV, entityLevelRep, alphaMatColorBinding
                                       ));
                geomEntity.SetModelInstance(
                    AssetLocator.GameAlphaLayer,
                    curLevel.GetModelHandleForGeometry(entityLevelRep.Geometry),
                    alphaMat
                    );
            }

            foreach (KeyValuePair <GeometryEntity, HiddenEntityMetadata> kvp in hiddenEntities)
            {
                HiddenEntityMetadata metadata = kvp.Value;
                if (hiddenEntityAccountingSpace.Contains(kvp.Key))
                {
                    metadata.Alpha += GameplayConstants.OBSCURING_GEOM_ALPHA_REGAIN_SPEED * deltaTimeSeconds;
                    if (metadata.Alpha < GameplayConstants.OBSCURING_GEOM_MAX_ALPHA)
                    {
                        hiddenEntityAccountingSpace.Remove(kvp.Key);
                    }
                }
                else if (metadata.Alpha > GameplayConstants.OBSCURING_GEOM_MIN_ALPHA)
                {
                    metadata.Alpha -= GameplayConstants.OBSCURING_GEOM_ALPHA_REGAIN_SPEED * deltaTimeSeconds;
                }
            }

            foreach (GeometryEntity hiddenEntity in hiddenEntityAccountingSpace)
            {
                var hiddenEntityMetadata = hiddenEntities.Pop(hiddenEntity);
                AssetLocator.UnloadTexture(hiddenEntityMetadata.LevelRepresentation.Material.TextureFileName);
                hiddenEntityMetadata.TexSRV.Dispose();
                hiddenEntityMetadata.Material.Dispose();

                hiddenEntity.SetModelInstance(
                    AssetLocator.GameLayer,
                    curLevel.GetModelHandleForGeometry(hiddenEntityMetadata.LevelRepresentation.Geometry),
                    curLevel.GetLoadedMaterialForLevelMaterial(hiddenEntityMetadata.LevelRepresentation.Material)
                    );
            }
        }