Exemple #1
0
        //Load our default setup!
        private void SetUpEditorScene(GraphicsDevice graphics)
        {
            ////////////////////////////////////////////////////////////////////////
            // Camera

            //Set up our starting camera position

            // NOTE: Coordinate system depends on Camera.up,
            //       Right now z is going up, it's not depth!

            Camera = new Camera(position: new Vector3(-88, -11f, 4), lookat: new Vector3(38, 8, 32));

            EnvironmentSample = new EnvironmentSample(new Vector3(-45, -5, 5));

            VolumeTexture = new VolumeTextureEntity("Content/Sponza/sponza_sdf.sdff", graphics, new Vector3(-7, 0, 63), new Vector3(200, 100, 100))
            {
                NeedsUpdate = true
            };

            _sdfGenerator = new SDFGenerator();

            ////////////////////////////////////////////////////////////////////////
            // GUI

            ////////////////////////////////////////////////////////////////////////
            // Static geometry

            // NOTE: If you don't pass a materialEffect it will use the default material from the object

            BasicEntity testEntity = AddEntity(model: _assets.SponzaModel,
                                               position: Vector3.Zero,
                                               angleX: Math.PI / 2,
                                               angleY: 0,
                                               angleZ: 0,
                                               scale: 0.1f,
                                               hasStaticPhysics: false);//CHANGE BACK


            //AddEntity(model: _assets.CloneTrooper,
            //    position: new Vector3(20, 0, 10),
            //    angleX: Math.PI / 2,
            //    angleY: 0,
            //    angleZ: 0,
            //    scale: 10.4f);

            for (int x = -5; x <= 5; x++)
            {
                for (int y = -5; y <= 5; y++)
                {
                    AddEntity(model: _assets.Plane,
                              materialEffect: ((x + 5 + y + 5) % 2 == 1) ? _assets.MirrorMaterial : _assets.MetalRough03Material,
                              position: new Vector3(30 + x * 4, y * 4 + 4, 0),
                              angleX: 0,
                              angleY: 0,
                              angleZ: 0,
                              scale: 2);
                }
            }

            AddEntity(model: _assets.StanfordDragon,
                      materialEffect: _assets.BaseMaterial,
                      position: new Vector3(40, -10, 0),
                      angleX: Math.PI / 2,
                      angleY: 0,
                      angleZ: 0,
                      scale: 10);

            ////////////////////////////////////////////////////////////////////////
            // Dynamic geometry

            // NOTE: We first have to create a physics object and then apply said object to a rendered model
            // BEPU could use non-default meshes, but that is much much more expensive so I am using just default ones right now
            // ... so -> spheres, boxes etc.
            // For dynamic meshes I could use the same way i have static meshes, but use - MobileMesh - instead

            // NOTE: Our physics entity's position will be overwritten, so it doesn't matter
            // NOTE: If a physics object has mass it will move, otherwise it is static

            Entity physicsEntity;

            //Just a ground box where nothing should fall through
            //_physicsSpace.Add(new Box(new BEPUutilities.Vector3(0, 0, -0.5f), 1000, 1000, 1));

            _physicsSpace.Add(physicsEntity = new Sphere(position: BEPUutilities.Vector3.Zero, radius: 5, mass: 50));
            AddEntity(model: _assets.IsoSphere,
                      materialEffect: _assets.AlphaBlendRim,
                      position: new Vector3(20, 0, 10),
                      angleX: Math.PI / 2,
                      angleY: 0,
                      angleZ: 0,
                      scale: 5,
                      PhysicsEntity: physicsEntity);

            testEntity.ApplyTransformation();
            _sdfGenerator.Generate(testEntity);

            for (int i = 0; i < 10; i++)
            {
                MaterialEffect test = _assets.SilverMaterial.Clone();
                test.Roughness = i / 9.0f + 0.1f;
                test.Metallic  = 1;
                _physicsSpace.Add(physicsEntity = new Sphere(position: BEPUutilities.Vector3.Zero, radius: 5, mass: 50));
                AddEntity(model: _assets.IsoSphere,
                          materialEffect: test,
                          position: new Vector3(30 + i * 10, 0, 10),
                          angleX: Math.PI / 2,
                          angleY: 0,
                          angleZ: 0,
                          scale: 5,
                          PhysicsEntity: physicsEntity);
            }

            ////////////////////////////////////////////////////////////////////////
            // Decals

            Decals.Add(new Decal(_assets.IconDecal, new Vector3(-6, 22, 15), 0, -Math.PI / 2, 0, Vector3.One * 10));

            ////////////////////////////////////////////////////////////////////////
            // Dynamic lights

            AddPointLight(position: new Vector3(-61, 0, 107),
                          radius: 150,
                          color: new Color(104, 163, 223),
                          intensity: 20,
                          castShadows: false,
                          shadowResolution: 1024,
                          staticShadow: false,
                          isVolumetric: true);

            AddPointLight(position: new Vector3(15, 0, 107),
                          radius: 150,
                          color: new Color(104, 163, 223),
                          intensity: 30,
                          castShadows: false,
                          shadowResolution: 1024,
                          staticShadow: false,
                          isVolumetric: true);

            AddPointLight(position: new Vector3(66, 0, 40),
                          radius: 120,
                          color: new Color(255, 248, 232),
                          intensity: 120,
                          castShadows: true,
                          shadowResolution: 1024,
                          softShadowBlurAmount: 0,
                          staticShadow: false,
                          isVolumetric: false);

            //volumetric light!
            //AddPointLight(position: new Vector3(-4, 40, 66),
            //    radius: 80,
            //    color: Color.White,
            //    intensity: 50,
            //    castShadows: true,
            //    shadowResolution: 1024,
            //    staticShadow: false,
            //    isVolumetric: true,
            //    volumetricDensity: 3);


            // Spawn a lot of lights to test performance

            //int sides = 4;
            //float distance = 20;
            //Vector3 startPosition = new Vector3(-30, 30, 1);

            ////amount of lights is sides*sides* sides*2

            //for (int x = 0; x < sides * 2; x++)
            //    for (int y = 0; y < sides; y++)
            //        for (int z = 0; z < sides; z++)
            //        {
            //            Vector3 position = new Vector3(x, -y, z) * distance + startPosition;
            //            AddPointLight(position, distance, FastRand.NextColor(), 50, false, false, 0.9f);
            //        }


            //AddDirectionalLight(direction: new Vector3(0.2f, 0.2f, -1),
            //    intensity: 100,
            //    color: Color.White,
            //    position: Vector3.UnitZ * 2,
            //    drawShadows: true,
            //    shadowWorldSize: 450,
            //    shadowDepth: 180,
            //    shadowResolution: 1024,
            //    shadowFilteringFiltering: DirectionalLightSource.ShadowFilteringTypes.SoftPCF3x,
            //    screenspaceShadowBlur: false);
        }
        /// <summary>
        /// Update whether or not Objects are in the viewFrustum and need to be rendered or not.
        /// </summary>
        /// <param name="entities"></param>
        /// <param name="boundingFrustrum"></param>
        /// <param name="hasCameraChanged"></param>
        public bool FrustumCulling(List <BasicEntity> entities, BoundingFrustum boundingFrustrum, bool hasCameraChanged, Vector3 cameraPosition)
        {
            //Check if the culling mode has changed
            if (_previousMode != GameSettings.g_CPU_Culling)
            {
                if (_previousMode)
                {
                    //If we previously did cull and now don't we need to set all the submeshes to render
                    for (int index1 = 0; index1 < Index; index1++)
                    {
                        MaterialLibrary matLib = MaterialLib[index1];
                        for (int i = 0; i < matLib.Index; i++)
                        {
                            MeshLibrary meshLib = matLib.GetMeshLibrary()[i];
                            for (int j = 0; j < meshLib.Rendered.Length; j++)
                            {
                                meshLib.Rendered[j] = _previousMode;
                            }
                        }
                    }
                }
                _previousMode = GameSettings.g_CPU_Culling;
            }

            if (!GameSettings.g_CPU_Culling)
            {
                return(false);
            }

            for (int index1 = 0; index1 < entities.Count; index1++)
            {
                BasicEntity entity = entities[index1];

                if (!hasCameraChanged && !entity.WorldTransform.HasChanged)// && entity.DynamicPhysicsObject == null)
                {
                    continue;
                }

                if (entity.WorldTransform.HasChanged)// || entity.DynamicPhysicsObject != null)
                {
                    entity.ApplyTransformation();
                }
            }

            bool hasAnythingChanged = false;

            //Ok we applied the transformation to all the entities, now update the submesh boundingboxes!
            // Parallel.For(0, Index, index1 =>
            for (int index1 = 0; index1 < Index; index1++)
            {
                float distance = 0;
                int   counter  = 0;


                MaterialLibrary matLib = GameSettings.g_CPU_Sort
                        ? MaterialLib[MaterialLibPointer[index1]]
                        : MaterialLib[index1];
                for (int i = 0; i < matLib.Index; i++)
                {
                    MeshLibrary meshLib    = matLib.GetMeshLibrary()[i];
                    float?      distanceSq = meshLib.UpdatePositionAndCheckRender(hasCameraChanged, boundingFrustrum,
                                                                                  cameraPosition, _defaultBoundingSphere);

                    //If we get a new distance, apply it to the material
                    if (distanceSq != null)
                    {
                        distance += (float)distanceSq;
                        counter++;
                        hasAnythingChanged = true;
                    }
                }

                if (Math.Abs(distance) > 0.00001f)
                {
                    distance /= counter;
                    matLib.DistanceSquared     = distance;
                    matLib.HasChangedThisFrame = true;
                }
            }    //);

            //finally sort the materials by distance. Bubble sort should in theory be fast here since little changes.
            if (hasAnythingChanged)
            {
                SortByDistance();
            }

            return(hasAnythingChanged);
        }