Beispiel #1
0
        public virtual void Dispose()
        {
            using (RenderingModule.RenderStateBarrier.AcquirePermit(withLock: instanceMutationLock)) {
                currentGeometryEntities.Values.ForEach(e => e.Dispose());
                currentMaterials.ForEach(kvp => kvp.Value.Dispose());
                if (currentCache != null)
                {
                    currentCache.Dispose();
                }
                if (currentSkydomeCache != null)
                {
                    currentSkydomeCache.Dispose();
                }

                textureViews.ForEach(kvp => {
                    AssetLocator.UnloadTexture(kvp.Key);
                    kvp.Value.Dispose();
                });
                textureViews.Clear();

                precalculatedTriangles.Clear();
            }

            GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce;
            GC.Collect(2, GCCollectionMode.Forced, true);
        }
Beispiel #2
0
        private static void UnloadCurrentlyLoaded()
        {
            foreach (var kvp in loadedTextures)
            {
                AssetLocator.UnloadTexture(kvp.Value);
            }

            loadedTextures.Clear();
        }
Beispiel #3
0
        public override PhysicsShapeHandle CreatePhysicsShape(out Vector3 shapeOffset)
        {
            shapeOffset = Vector3.ZERO;

            if (this.Transform == Transform.DEFAULT_TRANSFORM)
            {
                var potentialResult = WorldModelCache.GetCachedModel(ModelFileName);
                if (potentialResult.HasValue)
                {
                    return(potentialResult.Value);
                }
            }

            List <DefaultVertex> outVerts;
            List <uint>          outIndices;

            GetVertexDataUnscaled(out outVerts, out outIndices);

            string acdFileName = ModelFileName;

            if (MirrorX)
            {
                acdFileName = Path.GetFileNameWithoutExtension(acdFileName) + "_mirrored" + Path.GetExtension(acdFileName);
            }
            var result = PhysicsManager.CreateConcaveHullShape(
                outVerts.Select(df => df.Position),
                outIndices.Select(@uint => (int)@uint),
                new CollisionShapeOptionsDesc(Transform.Scale),
                AssetLocator.CreateACDFilePath(acdFileName)
                );

            if (this.Transform == Transform.DEFAULT_TRANSFORM)
            {
                WorldModelCache.SetCachedModel(ModelFileName, result);
            }

            return(result);
        }
Beispiel #4
0
        public static void LoadLevel(LevelID levelID)
        {
            lock (staticMutationLock) {
                UnloadCurrentlyLoaded();

                string filename = Path.Combine("Previews\\", "level" + levelID.WorldIndex + "-" + levelID.LevelIndex + ".png");
                if (!File.Exists(Path.Combine(AssetLocator.MaterialsDir, filename)))
                {
                    loadedTextures.Add(new KeyValuePair <ITexture2D, string>(
                                           AssetLocator.LoadTexture("blue.bmp", false),
                                           "blue.bmp"
                                           ));
                }
                else
                {
                    loadedTextures.Add(new KeyValuePair <ITexture2D, string>(
                                           AssetLocator.LoadTexture(filename, false),
                                           filename
                                           ));
                }

                curTexIndex = 0;
            }
        }
Beispiel #5
0
        public static void LoadWorld(byte worldIndex)
        {
            lock (staticMutationLock) {
                UnloadCurrentlyLoaded();

                for (int i = 0; i < NUM_IMAGES_PER_WORLD; ++i)
                {
                    string filename = Path.Combine("Previews\\", "world" + worldIndex + "-" + i + ".png");
                    if (!File.Exists(Path.Combine(AssetLocator.MaterialsDir, filename)))
                    {
                        string stubfile = "blue.bmp";
                        if (i % 3 == 1)
                        {
                            stubfile = "green.bmp";
                        }
                        if (i % 3 == 2)
                        {
                            stubfile = "red.bmp";
                        }
                        loadedTextures.Add(new KeyValuePair <ITexture2D, string>(
                                               AssetLocator.LoadTexture(stubfile, false),
                                               stubfile
                                               ));
                    }
                    else
                    {
                        loadedTextures.Add(new KeyValuePair <ITexture2D, string>(
                                               AssetLocator.LoadTexture(filename, false),
                                               filename
                                               ));
                    }
                }

                curTexIndex = loadedTextures.Count - 1;
            }
        }
        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)
                    );
            }
        }
Beispiel #7
0
        public void RecreateMaterials()
        {
            lock (instanceMutationLock) {
                if (!materialsOutOfDate)
                {
                    return;
                }
            }

            FragmentShader fs = GetRecommendedFragmentShader();

            using (RenderingModule.RenderStateBarrier.AcquirePermit(withLock: instanceMutationLock)) {
                currentMaterials.ForEach(kvp => kvp.Value.Dispose());
                currentMaterials.Clear();
                textureViews.ForEach(kvp => {
                    AssetLocator.UnloadTexture(kvp.Key);
                    kvp.Value.Dispose();
                });
                textureViews.Clear();

                foreach (LevelMaterial levelMaterial in materials)
                {
                    Material           material = new Material(levelMaterial.Name + " [" + levelMaterial.ID + "]", fs);
                    ShaderResourceView srv;
                    if (textureViews.ContainsKey(levelMaterial.TextureFileName))
                    {
                        srv = textureViews[levelMaterial.TextureFileName];
                    }
                    else
                    {
                        ITexture2D loadedTexture = AssetLocator.LoadTexture(levelMaterial.TextureFileName, levelMaterial.GenerateMips);
                        srv = loadedTexture.CreateView();
                        textureViews[levelMaterial.TextureFileName] = srv;
                    }
                    material.SetMaterialResource((ResourceViewBinding)fs.GetBindingByIdentifier("DiffuseMap"), srv);
                    if (fs.ContainsBinding("MaterialProperties"))
                    {
                        material.SetMaterialConstantValue(
                            (ConstantBufferBinding)fs.GetBindingByIdentifier("MaterialProperties"),
                            new Vector4(0f, 0f, 0f, levelMaterial.SpecularPower)
                            );
                    }

                    if (fs.ContainsBinding("NormalMap"))
                    {
                        if (levelMaterial.NormalFileName != null)
                        {
                            var loadedNormalMap = AssetLocator.LoadTexture(levelMaterial.NormalFileName, levelMaterial.GenerateMips);
                            srv = loadedNormalMap.CreateView();
                            textureViews[levelMaterial.NormalFileName] = srv;
                        }
                        else
                        {
                            srv = AssetLocator.DefaultNormalMapView;
                        }
                        material.SetMaterialResource((ResourceViewBinding)fs.GetBindingByIdentifier("NormalMap"), srv);
                    }

                    if (fs.ContainsBinding("SpecularMap"))
                    {
                        if (levelMaterial.SpecularFileName != null)
                        {
                            var loadedSpecularMap = AssetLocator.LoadTexture(levelMaterial.SpecularFileName, levelMaterial.GenerateMips);
                            srv = loadedSpecularMap.CreateView();
                            textureViews[levelMaterial.SpecularFileName] = srv;
                        }
                        else
                        {
                            srv = AssetLocator.DefaultSpecularMapView;
                        }
                        material.SetMaterialResource((ResourceViewBinding)fs.GetBindingByIdentifier("SpecularMap"), srv);
                    }

                    if (fs.ContainsBinding("EmissiveMap"))
                    {
                        if (levelMaterial.EmissiveFileName != null)
                        {
                            var loadedEmissiveMap = AssetLocator.LoadTexture(levelMaterial.EmissiveFileName, levelMaterial.GenerateMips);
                            srv = loadedEmissiveMap.CreateView();
                            textureViews[levelMaterial.EmissiveFileName] = srv;
                        }
                        else
                        {
                            srv = AssetLocator.DefaultEmissiveMapView;
                        }
                        material.SetMaterialResource((ResourceViewBinding)fs.GetBindingByIdentifier("EmissiveMap"), srv);
                    }

                    currentMaterials.Add(levelMaterial, material);
                }

                materialsOutOfDate = false;
            }
        }