예제 #1
0
        public void BoundingFrustumToBoundingBoxTests()
        {
            var view        = Matrix.CreateLookAt(new Vector3(0, 0, 5), Vector3.Zero, Vector3.Up);
            var projection  = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, 1, 1, 100);
            var testFrustum = new BoundingFrustum(view * projection);

            var bbox1 = new BoundingBox(new Vector3(0, 0, 0), new Vector3(1, 1, 1));

            Assert.That(testFrustum.Contains(bbox1), Is.EqualTo(ContainmentType.Contains));
            Assert.That(testFrustum.Intersects(bbox1), Is.True);

            var bbox2 = new BoundingBox(new Vector3(-1000, -1000, -1000), new Vector3(1000, 1000, 1000));

            Assert.That(testFrustum.Contains(bbox2), Is.EqualTo(ContainmentType.Intersects));
            Assert.That(testFrustum.Intersects(bbox2), Is.True);

            var bbox3 = new BoundingBox(new Vector3(-1000, -1000, -1000), new Vector3(0, 0, 0));

            Assert.That(testFrustum.Contains(bbox3), Is.EqualTo(ContainmentType.Intersects));
            Assert.That(testFrustum.Intersects(bbox3), Is.True);

            var bbox4 = new BoundingBox(new Vector3(-1000, -1000, -1000), new Vector3(-500, -500, -500));

            Assert.That(testFrustum.Contains(bbox4), Is.EqualTo(ContainmentType.Disjoint));
            Assert.That(testFrustum.Intersects(bbox4), Is.False);
        }
예제 #2
0
        public override void GetVisibleLights(BoundingFrustum frustum, List <Light> visibleLights)
        {
            for (int i = 0; i < _worldLights.Count; i++)
            {
                Light light = _worldLights[i];
                if (light.Enabled)
                {
                    switch (light.LightType)
                    {
                    case Light.Type.Point:
                        if (frustum.Intersects(light.BoundingSphere))
                        {
                            visibleLights.Add(light);
                        }
                        break;

                    case Light.Type.Spot:
                        if (frustum.Intersects(light.BoundingSphere) &&
                            frustum.Intersects(light.Frustum))
                        {
                            visibleLights.Add(light);
                        }
                        break;

                    default:
                        throw new ArgumentOutOfRangeException();
                    }
                }
            }
        }
예제 #3
0
        public void BoundingFrustumToBoundingFrustumTests()
        {
            var view        = Matrix.CreateLookAt(new Vector3(0, 0, 5), Vector3.Zero, Vector3.Up);
            var projection  = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, 1, 1, 100);
            var testFrustum = new BoundingFrustum(view * projection);

            // Same frustum.
            Assert.That(testFrustum.Contains(testFrustum), Is.EqualTo(ContainmentType.Contains));
            Assert.That(testFrustum.Intersects(testFrustum), Is.True);

            var otherFrustum = new BoundingFrustum(Matrix.Identity);

            // Smaller frustum contained entirely inside.
            var view2       = Matrix.CreateLookAt(new Vector3(0, 0, 4), Vector3.Zero, Vector3.Up);
            var projection2 = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, 1, 1, 50);

            otherFrustum.Matrix = view2 * projection2;

            Assert.That(testFrustum.Contains(otherFrustum), Is.EqualTo(ContainmentType.Contains));
            Assert.That(testFrustum.Intersects(otherFrustum), Is.True);

            // Same size frustum, pointing in the same direction and offset by a small amount.
            otherFrustum.Matrix = view2 * projection;

            Assert.That(testFrustum.Contains(otherFrustum), Is.EqualTo(ContainmentType.Intersects));
            Assert.That(testFrustum.Intersects(otherFrustum), Is.True);

            // Same size frustum, pointing in the opposite direction and not overlapping.
            var view3 = Matrix.CreateLookAt(new Vector3(0, 0, 6), new Vector3(0, 0, 7), Vector3.Up);

            otherFrustum.Matrix = view3 * projection;

            Assert.That(testFrustum.Contains(otherFrustum), Is.EqualTo(ContainmentType.Disjoint));
            Assert.That(testFrustum.Intersects(otherFrustum), Is.False);

            // Larger frustum, entirely containing test frustum.
            var view4       = Matrix.CreateLookAt(new Vector3(0, 0, 10), Vector3.Zero, Vector3.Up);
            var projection4 = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, 1, 1, 1000);

            otherFrustum.Matrix = view4 * projection4;

            Assert.That(testFrustum.Contains(otherFrustum), Is.EqualTo(ContainmentType.Intersects));
            Assert.That(testFrustum.Intersects(otherFrustum), Is.True);

            var bf =
                new BoundingFrustum(Matrix.CreateLookAt(new Vector3(0, 1, 1), new Vector3(0, 0, 0), Vector3.Up) *
                                    Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4,
                                                                        1.3f, 0.1f, 1000.0f));
            var ray    = new Ray(new Vector3(0, 0.5f, 0.5f), new Vector3(0, 0, 0));
            var ray2   = new Ray(new Vector3(0, 1.0f, 1.0f), new Vector3(0, 0, 0));
            var value  = bf.Intersects(ray);
            var value2 = bf.Intersects(ray2);

            Assert.AreEqual(0.0f, value);
            Assert.AreEqual(null, value2);
        }
예제 #4
0
        /// <summary>
        /// Views the frustum test.
        /// </summary>
        /// <param name="viewFrustum">The view frustum.</param>
        /// <returns></returns>
        public override bool TestViewFrustum(ref BoundingFrustum viewFrustum)
        {
            if (!HasBound || !EnableViewFrustumCheck)
            {
                return(true);
            }
            var bound  = BoundsWithTransform;
            var sphere = BoundsSphereWithTransform;

            return(viewFrustum.Intersects(ref sphere) && viewFrustum.Intersects(ref bound));
        }
예제 #5
0
        /// <summary>
        /// Checks the bounding frustum.
        /// </summary>
        /// <param name="viewFrustum">The view frustum.</param>
        /// <returns></returns>
        protected virtual bool CheckBoundingFrustum(BoundingFrustum viewFrustum)
        {
            if (!HasBound)
            {
                return(true);
            }
            var bound  = BoundsWithTransform;
            var sphere = BoundsSphereWithTransform;

            return(viewFrustum.Intersects(ref bound) && viewFrustum.Intersects(ref sphere));
        }
예제 #6
0
 public override void GetVisibleMeshes(BoundingFrustum frustum, List<Mesh.SubMesh>[] visibleSubMeshes)
 {
     for (int index = 0; index < _worldSubMeshes.Count; index++)
     {
         Mesh.SubMesh subMesh = _worldSubMeshes[index];
         if (subMesh.Enabled && 
             frustum.Intersects(subMesh.GlobalBoundingSphere) &&
             frustum.Intersects(subMesh.GlobalBoundingBox))
         {
             visibleSubMeshes[(int)subMesh.RenderQueue].Add(subMesh);
         }
     }
 }
예제 #7
0
 public override void GetVisibleMeshes(BoundingFrustum frustum, List <Mesh.SubMesh>[] visibleSubMeshes)
 {
     for (int index = 0; index < _worldSubMeshes.Count; index++)
     {
         Mesh.SubMesh subMesh = _worldSubMeshes[index];
         if (subMesh.Enabled &&
             frustum.Intersects(subMesh.GlobalBoundingSphere) &&
             frustum.Intersects(subMesh.GlobalBoundingBox))
         {
             visibleSubMeshes[(int)subMesh.RenderQueue].Add(subMesh);
         }
     }
 }
예제 #8
0
 public override void GetShadowCasters(BoundingFrustum frustum, List <Mesh.SubMesh> visibleSubMeshes)
 {
     for (int index = 0; index < _worldSubMeshes.Count; index++)
     {
         Mesh.SubMesh subMesh = _worldSubMeshes[index];
         if (subMesh.Enabled && subMesh.CastShadows &&
             frustum.Intersects(subMesh.GlobalBoundingSphere) &&
             frustum.Intersects(subMesh.GlobalBoundingBox))
         {
             visibleSubMeshes.Add(subMesh);
         }
     }
 }
예제 #9
0
        public void BoundingFrustum_CalculatesIntersectsRayCorrectly()
        {
            var view    = Matrix.CreateLookAt(new Vector3(0, 0, 5), Vector3.Zero, Vector3.Up);
            var proj    = Matrix.CreatePerspectiveFieldOfView((float)Math.PI / 4f, 4f / 3f, 1f, 1000f);
            var frustum = new BoundingFrustum(view * proj);

            var ray1 = new Ray(new Vector3(0, 0, 10), Vector3.Zero - new Vector3(0, 0, 10));
            var ray2 = new Ray(new Vector3(0, 0, 10), -ray1.Direction);

            var result1 = frustum.Intersects(ray1);
            var result2 = frustum.Intersects(ray2);

            TheResultingValue(result1.Value).ShouldBe(0.6f);
            TheResultingValue(result2.HasValue).ShouldBe(false);
        }
예제 #10
0
            internal override void GetOverlaps(ref BoundingFrustum boundingFrustum, IList <int> outputOverlappedElements)
            {
                bool intersects;

                boundingFrustum.Intersects(ref ChildA.BoundingBox, out intersects);
                if (intersects)
                {
                    ChildA.GetOverlaps(ref boundingFrustum, outputOverlappedElements);
                }
                boundingFrustum.Intersects(ref ChildB.BoundingBox, out intersects);
                if (intersects)
                {
                    ChildB.GetOverlaps(ref boundingFrustum, outputOverlappedElements);
                }
            }
예제 #11
0
        public void RenderAll(Camera renderCamera, DwarfTime gameTime, GraphicsDevice graphicsDevice, Effect effect, Matrix worldMatrix, Texture2D tilemap)
        {
            effect.Parameters["xIllumination"].SetValue(ChunkData.IllumMap);
            effect.Parameters["xTexture"].SetValue(tilemap);
            effect.Parameters["xSunGradient"].SetValue(ChunkData.SunMap);
            effect.Parameters["xAmbientGradient"].SetValue(ChunkData.AmbientMap);
            effect.Parameters["xTorchGradient"].SetValue(ChunkData.TorchMap);
            effect.Parameters["xTint"].SetValue(new Vector4(1.0f, 1.0f, 1.0f, 1.0f));
            effect.Parameters["SelfIllumination"].SetValue(1);
            effect.Parameters["xEnableShadows"].SetValue(0);

			BoundingFrustum cameraFrustrum = renderCamera.GetFrustrum();
            foreach (EffectPass pass in effect.CurrentTechnique.Passes)
            {
                pass.Apply();
                foreach (KeyValuePair<Point3, VoxelChunk> chunk in ChunkData.ChunkMap)
                {
                    if (cameraFrustrum.Intersects(chunk.Value.GetBoundingBox()))
                    {
                        chunk.Value.Render(Graphics);
                    }
                }
            }
            effect.Parameters["SelfIllumination"].SetValue(0);
        }
예제 #12
0
        public override void Draw(GraphicsDevice gd, WorldState state)
        {
            var effect = WorldContent.RCObject;

            gd.BlendState = BlendState.NonPremultiplied;
            var vp = state.Camera.View * state.Camera.Projection;

            effect.Parameters["ViewProjection"].SetValue(vp);


            Blueprint.WCRC?.Draw(gd, state);

            gd.BlendState      = BlendState.NonPremultiplied;
            gd.RasterizerState = RasterizerState.CullNone;

            effect.CurrentTechnique = effect.Techniques["Draw"];
            var frustrum = new BoundingFrustum(vp);
            var objs     = Blueprint.Objects.Where(x => x.Level <= state.Level && frustrum.Intersects(((ObjectComponentRC)x).GetBounds()))
                           .OrderBy(x => ((ObjectComponentRC)x).SortDepth(vp));

            foreach (var obj in objs)
            {
                obj.Draw(gd, state);
            }

            foreach (var ava in Blueprint.Avatars)
            {
                if (ava.Level < state.Level)
                {
                    ava.DrawHeadline3D(gd, state);
                }
            }
            Drawn = true;
        }
예제 #13
0
        public void Render(GraphicsDevice device, float dT, Vector2 Reference, BoundingFrustum F)
        {
            foreach (KeyValuePair <int, Unit> bv in this.Blocks)
            {
                Unit block = bv.Value;
                if (block == null)
                {
                    continue;
                }
                BoundingBox bb = new BoundingBox(new Vector3((block.X - Reference.X) * BlockSize - 10, -1255, (block.Y - Reference.Y) * BlockSize - 10), new Vector3(((block.X - Reference.X) + 1) * BlockSize + 10, 1255, ((block.Y - Reference.Y) + 1) * BlockSize + 10));
                if (!F.Intersects(bb))
                {
                    continue;
                }
                TerrainEffect.CurrentTechnique = TerrainEffect.Techniques["TexturedTinted"];

                Matrix worldMatrix = Matrix.CreateTranslation((block.X - Reference.X) * BlockSize, 0, (block.Y - Reference.Y) * BlockSize);


                Vector3 Light = new Vector3(0.0f, -1.0f, 0.0f);
                Vector3.Transform(Light, Matrix.CreateRotationX(MathHelper.ToRadians(60)));
                TerrainEffect.Parameters["xWorld"].SetValue(worldMatrix);
                TerrainEffect.Parameters["xLightDirection"].SetValue(Light);
                TerrainEffect.CurrentTechnique.Passes[0].Apply();
                block.Render(device, dT);
            }
        }
예제 #14
0
파일: Camera3D.cs 프로젝트: enjame/GGJ13
        public bool FrustrumIntersects(ref BoundingSphere bs)
        {
            bool result;

            BoundingFrustum.Intersects(ref bs, out result);
            return(result);
        }
        /// <summary>
        /// Get the total number of visible dwarves, and resize our instance arrays accordingly
        /// </summary>
        /// <param name="frustum"></param>
        private void RefreshMeshCounts(BoundingFrustum frustum)
        {
            // Reset the counts of each part to 0
            for (int i = 0; i < this.meshPartCount.Length; i++)
            {
                this.meshPartCount[i] = 0;
            }

            // Loop through, and see if they are visible
            // If the dwarf is visible, make sure we add to the body part counters
            for (int i = 0; i < this.numInstances; i++)
            {
                Dwarf dwarf      = this.dwarves[i];
                bool  intersects = true;
                frustum.Intersects(ref dwarf.boundingSphere, out intersects);
                if (intersects)
                {
                    this.meshPartCount[dwarf.HeadPart]++;
                    this.meshPartCount[dwarf.BodyPart]++;
                    this.meshPartCount[dwarf.LegPart]++;
                }
                dwarf.IsVisible = intersects;
            }

            // Resize all the arrays accordingly
            for (int i = 0; i < this.meshInstances.Count; i++)
            {
                Array.Resize(ref this.meshInstances[i].transforms, meshPartCount[i]);
                Array.Resize(ref this.meshInstances[i].animations, meshPartCount[i]);
            }
        }
예제 #16
0
        public void RenderChunk(Chunk chunk)
        {
            UpdateEffects();

            BoundingFrustum viewFrustum = new BoundingFrustum(BananaGame.GameCamera.View * BananaGame.GameCamera.Projection);

            foreach (EffectPass pass in tileEffect.CurrentTechnique.Passes)
            {
                pass.Apply();
                if (viewFrustum.Intersects(chunk.Bounds))
                {
                    if (chunk.IndexBuffer != null && chunk.IndexBuffer.IndexCount > 0)
                    {
                        //VertCount += chunk.VertexBuffer.VertexCount;
                        BananaGame.Graphics.SetVertexBuffer(chunk.VertexBuffer);
                        BananaGame.Graphics.Indices = chunk.IndexBuffer;
                        BananaGame.Graphics.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, chunk.VertexBuffer.VertexCount, 0, chunk.IndexBuffer.IndexCount / 3);
                    }
                    if (chunk.State == ChunkState.AwaitingRender)
                    {
                        chunk.shapeM.Process(chunk);
                    }
                }
                //if (chunk.State == ChunkState.AwaitingProcess)
                //{
                //    chunk.State = ChunkState.InQueue;
                //    chunk.ProcessChunk();
                //}
            }
        }
예제 #17
0
파일: Camera3D.cs 프로젝트: enjame/GGJ13
        public bool FrustrumIntersects(ref BoundingBox bb)
        {
            bool result;

            BoundingFrustum.Intersects(ref bb, out result);
            return(result);
        }
예제 #18
0
파일: Race.cs 프로젝트: slasher79/OpenNFS1
        public void Render(bool renderPlayerVehicle)
        {
            Engine.Instance.Device.BlendState        = BlendState.Opaque;
            Engine.Instance.Device.DepthStencilState = DepthStencilState.Default;
            Engine.Instance.Device.SamplerStates[0]  = GameConfig.WrapSampler;

            Track.Render(Engine.Instance.Camera.Position, Player.Vehicle.CurrentNode);

            var frustum = new BoundingFrustum(Engine.Instance.Camera.View * Engine.Instance.Camera.Projection);

            foreach (var driver in Drivers)
            {
                bool isPlayer = driver == Player;
                if (isPlayer && !renderPlayerVehicle)
                {
                    continue;
                }

                if (!frustum.Intersects(driver.Vehicle.BoundingSphere))
                {
                    continue;
                }
                if (driver.Vehicle is DrivableVehicle)
                {
                    ((DrivableVehicle)driver.Vehicle).RenderShadow(isPlayer);
                }
                if (driver is AIDriver && ((AIDriver)driver).AtEndOfTrack)
                {
                    continue;
                }

                driver.Vehicle.Render();
            }
        }
예제 #19
0
        public void BoundingFrustum_CalculatesIntersectsBoundingBoxCorrectly()
        {
            var view    = Matrix.CreateLookAt(new Vector3(0, 0, 5), Vector3.Zero, Vector3.Up);
            var proj    = Matrix.CreatePerspectiveFieldOfView((float)Math.PI / 4f, 4f / 3f, 1f, 1000f);
            var frustum = new BoundingFrustum(view * proj);

            var sphere1 = new BoundingBox(new Vector3(0f, 0f, 0f), new Vector3(20f, 20f, 20f));
            var result1 = frustum.Intersects(sphere1);
            var sphere2 = new BoundingBox(new Vector3(-100f, -100f, -100f), new Vector3(-90f, -90f, -90f));
            var result2 = frustum.Intersects(sphere2);

            TheResultingValue(result1)
            .ShouldBe(true);
            TheResultingValue(result2)
            .ShouldBe(false);
        }
예제 #20
0
        // Token: 0x06000018 RID: 24 RVA: 0x000026C8 File Offset: 0x000008C8
        private static void SubAttackOnSight(Human E)
        {
            bool noTarget = E.NoTarget;

            if (noTarget)
            {
                bool flag = !E.CheckOutOfStackRange();
                if (flag)
                {
                    BoundingFrustum ViewFrustum = new BoundingFrustum(Matrix.CreateLookAt(E.Position, E.Position + E.HeadRotation.Forward, E.HeadRotation.Up) * Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(70f), 1f, 1f, E.CloseByRange));

                    foreach (Entity Ent in Ground.CStack.eList)
                    {
                        bool flag2 = Ent.ICode != E.ICode;
                        if (flag2)
                        {
                            bool flag3 = ViewFrustum.Intersects(new BoundingSphere(Ent.Position, 100f));
                            if (flag3)
                            {
                                bool flag4 = E.CheckAndLockTargetForSee(Ent) > AITargetMode.None;
                                if (flag4)
                                {
                                    break;
                                }
                            }
                        }
                    }
                }
            }
        }
예제 #21
0
        private void DrawOcclusions(BoundingFrustum viewFrustum)
        {
            if (postProcessingEffectsEnabled)
            {
                graphicsDevice.SetRenderTarget(occlusionRT);
                graphicsDevice.Clear(Color.Black);

                lightRenderer.Draw(level.Light, camera.Up, camera.Look);
                if (level.Type == LevelType.Outdoor)
                {
                    terrainRenderer.DrawOcclusion(level.Terrain);
                    terrainRenderer.DrawOcclusion(level.TerrainPlane);
                }
                foreach (Mesh mesh in level.MeshList)
                {
                    if (viewFrustum.Intersects(mesh.AABB))
                    {
                        meshRenderer.DrawMeshOcclusion(mesh, viewFrustum);
                    }
                }
                foreach (ShootingTarget target in level.ShootingTargetList)
                {
                    target.DrawOcclusion(meshRenderer, viewFrustum);
                }
                level.Sky.DrawOcclusion();
            }
        }
예제 #22
0
        private void DrawReflections(BoundingFrustum viewFrustum)
        {
            if (level.WaterHeight != Level.WATER_DISABLED_HEIGHT &&
                level.Water.TransparencyRatio > 0.0f)
            {
                graphicsDevice.SetRenderTarget(reflectionRT);
                graphicsDevice.Clear(Color.Black);

                BoundingFrustum reflViewFrustum = new BoundingFrustum(SharedEffectParameters.xReflectionViewMatrix
                                                                      * SharedEffectParameters.xReflectionProjectionMatrix);

                if (level.Type == LevelType.Outdoor)
                {
                    terrainRenderer.DrawReflection(level.Terrain);
                }

                // Draw mesh reflections
                foreach (Mesh mesh in level.MeshList)
                {
                    if (reflViewFrustum.Intersects(mesh.AABB))
                    {
                        meshRenderer.DrawMeshReflection(mesh, reflViewFrustum, level.WaterHeight);
                    }
                }

                // Draw target reflections
                foreach (ShootingTarget target in level.ShootingTargetList)
                {
                    target.DrawReflection(meshRenderer, reflViewFrustum, level.WaterHeight);
                }

                level.Sky.DrawCloudsReflection();
            }
        }
예제 #23
0
 public IEnumerable <T> EnumerateItems(BoundingFrustum SearchBounds)
 {
     lock (Lock)
     {
         if (!SearchBounds.Intersects(Bounds))
         {
             yield break;
         }
         if (Children == null)
         {
             foreach (var t in Items.Where(t => t.Item2.Intersects(SearchBounds)))
             {
                 yield return(t.Item1);
             }
         }
         else
         {
             for (var i = 0; i < 8; ++i)
             {
                 foreach (var item in Children[i].EnumerateItems(SearchBounds))
                 {
                     yield return(item);
                 }
             }
         }
     }
 }
예제 #24
0
        public bool Intersects(BoundingFrustum frustrum, Vector3 absolutePosition)
        {
            switch (Type)
            {
            case LocalisedBoundingRegionType.Sphere:
                return(frustrum.Intersects(new BoundingSphere(absolutePosition, Radius)));

            case LocalisedBoundingRegionType.Box:
                return(frustrum.Intersects(new Microsoft.Xna.Framework.BoundingBox(absolutePosition - RelativeOrigin, absolutePosition - RelativeOrigin + Size)));

            case LocalisedBoundingRegionType.Ray:
                return(frustrum.Intersects(new Ray(absolutePosition, RayVector)) != null);
            }

            return(false);
        }
예제 #25
0
        public void RenderAll(Camera renderCamera, DwarfTime gameTime, GraphicsDevice graphicsDevice, Shader effect, Matrix worldMatrix, Texture2D tilemap)
        {
            effect.SelfIlluminationTexture  = ChunkData.IllumMap;
            effect.MainTexture              = tilemap;
            effect.SunlightGradient         = ChunkData.SunMap;
            effect.AmbientOcclusionGradient = ChunkData.AmbientMap;
            effect.TorchlightGradient       = ChunkData.TorchMap;
            effect.LightRampTint            = Color.White;
            effect.VertexColorTint          = Color.White;
            effect.SelfIlluminationEnabled  = true;
            effect.EnableShadows            = false;

            BoundingFrustum cameraFrustrum = renderCamera.GetFrustrum();

            foreach (EffectPass pass in effect.CurrentTechnique.Passes)
            {
                pass.Apply();
                foreach (KeyValuePair <Point3, VoxelChunk> chunk in ChunkData.ChunkMap)
                {
                    if (cameraFrustrum.Intersects(chunk.Value.GetBoundingBox()))
                    {
                        chunk.Value.Render(Graphics);
                    }
                }
            }
            effect.SelfIlluminationEnabled = false;
        }
예제 #26
0
        public override void DrawArch(GraphicsDevice gd, WorldState parentState)
        {
            var parentScroll = parentState.CenterTile;

            if (!(parentState.Camera is WorldCamera))
            {
                parentState.Camera.Translation = new Vector3(GlobalPosition.X * 3, 0, GlobalPosition.Y * 3);
            }
            else
            {
                parentState.CenterTile += GlobalPosition;  //TODO: vertical offset
            }
            if (State.Light != null)
            {
                State.PrepareLighting();
            }
            else
            {
                parentState.ClearLighting(true);
            }

            var level = parentState.SilentLevel;
            var build = parentState.SilentBuildMode;

            parentState.SilentLevel     = 5;
            parentState.SilentBuildMode = 0;
            Blueprint.Terrain._3D       = true;
            Blueprint.Terrain.Draw(gd, parentState);
            parentState.SilentBuildMode = build;
            var effect = WorldContent.RCObject;

            gd.BlendState       = BlendState.NonPremultiplied;
            parentState.DrawOOB = false;
            var view = parentState.Camera.View;
            var vp   = view * parentState.Camera.Projection;

            effect.Parameters["ViewProjection"].SetValue(vp);
            Blueprint.WCRC.Draw(gd, parentState);
            Blueprint.RoofComp.Draw(gd, parentState);
            parentState.SilentLevel = level;
            effect.CurrentTechnique = effect.Techniques["Draw"];
            gd.BlendState           = BlendState.NonPremultiplied;

            var frustrum = new BoundingFrustum(vp);
            var objs     = Blueprint.Objects.Where(x => frustrum.Intersects(((ObjectComponentRC)x).GetBounds()))
                           .OrderBy(x => ((ObjectComponentRC)x).SortDepth(view));

            foreach (var obj in objs)
            {
                obj.Draw(gd, parentState);
            }

            parentState.CenterTile = parentScroll;
            if (!(parentState.Camera is WorldCamera))
            {
                parentState.Camera.Translation = Vector3.Zero;
            }
            parentState.PrepareLighting();
        }
예제 #27
0
        private bool IsWithinView(ChunkCoordinates chunk, BoundingFrustum frustum)
        {
            var chunkPos = new Vector3(chunk.X * ChunkColumn.ChunkWidth, 0, chunk.Z * ChunkColumn.ChunkDepth);

            return(frustum.Intersects(new Microsoft.Xna.Framework.BoundingBox(chunkPos,
                                                                              chunkPos + new Vector3(ChunkColumn.ChunkWidth, _cameraPosition.Y + 10,
                                                                                                     ChunkColumn.ChunkDepth))));
        }
예제 #28
0
        public bool CullTest(ref BoundingBox aabb)
        {
            bool isVisible;

            boundingfrustum.Intersects(ref aabb, out isVisible);

            return(!isVisible);
        }
예제 #29
0
            public int Compare(Candidate candidate1, Candidate candidate2)
            {
                float distance1;

                Vector3.DistanceSquared(ref candidate1.CenterWorld, ref EyePositionWorld, out distance1);

                float distance2;

                Vector3.DistanceSquared(ref candidate2.CenterWorld, ref EyePositionWorld, out distance2);

                // 優先領域にある物をより優先。
                if (distance1 <= priorDistanceSquared && priorDistanceSquared < distance2)
                {
                    return(-1);
                }
                if (priorDistanceSquared < distance1 && distance2 <= priorDistanceSquared)
                {
                    return(1);
                }

                // 視錐台に含まれる物は、含まれない物より優先。
                bool intersected1;

                Frustum.Intersects(ref candidate1.BoxWorld, out intersected1);
                bool intersected2;

                Frustum.Intersects(ref candidate2.BoxWorld, out intersected2);

                if (intersected1 && !intersected2)
                {
                    return(-1);
                }
                if (!intersected1 && intersected2)
                {
                    return(1);
                }

                // 互いに視錐台に含まれる、あるいは、含まれない場合、
                // より視点に近い物を優先。

                if (distance1 == distance2)
                {
                    return(0);
                }
                return(distance1 < distance2 ? -1 : 1);
            }
예제 #30
0
 public static void VisitTree(OctCell root, BoundingFrustum frustum, Action<OctCell> callback)
 {
     if (frustum.Intersects(root.Bounds))
     {
         if (root.Leaf) callback(root);
         else foreach (var child in root.Children) VisitTree(child, frustum, callback);
     }
 }
예제 #31
0
        public void BoundingFrustum_CalculatesIntersectsPlaneCorrectly()
        {
            var view    = Matrix.CreateLookAt(new Vector3(0, 0, 5), Vector3.Zero, Vector3.Up);
            var proj    = Matrix.CreatePerspectiveFieldOfView((float)Math.PI / 4f, 4f / 3f, 1f, 1000f);
            var frustum = new BoundingFrustum(view * proj);

            var plane1 = new Plane(frustum.Near.Normal, frustum.Near.D - 1000f);
            var plane2 = new Plane(frustum.Near.Normal, frustum.Near.D + 1000f);
            var plane3 = new Plane(frustum.Near.Normal, frustum.Near.D + 500f);

            var result1 = frustum.Intersects(plane1);
            var result2 = frustum.Intersects(plane2);
            var result3 = frustum.Intersects(plane3);

            TheResultingValue(result1).ShouldBe(PlaneIntersectionType.Back);
            TheResultingValue(result2).ShouldBe(PlaneIntersectionType.Front);
            TheResultingValue(result3).ShouldBe(PlaneIntersectionType.Intersecting);
        }
예제 #32
0
        public bool Intersects(OrientedBoundingBox oob)
        {
            Matrix          invoob  = Matrix.Invert(oob.Transformation);
            BoundingFrustum frustum = new BoundingFrustum(oob.Transformation * View * Projection);

            BoundingBox bbox = new BoundingBox(-oob.Extents, oob.Extents);

            return(frustum.Intersects(ref bbox));
        }
예제 #33
0
 public void GetVisibleLights(BoundingFrustum frustum, List<Light> visibleLights)
 {
     for (int index = 0; index < lights.Count; index++)
     {
         Light l = lights[index];
         if (l.Enabled && frustum.Intersects(l.BoundingSphere))
         {
             visibleLights.Add(l);
         }
     }
 }
예제 #34
0
        public void BoundingFrustumToBoundingBoxTests()
        {
            var view = Matrix.CreateLookAt(new Vector3(0, 0, 5), Vector3.Zero, Vector3.Up);
            var projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, 1, 1, 100);
            var testFrustum = new BoundingFrustum(view * projection);

            var bbox1 = new BoundingBox(new Vector3(0, 0, 0), new Vector3(1, 1, 1));
            Assert.That(testFrustum.Contains(bbox1), Is.EqualTo(ContainmentType.Contains));
            Assert.That(testFrustum.Intersects(bbox1), Is.True);

            var bbox2 = new BoundingBox(new Vector3(-1000, -1000, -1000), new Vector3(1000, 1000, 1000));
            Assert.That(testFrustum.Contains(bbox2), Is.EqualTo(ContainmentType.Intersects));
            Assert.That(testFrustum.Intersects(bbox2), Is.True);

            var bbox3 = new BoundingBox(new Vector3(-1000, -1000, -1000), new Vector3(0, 0, 0));
            Assert.That(testFrustum.Contains(bbox3), Is.EqualTo(ContainmentType.Intersects));
            Assert.That(testFrustum.Intersects(bbox3), Is.True);

            var bbox4 = new BoundingBox(new Vector3(-1000, -1000, -1000), new Vector3(-500, -500, -500));
            Assert.That(testFrustum.Contains(bbox4), Is.EqualTo(ContainmentType.Disjoint));
            Assert.That(testFrustum.Intersects(bbox4), Is.False);
        }
예제 #35
0
 public void GetVisibleMeshes(BoundingFrustum frustum, List<Mesh.SubMesh> visibleSubMeshes)
 {
     for (int index = 0; index < meshes.Count; index++)
     {
         Mesh m = meshes[index];
         if (frustum.Intersects(m.GlobalBoundingBox))
         {
             for (int si = 0; si < m.SubMeshes.Count; si++)
             {
                 Mesh.SubMesh sm = m.SubMeshes[si];
                 if (sm.Enabled) visibleSubMeshes.Add(sm);
             }
         }
     }
 }
예제 #36
0
        public virtual void Draw(Matrix view, Matrix projection)
        {
            baseTransforms = new Matrix[this.Model.Bones.Count];
            this.Model.CopyAbsoluteBoneTransformsTo(baseTransforms);

            // Do nothing if the object is outside the view frustum
            BoundingFrustum viewFrustum = new BoundingFrustum(view * projection);
            if (viewFrustum.Intersects(BoundingSphere))
            {
                world = Matrix.CreateScale(Scale) * Matrix.CreateFromYawPitchRoll(Rotation.Y, Rotation.X, Rotation.Z) * Matrix.CreateTranslation(Position);

                foreach (ModelMesh mesh in Model.Meshes)
                {
                    foreach (Effect currentEffect in mesh.Effects)
                    {
                        if (currentEffect is BasicEffect)
                        {
                            BasicEffect effect = currentEffect as BasicEffect;
                            effect.World = baseTransforms[mesh.ParentBone.Index] * world;
                            effect.View = view;
                            effect.Projection = projection;
                        }
                        else
                        {
                            EffectParameterCollection parameters = currentEffect.Parameters;
                            if (parameters["World"] != null)
                                parameters["World"].SetValue(baseTransforms[mesh.ParentBone.Index] * world);
                            if (parameters["View"] != null)
                                parameters["View"].SetValue(view);
                            if (parameters["Projection"] != null)
                                parameters["Projection"].SetValue(projection);
                        }
                        SetEffectParameters(currentEffect);
                    }
                    mesh.Draw();
                }
            }
        }
예제 #37
0
        public void UpdateVisible(CollisionGrid cg)
        {
            // All Team Friendly Units Are Visible
            BoundingFrustum frustum = new BoundingFrustum(Camera.View * Camera.Projection);

            // Update Units
            Predicate<RTSUnit> fFVU = (u) => {
                return frustum.Intersects(u.BBox);
            };
            foreach(var um in FriendlyUnitModels)
                um.UpdateInstances(G, GameplayController.IsUnitDead, fFVU);

            Predicate<RTSUnit> fNFVU = (u) => {
                Point up = HashHelper.Hash(u.GridPosition, cg.numCells, cg.size);
                if(cg.GetFogOfWar(up.X, up.Y, teamIndex) != FogOfWar.Active)
                    return false;
                return frustum.Intersects(u.BBox);
            };
            foreach(var um in NonFriendlyUnitModels)
                um.UpdateInstances(G, GameplayController.IsUnitDead, UseFOW ? fNFVU : fFVU);

            // Update Buildings
            Predicate<BoundingBox> fFVB = (b) => {
                return frustum.Intersects(b);
            };
            foreach(var bm in FriendlyBuildingModels)
                bm.UpdateInstances(G, fFVB);
            foreach(var bm in NonFriendlyBuildingModels)
                bm.UpdateInstances(G, fFVB);
        }
예제 #38
0
파일: Unit.cs 프로젝트: DagonGD/Game3
        /// <summary>
        /// Проверка столкновения юнита с заданной пирамидой вида
        /// </summary>
        /// <param name="boundingFrustum">Пирамида вида</param>
        /// <returns>Истина если пересекаются</returns>
        public bool Intersects(BoundingFrustum boundingFrustum)
        {
            //if (BoundingBox != null)
            //    return boundingFrustum.Intersects(BoundingBox.Value);

            if (Type.Model == null)
                return true;

            return Type.Model.Meshes.Any(mesh => boundingFrustum.Intersects(
                mesh.BoundingSphere.Transform(GetResultingTransformation(Transforms[mesh.ParentBone.Index]))));
        }
예제 #39
0
        private void RenderChildren(BoundingFrustum frustum, CActor actor, Matrix world, bool parentAnimated)
        {
            if (RenderWheelsSeparately && actor.IsWheel) return;

            bool intersects;

            if (frustum == null)
            {
                intersects = true;
            }
            else
            {
                intersects = actor.BoundingBox.Max.X == 0;
                if (!intersects)
                {
                    frustum.Intersects(ref actor.BoundingBox, out intersects);
                    GameVars.NbrSectionsChecked++;
                }
            }

            if (intersects)
            {
                Matrix m = actor.GetDynamicMatrix();

                if (actor.IsAnimated || parentAnimated)
                {
                    if (actor.IsAnimated && !parentAnimated)
                    {
                        world = m * actor.ParentMatrix * GameVars.ScaleMatrix * world;
                    }
                    else
                    {
                        world = m * world;
                    }

                    GameVars.CurrentEffect.World = world;
                    parentAnimated = true;
                }
                else
                {
                    GameVars.CurrentEffect.World = m * world;
                }

                GameVars.CurrentEffect.CommitChanges();

                if (actor.Model != null)
                {
                    actor.Model.Render(actor.Material);
                    if (actor.Model is CDeformableModel)
                    {
                        Models.SetupRender();
                    }
                }

                GameVars.NbrSectionsRendered++;

                foreach (CActor child in actor.Children)
                    RenderChildren(frustum, child, world, parentAnimated);
            }
        }
예제 #40
0
파일: Race.cs 프로젝트: sikora507/OpenC1
        public void Render()
        {
            if (_skybox != null) _skybox.Draw();

            BoundingFrustum frustum = new BoundingFrustum(Engine.Camera.View * Engine.Camera.Projection);
            _actors.Render(Matrix.Identity, frustum);

            foreach (Opponent opponent in Opponents)
            {
                if (frustum.Intersects(opponent.GetBoundingSphere()))
                {
                    opponent.Driver.InPlayersView = true;
                    opponent.Vehicle.Render();
                }
                else
                {
                    opponent.Vehicle.SkidMarkBuffer.Render();  //always render skids
                    opponent.Driver.InPlayersView = false;
                }
                opponent.Driver.DistanceFromPlayer = Vector3.Distance(PlayerVehicle.Position, opponent.Vehicle.Position);
            }

            Peds.Render();

            RaceTime.Render();
            MessageRenderer.Instance.Render();
            //Engine.DebugRenderer.AddAxis(Matrix.CreateTranslation(ConfigFile.GridPosition), 10);

            if (_map.Show)
            {
                _map.Render();
                return;
            }
        }
예제 #41
0
        public void BoundingFrustumToBoundingFrustumTests()
        {
            var view = Matrix.CreateLookAt(new Vector3(0, 0, 5), Vector3.Zero, Vector3.Up);
            var projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, 1, 1, 100);
            var testFrustum = new BoundingFrustum(view * projection);

            // Same frustum.
            Assert.That(testFrustum.Contains(testFrustum), Is.EqualTo(ContainmentType.Contains));
            Assert.That(testFrustum.Intersects(testFrustum), Is.True);

            var otherFrustum = new BoundingFrustum(Matrix.Identity);

            // Smaller frustum contained entirely inside.
            var view2 = Matrix.CreateLookAt(new Vector3(0, 0, 4), Vector3.Zero, Vector3.Up);
            var projection2 = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, 1, 1, 50);
            otherFrustum.Matrix = view2 * projection2;

            Assert.That(testFrustum.Contains(otherFrustum), Is.EqualTo(ContainmentType.Contains));
            Assert.That(testFrustum.Intersects(otherFrustum), Is.True);

            // Same size frustum, pointing in the same direction and offset by a small amount.
            otherFrustum.Matrix = view2 * projection;

            Assert.That(testFrustum.Contains(otherFrustum), Is.EqualTo(ContainmentType.Intersects));
            Assert.That(testFrustum.Intersects(otherFrustum), Is.True);

            // Same size frustum, pointing in the opposite direction and not overlapping.
            var view3 = Matrix.CreateLookAt(new Vector3(0, 0, 6), new Vector3(0, 0, 7), Vector3.Up);
            otherFrustum.Matrix = view3 * projection;

            Assert.That(testFrustum.Contains(otherFrustum), Is.EqualTo(ContainmentType.Disjoint));
            Assert.That(testFrustum.Intersects(otherFrustum), Is.False);

            // Larger frustum, entirely containing test frustum.
            var view4 = Matrix.CreateLookAt(new Vector3(0, 0, 10), Vector3.Zero, Vector3.Up);
            var projection4 = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, 1, 1, 1000);
            otherFrustum.Matrix = view4 * projection4;

            Assert.That(testFrustum.Contains(otherFrustum), Is.EqualTo(ContainmentType.Intersects));
            Assert.That(testFrustum.Intersects(otherFrustum), Is.True);
        }
예제 #42
0
        /// <summary>
        /// Checks if the light source is visible in the specified camera. 
        /// Outputs the world -> NDC transformation for use in a shadow caster (light depth) render pass.
        /// Should generate a frustum for the light, which
        /// A) Contains the intersection between the scene and the camera view frustum
        /// B) Contains also the part of the scene which may cast shadows onto A)
        /// C) Is as small as possible
        /// </summary>
        public bool IsVisible(Matrix cameraViewProjection, out Matrix viewProjectionForShadowCaster)
        {
            viewProjectionForShadowCaster = new Matrix();
            switch (Kind)
            {
                case LightKind.Global:
                {
                    if (CastsShadows)
                        throw new NotImplementedException();
                    return true;
                }
                case LightKind.Directional:
                {
                    if (CastsShadows)
                    {
                        // Choose a view matrix with the right orientation and arbitrary position (zero)
                        var up = Math.Abs(Direction.Y) < 0.95f ? Vector3.UnitY : Vector3.UnitZ;
                        var worldToLightCam = Matrix.CreateLookAt(Vector3.Zero, Direction, up);

                        // Map the camera's view frustum to the light cam coordinates
                        var worldToCameraNDC = cameraViewProjection;
                        var cameraNDCToLightCam = Matrix.Invert(worldToCameraNDC) * worldToLightCam;
                        var bounds = BoundingBox.CreateFromPoints(NDCBounds.Select(pt => pt.TransformHomogenous(cameraNDCToLightCam)));

                        // Make a projection matrix to cover exactly the bounds
                        // (but with a closer near plane, to also cover parts of the scene which cast shadows on the visible part)
                        //ToDo: the near plane should be calculated using a bounding volume of the scene
                        const float MinDepth = 50;
                        var far = -bounds.Min.Z;
                        var depth = Math.Max(bounds.Max.Z - bounds.Min.Z, MinDepth);
                        var lightCamToLightNDC = Matrix.CreateOrthographicOffCenter(bounds.Min.X, bounds.Max.X, bounds.Min.Y, bounds.Max.Y,
                            far - depth, far);

                        viewProjectionForShadowCaster = worldToLightCam * lightCamToLightNDC;
                    }
                    return true;
                }
                case LightKind.Point:
                {
                    if (CastsShadows)
                        throw new NotImplementedException();
                    var viewFrustum = new BoundingFrustum(cameraViewProjection);
                    var lightVolume = new BoundingSphere(Position, Range);
                    return viewFrustum.Intersects(lightVolume);
                }
                case LightKind.Spot:
                {
                    // Choose a view matrix with the right orientation and position
                    var up = Math.Abs(Direction.Y) < 0.95f ? Vector3.UnitY : Vector3.UnitZ;
                    var worldToLightCam = Matrix.CreateLookAt(Position, Position + Direction, up);

                    // Map the camera's view frustum to the light cam coordinates
            /*                    var worldToCameraNDC = cameraViewProjection;
                    var cameraNDCToLightCam = Matrix.Invert(worldToCameraNDC) * worldToLightCam;
                    var corners = NDCBounds.Select(pt => pt.TransformHomogenous(cameraNDCToLightCam)).ToList();

                    // Find the furthest point in the camera's view frustum within the cone of the light
                    // (measured along the negative Z axis which is the light direction)
                    var distToFurthest = 0f;
                    for (int iEdge = 0; iEdge < 12; iEdge++)
                    {
                        // Take an edge in "light cam" coordinates
                        var ptA = corners[NDCEdges[2*iEdge]];
                        var ptB = corners[NDCEdges[2*iEdge+1]];

                        // Find the furthest point on the edge in the cone with apex in Zero, axis going along -Z and angle SpotAngle

                    }

                    // Find the closest and furthest point in the camera's view frustum from the light source
                    // ToDo: should be the furthest point in the intersection between the frustum and the light cone
                    var lightCamToCameraNDC = Matrix.Invert(worldToLightCam) * cameraViewProjection;
                    var viewFrustum = new BoundingFrustum(lightCamToCameraNDC);*/

                    var distToFurthest = Range;
                    var distToClosest = Range / 8;

                    // Make a projection matrix to cover exactly the bounds
                    var lightCamToLightNDC = Matrix.CreatePerspectiveFieldOfView(2 * SpotAngle, 1, distToClosest, distToFurthest);

                    viewProjectionForShadowCaster = worldToLightCam * lightCamToLightNDC;

                    // ToDo: map the camera frustum to light NDC and check if it intersects the cylinder corresponding to the spot light cone
                    return new BoundingFrustum(cameraViewProjection).Intersects(new BoundingFrustum(viewProjectionForShadowCaster));
                }
                default:
                    throw new ArgumentOutOfRangeException();
            }
        }
예제 #43
0
        public void Update(Vector3 cameraPosition, BoundingFrustum cameraFrustum)
        {
            // Frustum culling
            _visiblePatches.Clear();
            foreach (Patch p in _patches)
            {
                p.Visible = cameraFrustum.Intersects(p.BoundingBox);
                if (p.Visible)
                {
                    _visiblePatches.Add(p);
                    p.UpdateDistanceFromCamera(cameraPosition);
                }
                else
                {
                    p.ActiveLevel = 0;
                }
            }

            _visiblePatches.Sort();

            int minLevel = 0;
            int processedPatches = 0;
            foreach (Patch p in _visiblePatches)
            {
                while (minLevel < _numLevels - 1 && processedPatches >= MaxPatchesAtLevel[minLevel])
                {
                    minLevel++;
                }
                p.ActiveLevel = minLevel;
                processedPatches++;
            }

            bool changed;
            do
            {
                changed = false;
                foreach (Patch p in _visiblePatches)
                {
                    int maxActiveLevel = p.ActiveLevel;
                    if (p.TopActiveLevel != int.MaxValue) maxActiveLevel = Math.Max(maxActiveLevel, p.TopActiveLevel);
                    if (p.BottomActiveLevel != int.MaxValue) maxActiveLevel = Math.Max(maxActiveLevel, p.BottomActiveLevel);
                    if (p.LeftActiveLevel != int.MaxValue) maxActiveLevel = Math.Max(maxActiveLevel, p.LeftActiveLevel);
                    if (p.RightActiveLevel != int.MaxValue) maxActiveLevel = Math.Max(maxActiveLevel, p.RightActiveLevel);
                    if (p.ActiveLevel < maxActiveLevel - 1)
                    {
                        changed = true;
                        p.ActiveLevel = maxActiveLevel - 1;
                    }
                }
            } while (changed);

            foreach (Patch p in _visiblePatches)
            {
                p.UpdateTessellation();
            }
        }
예제 #44
0
        ////////////////////////////////////////////////////////////////////
        /// <summary>
        /// Yet another recursive function. This function takes the position of the camera, and statuses all the children nodes of the 
        /// specified quadnode based on their distance. It then recurses down the tree, statusing as it goes.
        /// In essence, this function is what applies our LOD
        /// 
        /// Addition: I've integrated the frustrum checks into this algorithm, to improve performance.
        /// </summary>
        /// <param name="qNode">The root node.</param>
        /// <param name="cameraPoint">The camera's position</param>
        /// <param name="LODLevel">The LOD Distance to apply. 3.5 is the recommended minimum, because of stitching issues. Less than 2 may cause an unhandled exception.</param>
        private void RecursiveChildStatus(QuadNode qNode, Vector3 cameraPoint, float LODLevel, BoundingFrustum CameraFrustrum)
        {
            //Determine the squared distance of the camera from the specified node, taking into account the size of the node and the scale of 
            //the terrain.
            //This value doesn't undergo a Sqrt to save processing power: instead, the opposite side is sqared
            qNode.distanceFromCamera = (float)(Math.Pow(Math.Abs(cameraPoint.X - ((qNode.XPosition + (qNode.NodeScale / 2)) * Scale)), 2) + Math.Pow(Math.Abs(cameraPoint.Y - ((0 + (qNode.NodeScale / 2)) * Scale)), 2) * LODHeightImpact + Math.Pow(Math.Abs(cameraPoint.Z - ((qNode.YPosition + (qNode.NodeScale / 2)) * Scale)), 2));

            /////////////////////////////////////////////////
            //Staus this node as 1...
            qNode.status = 1;
            //...then, if node depth is not too deep...
            if (qNode.NodeDepth < maxNodeDepth)
            {
                float leftUpLOD = qNode.leftUpNode.NodeScale * Scale * LODLevel;
                float leftDownLOD = qNode.leftDownNode.NodeScale * Scale * LODLevel;
                float rightUpLOD = qNode.rightUpNode.NodeScale * Scale * LODLevel;
                float rightDownLOD = qNode.rightDownNode.NodeScale * Scale * LODLevel;

                leftUpLOD *= leftUpLOD;
                leftDownLOD *= leftDownLOD;
                rightUpLOD *= rightUpLOD;
                rightDownLOD *= rightDownLOD;

                //...determine whether or not to recurse onto the nodes children.
                if (qNode.distanceFromCamera < leftUpLOD)
                {
                    if (CameraFrustrum.Intersects(qNode.leftUpNode.boundBox))
                    {
                        qNode.status = 2;
                        RecursiveChildStatus(qNode.leftUpNode, cameraPoint, LODLevel, CameraFrustrum);
                    }
                    else
                    {
                        qNode.leftUpNode.inView = false;
                        qNode.status = 2;
                    }
                }
                if (qNode.distanceFromCamera < leftDownLOD)
                {
                    if (CameraFrustrum.Intersects(qNode.leftDownNode.boundBox))
                    {
                        qNode.status = 2;
                        RecursiveChildStatus(qNode.leftDownNode, cameraPoint, LODLevel, CameraFrustrum);
                    }
                    else
                    {
                        qNode.leftDownNode.inView = false;
                        qNode.status = 2;
                    }
                }
                if (qNode.distanceFromCamera < rightUpLOD)
                {
                    if (CameraFrustrum.Intersects(qNode.rightUpNode.boundBox))
                    {
                        qNode.status = 2;
                        RecursiveChildStatus(qNode.rightUpNode, cameraPoint, LODLevel, CameraFrustrum);
                    }
                    else
                    {
                        qNode.rightUpNode.inView = false;
                        qNode.status = 2;
                    }
                }
                if (qNode.distanceFromCamera < rightDownLOD)
                {
                    if (CameraFrustrum.Intersects(qNode.rightDownNode.boundBox))
                    {
                        qNode.status = 2;
                        RecursiveChildStatus(qNode.rightDownNode, cameraPoint, LODLevel, CameraFrustrum);
                    }
                    else
                    {
                        qNode.rightDownNode.inView = false;
                        qNode.status = 2;
                    }
                }
            }
        }
예제 #45
0
파일: Race.cs 프로젝트: STPKITT/OpenNFS1
        public void Render(bool renderPlayerVehicle)
        {
            Engine.Instance.Device.BlendState = BlendState.Opaque;
            Engine.Instance.Device.DepthStencilState = DepthStencilState.Default;
            Engine.Instance.Device.SamplerStates[0] = GameConfig.WrapSampler;

            Track.Render(Engine.Instance.Camera.Position, Player.Vehicle.CurrentNode);

            var frustum = new BoundingFrustum(Engine.Instance.Camera.View * Engine.Instance.Camera.Projection);

            foreach (var driver in Drivers)
            {
                bool isPlayer = driver == Player;
                if (isPlayer && !renderPlayerVehicle)
                    continue;

                if (!frustum.Intersects(driver.Vehicle.BoundingSphere))
                    continue;
                if (driver.Vehicle is DrivableVehicle)
                {
                    ((DrivableVehicle)driver.Vehicle).RenderShadow(isPlayer);
                }
                if (driver is AIDriver && ((AIDriver)driver).AtEndOfTrack)
                    continue;

                driver.Vehicle.Render();
            }
        }
예제 #46
0
파일: Game1.cs 프로젝트: JamesPersaud/GOOS
        protected override void Draw(GameTime gameTime)
        {
            numquads = 0;
            fpsCam.Setjump(currentjump + 10.0f);

            //GraphicsDevice.SamplerStates[0].MagFilter = TextureFilter.

            graphics.GraphicsDevice.Clear(new Color(new Vector3(0.002f,0.002f,0.002f)));

            // enable the depth buffer since geometry will be drawn
            graphics.GraphicsDevice.RenderState.DepthBufferEnable = true;
            graphics.GraphicsDevice.RenderState.DepthBufferWriteEnable = true;
            // Depth bias, useful for making small near things look like large far away things!
            graphics.GraphicsDevice.RenderState.CullMode = CullMode.CullCounterClockwiseFace;

            // always set the shared effects parameters
            viewParameter.SetValue(fpsCam.ViewMatrix);
            cameraPositionParameter.SetValue(fpsCam.Position);

            //Further optimisation needed - each quad should know which square it's in and the player's field of view should be taken into account

            BoundingSphere sphere = new BoundingSphere();
            BoundingFrustum frustum = new BoundingFrustum(fpsCam.ViewMatrix * fpsCam.ProjectionMatrix);
            Matrix ww;

            //Render actors
            materials[0].SpinMyBones = true;
            materials[0].Scaled = true;
            materials[0].SpecularIntensity /= 8;
            materials[0].SpecularPower /= 8;
            if(Vector3.Distance(actor[0].CurrentLocation,fpsCam.Position) < 160)
                materials[0].DrawComplexModelWithMaterial(tinymodel, ref actor[0].WorldMatrix,string.Empty);
            graphics.GraphicsDevice.RenderState.CullMode = CullMode.CullClockwiseFace;
            materials[1].Scaled = true;
            if (Vector3.Distance(actor[1].CurrentLocation, fpsCam.Position) < 160)
                materials[5].DrawComplexModelWithMaterial(testmodel, ref actor[1].WorldMatrix,string.Empty);
            graphics.GraphicsDevice.RenderState.CullMode = CullMode.CullCounterClockwiseFace;
            //if (Vector3.Distance(actor[2].CurrentLocation, fpsCam.Position) < 160)
                materials[5].DrawComplexModelWithMaterial(testmodel, ref actor[2].WorldMatrix, string.Empty);

            foreach (Quad q in Stage.Map.Floors)
            {
                if (q.Origin.X*2 < fpsCam.Position.X + 160 && q.Origin.X*2 > fpsCam.Position.X - 160
                    && q.Origin.Z*2 < fpsCam.Position.Z + 160 && q.Origin.Z*2 > fpsCam.Position.Z -160)
                {
                    sphere = new BoundingSphere(new Vector3(q.Origin.X * 2, q.Origin.Y, q.Origin.Z * 2), 16.0f);

                    if (frustum.Intersects(sphere))
                    {
                        ww = Matrix.Identity * Matrix.CreateTranslation(q.Origin);
                        materials[7].DrawQuadWithMaterial(q, ref ww);
                        numquads++;
                    }
                }
            }
            foreach (Quad q in Stage.Map.Ceilings)
            {
                if (q.Origin.X * 2 < fpsCam.Position.X + 160 && q.Origin.X * 2 > fpsCam.Position.X - 160
                    && q.Origin.Z * 2 < fpsCam.Position.Z + 160 && q.Origin.Z * 2 > fpsCam.Position.Z - 160)
                {
                    sphere = new BoundingSphere(new Vector3(q.Origin.X * 2, q.Origin.Y, q.Origin.Z * 2), 16.0f);

                    if (frustum.Intersects(sphere))
                    {
                        ww = Matrix.Identity * Matrix.CreateTranslation(q.Origin);
                        materials[7].DrawQuadWithMaterial(q, ref ww);
                        numquads++;
                    }
                }
            }
            foreach (Quad q in Stage.Map.Walls)
            {
                if (q.Origin.X * 2 < fpsCam.Position.X + 160 && q.Origin.X * 2 > fpsCam.Position.X - 160
                    && q.Origin.Z * 2 < fpsCam.Position.Z + 160 && q.Origin.Z * 2 > fpsCam.Position.Z - 160)
                {

                    sphere = new BoundingSphere(new Vector3(q.Origin.X * 2, q.Origin.Y, q.Origin.Z * 2), 16.0f);

                    if (frustum.Intersects(sphere))
                    {
                        ww = Matrix.Identity * Matrix.CreateTranslation(q.Origin);
                        materials[7].DrawQuadWithMaterial(q, ref ww);
                        numquads++;
                    }
                }
            }

            //baseEffect.Parameters["ambientLightColor"].SetValue(
            //   new Vector4(.185f, .185f, .185f, 1.0f));
            //lights[0].Range = 500f;
            //lights[0].Falloff = 0f;
              //  materials[6].DrawModelWithMaterial(barrel, ref meshWorlds[1]);

            spriteBatch.Begin(SpriteBlendMode.AlphaBlend);
            spriteBatch.Draw(logo, new Vector2(10, 10), Color.White);

            spriteBatch.Draw(crosshair,
                new Vector2((float)graphics.PreferredBackBufferWidth/2 - (float)crosshair.Width/2,(float)graphics.PreferredBackBufferHeight/2 - (float)crosshair.Height/2),
                new Color(250,250,250,75));

            spriteBatch.DrawString(font, "GRID X: " + fpsCam.LastGridSquareX.ToString() + " y: " + fpsCam.LastGridSquareY.ToString(), new Vector2(10, 200), Color.WhiteSmoke);
            spriteBatch.DrawString(font, "FACING: " + fpsCam.GetFacingdegrees().ToString(), new Vector2(10, 220), Color.WhiteSmoke);
            spriteBatch.DrawString(font, "CAM  X: " + fpsCam.Position.X.ToString() + " Z: " + fpsCam.Position.Z.ToString(), new Vector2(10, 240), Color.WhiteSmoke);

            if (fps > 60)
            {
                spriteBatch.DrawString(font, "FPS   : >60", new Vector2(10, 280), Color.Green);
            }
            else if (fps <= 60 && fps > 45)
            {
                spriteBatch.DrawString(font, "FPS   : " + fps.ToString(), new Vector2(10, 280), Color.Yellow);
            }
            else if (fps <= 45)
            {
                spriteBatch.DrawString(font, "FPS   : " + fps.ToString(), new Vector2(10, 280), Color.Red);
            }

            spriteBatch.DrawString(font, "Wall Verts : " + (numquads*4).ToString(), new Vector2(10, 300), Color.WhiteSmoke);

            //Actor debugs

            // 0 = order move; 1 = aggressive; 2 = patrol move

            //  0 Location
            //  0 Target
            //  0 Behav
            //  0 State
            //  0 Qcount
            //
            //  1 Location
            //  1 Target
            //  1 Behav
            //  1 State
            //
            //  2 Location
            //  2 Target
            //  2 Behav
            //  2 State
            //  2 Patrol pos
            //

            //Start at 340

            if (float.IsNaN(actor[1].CurrentLocation.X))
            {
                throw new Exception("NAN!");
            }

            //0
            spriteBatch.DrawString(font, "actor[0] Loc.   : " + actor[0].CurrentLocation.X.ToString() + ", " + actor[0].CurrentLocation.Y.ToString() + ", " + actor[0].CurrentLocation.Z.ToString(), new Vector2(10, 340), Color.WhiteSmoke);
            spriteBatch.DrawString(font, "actor[0] Target : " + actor[0].CurrentTarget.X.ToString() + ", " + actor[1].CurrentTarget.Y.ToString(), new Vector2(10, 360), Color.WhiteSmoke);
            spriteBatch.DrawString(font, "actor[0] Behav. : " + actor[0].Behaviours.ToString(), new Vector2(10, 380), Color.WhiteSmoke);
            spriteBatch.DrawString(font, "actor[0] State  : " + actor[0].Actions.ToString(), new Vector2(10, 400), Color.WhiteSmoke);
            if (actor[0].SimpleMoveQueue != null)
                spriteBatch.DrawString(font, "actor[0] Queue  : " + actor[0].SimpleMoveQueue.Count.ToString(), new Vector2(10, 420), Color.WhiteSmoke);
            else
                spriteBatch.DrawString(font, "actor[0] Queue  : NULL", new Vector2(10, 420), Color.WhiteSmoke);
            //1
            spriteBatch.DrawString(font, "actor[1] Loc.   : " + actor[1].CurrentLocation.X.ToString() + ", " + actor[1].CurrentLocation.Y.ToString() + ", " + actor[1].CurrentLocation.Z.ToString(), new Vector2(10, 460), Color.WhiteSmoke);
            spriteBatch.DrawString(font, "actor[1] Target : " + actor[1].CurrentTarget.X.ToString() + ", " + actor[1].CurrentTarget.Y.ToString() + "GRID: " + actor[1].target_gridX.ToString() + "," + actor[1].target_gridY.ToString(), new Vector2(10, 480), Color.WhiteSmoke);
            spriteBatch.DrawString(font, "actor[1] Behav. : " + actor[1].Behaviours.ToString(), new Vector2(10, 500), Color.WhiteSmoke);
            spriteBatch.DrawString(font, "actor[1] State  : " + actor[1].Actions.ToString(), new Vector2(10, 520), Color.WhiteSmoke);
            //2
            spriteBatch.DrawString(font, "actor[2] Loc.   : " + actor[2].CurrentLocation.X.ToString() + ", " + actor[2].CurrentLocation.Y.ToString() + ", " + actor[2].CurrentLocation.Z.ToString(), new Vector2(10, 560), Color.WhiteSmoke);
            spriteBatch.DrawString(font, "actor[2] Target : " + actor[2].CurrentTarget.X.ToString() + ", " + actor[2].CurrentTarget.Y.ToString(), new Vector2(10, 580), Color.WhiteSmoke);
            spriteBatch.DrawString(font, "actor[2] Behav. : " + actor[2].Behaviours.ToString(), new Vector2(10, 600), Color.WhiteSmoke);
            spriteBatch.DrawString(font, "actor[2] State  : " + actor[2].Actions.ToString(), new Vector2(10, 620), Color.WhiteSmoke);
            spriteBatch.DrawString(font, "actor[2] Patrol: " + actor[2].CurrentPatrolIndex.ToString(), new Vector2(10, 640), Color.WhiteSmoke);

            string pa = string.Empty;
            foreach(string s in PickedActors)
            {
                pa += s + " ";
            }

            spriteBatch.DrawString(font, "Picked Actors   : " + pa.ToString() , new Vector2(10, 680), Color.WhiteSmoke);
            spriteBatch.DrawString(font, "Walldist        : " + NearestWall.ToString(), new Vector2(10, 720), Color.WhiteSmoke);

            spriteBatch.End();

            base.Draw(gameTime);
        }
예제 #47
0
        void Execute(BoundingFrustum frustum, ref BoundingSphere frustumSphere, Action<Octree> action, Octree octree)
        {
            bool intersected;

            // 視錐台球 vs 八分木球
            frustumSphere.Intersects(ref octree.Sphere, out intersected);
            if (!intersected) return;

            // 視錐台 vs 八分木球
            frustum.Intersects(ref octree.Sphere, out intersected);
            if (!intersected) return;

            // 視錐台 vs 八分木ボックス
            frustum.Intersects(ref octree.Box, out intersected);
            if (!intersected) return;

            action(octree);

            for (int z = 0; z < 2; z++)
            {
                for (int y = 0; y < 2; y++)
                {
                    for (int x = 0; x < 2; x++)
                    {
                        var child = octree[x, y, z];
                        if (child != null)
                        {
                            Execute(frustum, ref frustumSphere, action, child);
                        }
                    }
                }
            }
        }
예제 #48
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="gameTime"></param>
        /// <param name="view"></param>
        /// <param name="projection"></param>
        /// <param name="environment">If this renderpass is render to our dynamic environmentmap</param>
        private void RenderScene(GameTime gameTime, Matrix view, Matrix projection, bool environment)
        {
            BoundingFrustum viewFrustum = new BoundingFrustum(Game.GetService<CameraComponent>().CurrentCamera.View * projection);

            // TODO: CARMOVE
            //Matrix[] transforms = new Matrix[Car.Model.Bones.Count];
            //Car.Model.CopyAbsoluteBoneTransformsTo(transforms);

            GraphicsDevice.BlendState = BlendState.Opaque;

            #region SkyBox

            skyBoxEffect.Parameters["View"].SetValue(view);
            skyBoxEffect.Parameters["Projection"].SetValue(projection);

            skyBoxModel.Meshes[0].Draw();

            #endregion

            for (int z = 0; z < terrainSegmentsCount; z++)
                for (int x = 0; x < terrainSegmentsCount; x++)
                {
                    var terrain = terrainSegments[x, z];
                    if (viewFrustum.Intersects(terrain.BoundingBox))
                    {
                        if (environment)
                        {
                            Vector3 boxStart = Car.Position;
                            boxStart.Y = -5000;
                            Vector3 boxEnd = boxStart;
                            boxEnd.Y = 5000;
                            boxEnd.X += 50;
                            boxEnd.Z += 50;
                            if (terrain.BoundingBox.Intersects(new BoundingBox(boxStart, boxEnd)))
                                continue;
                        }

                        terrain.Draw(view, projection, gameInstance.GetService<CameraComponent>().Position,
                            directionalLight);
                    }
                }

            //if (Keyboard.GetState().IsKeyUp(Keys.N))
            //    navMesh.Draw(view, projection);

            GraphicsDevice.BlendState = BlendState.AlphaBlend;
            GraphicsDevice.DepthStencilState = DepthStencilState.Default;
            GraphicsDevice.RasterizerState = RasterizerState.CullCounterClockwise;
            GraphicsDevice.SamplerStates[0] = SamplerState.PointClamp;

            // Set view to particlesystems
            foreach (ParticleSystem pSystem in particleSystems)
            {
                pSystem.SetCamera(view, projection);
            }

            #region RenderObjects

            foreach (GameObject obj in GraphicalObjects)
            {
                obj.Draw(view, projection);
            }

            #endregion

            if (!environment)
            {
                foreach (Car car in gameInstance.GetService<CarControlComponent>().Cars.Values)
                    DrawCar(view, projection, car);
                DrawGhostCar(view, projection, gameTime);
            }
        }
예제 #49
0
        /// <summary>
        /// Draw a GameObject with respect to the view frustum.
        /// </summary>
        /// <param name="obj">The GameObject to draw.</param>
        /// <param name="viewFrustum">The view frustum.</param>
        private void drawObject(Objects.GameObject obj, BoundingFrustum viewFrustum)
        {
            Dictionary<String, Objects.Sprite>.ValueCollection.Enumerator spriteEnumerator = obj.sprites.Values.GetEnumerator();

            // Iterate over all this object's sprites.
            while (spriteEnumerator.MoveNext())
            {
                // Check if this sprite is visible.
                if (spriteEnumerator.Current.visible)
                {
                    Vector3 objectPosition = new Vector3(obj.position + spriteEnumerator.Current.position, -obj.layer - spriteEnumerator.Current.layerOffset);
                    Vector3 objectScale = new Vector3(Vector2.Multiply(spriteEnumerator.Current.image.size, obj.scale), 1);

                    BoundingSphere sphere =  new BoundingSphere(objectPosition, objectScale.Length() );

                    // Only draw the object if we can actually see it.
                    if (viewFrustum.Intersects(sphere))
                    {
                        int xBlock = (int)(spriteEnumerator.Current.frame % spriteEnumerator.Current.image.blocks.X);
                        int yBlock = (int)((spriteEnumerator.Current.frame - xBlock) / spriteEnumerator.Current.image.blocks.X);

                        Matrix translationMatrix = Matrix.CreateScale(objectScale) * Matrix.CreateRotationZ(obj.rotation + spriteEnumerator.Current.rotation) *
                            Matrix.CreateTranslation(objectPosition);
                        VertexPositionColorTexture[] objVertices = new VertexPositionColorTexture[vertices.Length];
                        int xFlip = 0;
                        if (spriteEnumerator.Current.horizontalFlip && !obj.horizontalFlip || obj.horizontalFlip && !spriteEnumerator.Current.horizontalFlip)
                        {
                            xFlip = 1;
                        }
                        int yFlip = 0;
                        for (int index = 0; index < vertices.Length; index++)
                        {
                            objVertices[index].Position.X = translationMatrix.M11 * vertices[index].Position.X
                                                            + translationMatrix.M21 * vertices[index].Position.Y
                                                            + translationMatrix.M41;
                            objVertices[index].Position.Y = translationMatrix.M12 * vertices[index].Position.X
                                                            + translationMatrix.M22 * vertices[index].Position.Y
                                                            + translationMatrix.M42;
                            objVertices[index].Position.Z = objectPosition.Z;

                            int xMod = 1 - ( index + xFlip ) % 2;
                            int yMod = 0;
                            if (index == 0 || index == 1)
                            {
                                yMod = 1 + yFlip;
                            }
                            objVertices[index].TextureCoordinate.X = (xBlock + xMod) / spriteEnumerator.Current.image.blocks.X;
                            objVertices[index].TextureCoordinate.Y = (yBlock + yMod) / spriteEnumerator.Current.image.blocks.Y;
                        }

                        // TODO: this probably isn't how we want to do this if we end up using more than one effect
                        Effect effect = getOrCreateEffect(spriteEnumerator.Current);
                        effect.CurrentTechnique = effect.Techniques["Textured"];
                        effect.Parameters["xView"].SetValue(cameraView);
                        effect.Parameters["xProjection"].SetValue(cameraProjection);
                        effect.Parameters["xWorld"].SetValue(Matrix.Identity);
                        effect.Parameters["xTexture"].SetValue(getOrCreateTexture(spriteEnumerator.Current));

                        effect.Begin();
                        IEnumerator<EffectPass> effectPassEnumerator = effect.CurrentTechnique.Passes.GetEnumerator();
                        while (effectPassEnumerator.MoveNext())
                        {
                            effectPassEnumerator.Current.Begin();
                            // The vertex declaration needs to be set before it gets here, or this will fail
                            SnailsPace.getInstance().GraphicsDevice.DrawUserPrimitives<VertexPositionColorTexture>(PrimitiveType.TriangleStrip, objVertices, 0, 2);
                            effectPassEnumerator.Current.End();
                        }
                        effectPassEnumerator.Dispose();
                        effect.End();
                    }
                    else
                    {
            #if DEBUG
                        if (SnailsPace.debugCulling)
                        {
                            SnailsPace.debug("Object culled.");
                        }
            #endif
                    }
                }
            }
            spriteEnumerator.Dispose();
        }
예제 #50
0
 bool InView(BoundingBox boundingSphere)
 {
     bf = new BoundingFrustum(cubeEffect.View * cubeEffect.Projection);
     return bf.Intersects(boundingSphere);
 }
예제 #51
0
        public virtual void Draw()
        {
            if (this.Exists && !this.IsInInventory)
            {
                BoundingFrustum viewFrustum = new BoundingFrustum(Camera.ActiveCamera.View * Camera.ActiveCamera.Projection);
                BoundingSphere sourceSphere = new BoundingSphere(Position, model.Meshes[0].BoundingSphere.Radius);

                if (viewFrustum.Intersects(sourceSphere))
                {
                    if (transforms == null)
                    {
                        transforms = new Matrix[model.Bones.Count];
                        model.CopyAbsoluteBoneTransformsTo(transforms);
                    }

                    foreach (ModelMesh mesh in model.Meshes)
                    {
                        foreach (BasicEffect effect in mesh.Effects)
                        {
                            if (texture != null)
                            {
                                effect.Texture = texture;
                            }

                            effect.EnableDefaultLighting();
                            effect.World = transforms[mesh.ParentBone.Index] *
                                           Matrix.CreateScale(Scale) *
                                           Matrix.CreateRotationX(RotationX) *
                                           Matrix.CreateRotationY(RotationY) *
                                           Matrix.CreateTranslation(Position);
                            effect.View = Camera.ActiveCamera.View;
                            effect.Projection = Camera.ActiveCamera.Projection;
                        }

                        mesh.Draw();
                    }
                }
            }
        }
예제 #52
0
 /// <summary>
 /// Gets the triangles whose bounding boxes are overlapped by the query.
 /// </summary>
 /// <param name="boundingFrustum">Shape to query against the tree.</param>
 /// <param name="outputOverlappedElements">Indices of triangles in the index buffer with bounding boxes which are overlapped by the query.</param>
 /// <returns>Whether or not any elements were overlapped.</returns>
 public bool GetOverlaps(BoundingFrustum boundingFrustum, IList<int> outputOverlappedElements)
 {
     if (root != null)
     {
         bool intersects;
         boundingFrustum.Intersects(ref root.BoundingBox, out intersects);
         if (intersects)
             root.GetOverlaps(ref boundingFrustum, outputOverlappedElements);
     }
     return outputOverlappedElements.Count > 0;
 }
        private void DrawGameplayScreen()
        {
            BoundingFrustum view_frustum = new BoundingFrustum(gameCamera.view_matrix * gameCamera.projection_matrix);
            //device.Clear(ClearOptions.Target | ClearOptions.DepthBuffer, Color.DarkSlateBlue, 1.0f, 0);
            skyboxModel.CopyAbsoluteBoneTransformsTo(skyboxTransforms);
            foreach (ModelMesh mesh in skyboxModel.Meshes)
            {
                foreach (BasicEffect effect in mesh.Effects)
                {
                    effect.World = skyboxTransforms[mesh.ParentBone.Index] * Matrix.CreateScale(20.0f);
                    effect.View = gameCamera.view_matrix;
                    effect.Projection = gameCamera.projection_matrix;
                }
                mesh.Draw();
            }

            DrawTerrain(ground.model, grassTexture);
            DrawWalls(brick_wall.model, brickTexture);
            foreach (Zombie zombie in zombies)
            {
                BoundingSphere object_sphere = new BoundingSphere(zombie.position, 5.0f);
                if (!zombie.Killed && view_frustum.Intersects(object_sphere))
                {
                    zombie.Draw(gameCamera.view_matrix,
                        gameCamera.projection_matrix);
                }
            }
            foreach (Tree tree in trees)
            {
                BoundingSphere object_sphere = new BoundingSphere(tree.position, 8.0f);
                if (view_frustum.Intersects(object_sphere))
                tree.Draw(gameCamera.view_matrix, gameCamera.projection_matrix);
            }
            DepthStencilState dss = new DepthStencilState();
            DepthStencilState dss2 = new DepthStencilState();
            dss.DepthBufferEnable = false;
            dss2.DepthBufferEnable = true;
            GraphicsDevice.DepthStencilState = dss;
            guns.Draw(player.position, player.forward_direction, gameCamera.view_matrix, gameCamera.projection_matrix);
            GraphicsDevice.DepthStencilState = dss2;

            /*foreach (Ray ray in rayList)
            {
               RayRenderer.Render(ray,100.0f, GraphicsDevice, gameCamera.view_matrix,gameCamera.projection_matrix, Color.Red);
            }
            */
            //player.Draw(gameCamera.view_matrix, gameCamera.projection_matrix);
            DrawStats();
        }
예제 #54
0
 internal override void GetOverlaps(ref BoundingFrustum boundingFrustum, IList<int> outputOverlappedElements)
 {
     bool intersects;
     boundingFrustum.Intersects(ref ChildA.BoundingBox, out intersects);
     if (intersects)
         ChildA.GetOverlaps(ref boundingFrustum, outputOverlappedElements);
     boundingFrustum.Intersects(ref ChildB.BoundingBox, out intersects);
     if (intersects)
         ChildB.GetOverlaps(ref boundingFrustum, outputOverlappedElements);
 }
예제 #55
0
        private void DrawScene(ref Matrix view)
        {
            m_Device.SamplerStates[0] = SamplerState.LinearWrap;
            BoundingFrustum viewFrustrum = new BoundingFrustum(view * m_Projection);

            foreach (var handle in m_Models)
            {
                Model model = handle.Get();

                Matrix[] transforms = new Matrix[model.Bones.Count];
                model.CopyAbsoluteBoneTransformsTo(transforms);

                foreach (ModelMesh mesh in model.Meshes)
                {
                    Matrix world = transforms[mesh.ParentBone.Index] * handle.Owner.Transform.GetWorld();
                    BoundingSphere sphere;
                    mesh.BoundingSphere.Transform(ref world, out sphere);
                    if (!viewFrustrum.Intersects(sphere))
                        continue;

                    MainEffect.GetResource().Parameters["World"].SetValue(world);

                    foreach (ModelMeshPart part in mesh.MeshParts)
                    {
                        MainEffect.GetResource().Parameters["SurfaceTexture"].SetValue((part.Effect as BasicEffect).Texture);

                        m_Device.SetVertexBuffer(part.VertexBuffer, part.VertexOffset);
                        m_Device.Indices = part.IndexBuffer;

                        foreach (EffectPass pass in MainEffect.GetResource().CurrentTechnique.Passes)
                        {
                            pass.Apply();
                            m_Device.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, part.NumVertices, part.StartIndex, part.PrimitiveCount);
                        }
                    }
                }
            }

            //SamplerState previousState = m_Device.SamplerStates[0];

            foreach (var handle in m_Meshes)
            {
                var mesh = handle.GetAbstract<IVertexResource>();
                Entity owner = handle.Owner;

                DrawVertexBuffer(mesh, owner);
            }

            //m_Device.SamplerStates[0] = previousState;
        }
예제 #56
0
        private void RenderLight(Camera camera, BoundingFrustum cameraFrustum, ref Matrix4 view, ref Matrix4 projection, Stage stage, ref Matrix4 modelViewProjection, Light light)
        {
            // Pad the radius of the rendered sphere a little, it's quite low poly so there will be minor artifacts otherwise
            var radius = light.Range * 1.1f;

            // Culling
            if (light.Type == LighType.PointLight)
            {
                BoundingSphere.Center = light.Position;
                BoundingSphere.Radius = radius;

                if (!cameraFrustum.Intersects(BoundingSphere))
                    return;
            }

            RenderedLights++;

            var renderStateId = DirectionalRenderState;

            var cameraDistanceToLight = light.Position - camera.Position;

            var castShadows = light.CastShadows && Settings.EnableShadows;

            if (light.Type == LighType.PointLight || light.Type == LighType.SpotLight)
            {
                if (Vector3.DistanceSquared(light.Position, camera.Position) > Settings.ShadowRenderDistance * Settings.ShadowRenderDistance)
                {
                    castShadows = false;
                }
            }

            if (light.Type == LighType.PointLight)
            {
                renderStateId = LightOutsideRenderState;
                // We pad it once again to avoid any artifacted when the camera is close to the edge of the bounding sphere
                if (cameraDistanceToLight.Length <= radius * 1.1f)
                {
                    renderStateId = LightInsideRenderState;
                }
            }
            else if (light.Type == LighType.SpotLight)
            {
                renderStateId = LightOutsideRenderState;
                if (IsInsideSpotLight(light, camera))
                {
                    renderStateId = LightInsideRenderState;
                }
            }

            // Initialize shadow map
            Matrix4 shadowViewProjection;
            Vector2 shadowCameraClipPlane;

            Matrix4[] shadowViewProjections = null;
            Vector4 clipDistances = Vector4.Zero;

            if (castShadows)
            {
                if (light.Type == LighType.PointLight)
                {
                    RenderShadowsCube(PointShadowsRenderTarget, light, stage, camera, out shadowViewProjection, out shadowCameraClipPlane);
                }
                else if (light.Type == LighType.SpotLight)
                {
                    RenderShadows(SpotShadowsRenderTarget, light, stage, camera, 0, out shadowViewProjection, out shadowCameraClipPlane);
                }
                else
                {
                    // Just to get rid of the unassigend error
                    shadowViewProjection = Matrix4.Identity;
                    shadowCameraClipPlane = Vector2.Zero;

                    // Do the csm
                    shadowViewProjections = new Matrix4[3];

                    float cameraNear = camera.NearClipDistance;
                    float cameraFar = camera.FarClipDistance;
                    float dist = cameraFar - cameraNear;

                    clipDistances.X = cameraNear;
                    clipDistances.Y = cameraFar * 0.1f;
                    clipDistances.Z = cameraFar * 0.4f;
                    clipDistances.W = cameraFar;

                    // Cascade 1
                    camera.NearClipDistance = clipDistances.X;
                    camera.FarClipDistance = clipDistances.Y;
                    RenderShadows(DirectionalShadowsRenderTarget[0], light, stage, camera, 0, out shadowViewProjections[0], out shadowCameraClipPlane);

                    // Cascade 2
                    camera.NearClipDistance = clipDistances.X;
                    camera.FarClipDistance = clipDistances.Z;
                    RenderShadows(DirectionalShadowsRenderTarget[1], light, stage, camera, 1, out shadowViewProjections[1], out shadowCameraClipPlane);

                    // Cascade 3
                    camera.NearClipDistance = clipDistances.X;
                    camera.FarClipDistance = clipDistances.W;
                    RenderShadows(DirectionalShadowsRenderTarget[2], light, stage, camera, 2, out shadowViewProjections[2], out shadowCameraClipPlane);

                    // Restore clip plane
                    camera.NearClipDistance = cameraNear;
                    camera.FarClipDistance = cameraFar;
                }
                Backend.ChangeRenderTarget(LightAccumulation);
            }
            else
            {
                shadowViewProjection = Matrix4.Identity;
                shadowCameraClipPlane = Vector2.Zero;
            }

            // Calculate matrices
            var scaleMatrix = Matrix4.Scale(radius);

            if (light.Type == LighType.SpotLight)
            {
                var height = light.Range;
                var spotRadius = (float)System.Math.Tan(light.OuterAngle / 2.0f) * height;
                scaleMatrix = Matrix4.Scale(spotRadius, height, spotRadius);
            }

            Matrix4 world;

            if (light.Type == LighType.SpotLight)
            {
                world = (scaleMatrix * Matrix4.Rotate(Vector3.GetRotationTo(Vector3.UnitY, light.Direction))) * Matrix4.CreateTranslation(light.Position);
            }
            else
            {
                world = scaleMatrix * Matrix4.CreateTranslation(light.Position);
            }
            modelViewProjection = world * view * projection;

            // Convert light color to linear space
            var lightColor = light.Color * light.Intensity;
            lightColor = new Vector3((float)System.Math.Pow(lightColor.X, 2.2f), (float)System.Math.Pow(lightColor.Y, 2.2f), (float)System.Math.Pow(lightColor.Z, 2.2f));

            // Select the correct shader
            var lightTypeOffset = 0;

            if (light.Type == LighType.PointLight)
                lightTypeOffset = PointLightShaderOffset;
            else if (light.Type == LighType.SpotLight)
                lightTypeOffset = SpotLightShaderOffset;

            if (castShadows)
                lightTypeOffset += 1 + (int)Settings.ShadowQuality;

            var shader = LightShaders[lightTypeOffset];
            var shaderParams = LightParams[lightTypeOffset];

            // Setup textures and begin rendering with the chosen shader
            int[] textures;
            int[] samplers;
            if (castShadows)
            {
                if (light.Type == LighType.Directional)
                {
                    textures = new int[] { GBuffer.Textures[0].Handle, GBuffer.Textures[1].Handle, GBuffer.Textures[2].Handle, GBuffer.Textures[3].Handle, DirectionalShadowsRenderTarget[0].Textures[0].Handle, DirectionalShadowsRenderTarget[1].Textures[0].Handle, DirectionalShadowsRenderTarget[2].Textures[0].Handle };
                    samplers = new int[] { Backend.DefaultSamplerNoFiltering, Backend.DefaultSamplerNoFiltering, Backend.DefaultSamplerNoFiltering, Backend.DefaultSamplerNoFiltering, ShadowSampler, ShadowSampler, ShadowSampler };
                }
                else
                {
                    var shadowMapHandle = light.Type == LighType.PointLight ?
                    PointShadowsRenderTarget.Textures[0].Handle : SpotShadowsRenderTarget.Textures[0].Handle;

                    textures = new int[] { GBuffer.Textures[0].Handle, GBuffer.Textures[1].Handle, GBuffer.Textures[2].Handle, GBuffer.Textures[3].Handle, shadowMapHandle };
                    samplers = new int[] { Backend.DefaultSamplerNoFiltering, Backend.DefaultSamplerNoFiltering, Backend.DefaultSamplerNoFiltering, Backend.DefaultSamplerNoFiltering, ShadowSampler };
                }
            }
            else
            {
                textures = new int[] { GBuffer.Textures[0].Handle, GBuffer.Textures[1].Handle, GBuffer.Textures[2].Handle, GBuffer.Textures[3].Handle };
                samplers = new int[] { Backend.DefaultSamplerNoFiltering, Backend.DefaultSamplerNoFiltering, Backend.DefaultSamplerNoFiltering, Backend.DefaultSamplerNoFiltering };
            }

            Backend.BeginInstance(shader.Handle, textures, samplers, renderStateId);

            // Setup texture samplers
            Backend.BindShaderVariable(shaderParams.SamplerGBuffer0, 0);
            Backend.BindShaderVariable(shaderParams.SamplerGBuffer1, 1);
            Backend.BindShaderVariable(shaderParams.SamplerGBuffer2, 2);
            Backend.BindShaderVariable(shaderParams.samplerDepth, 3);

            // Common uniforms
            Backend.BindShaderVariable(shaderParams.ScreenSize, ref ScreenSize);
            Backend.BindShaderVariable(shaderParams.ModelViewProjection, ref modelViewProjection);
            Backend.BindShaderVariable(shaderParams.LightColor, ref lightColor);
            Backend.BindShaderVariable(shaderParams.CameraPosition, ref camera.Position);

            if (light.Type == LighType.Directional || light.Type == LighType.SpotLight)
            {
                var lightDirWS = light.Direction.Normalize();

                Backend.BindShaderVariable(shaderParams.LightDirection, ref lightDirWS);
            }

            if (light.Type == LighType.PointLight || light.Type == LighType.SpotLight)
            {
                Backend.BindShaderVariable(shaderParams.LightPosition, ref light.Position);
                Backend.BindShaderVariable(shaderParams.LightRange, light.Range);
                Backend.BindShaderVariable(shaderParams.LightInvSquareRadius, 1.0f / (light.Range * light.Range));
            }

            if (light.Type == LighType.SpotLight)
            {
                var spotParams = new Vector2((float)System.Math.Cos(light.InnerAngle / 2.0f), (float)System.Math.Cos(light.OuterAngle / 2.0f));
                Backend.BindShaderVariable(shaderParams.SpotParams, ref spotParams);
            }

            var inverseViewProjectionMatrix = Matrix4.Invert(view * projection);
            Backend.BindShaderVariable(shaderParams.InvViewProjection, ref inverseViewProjectionMatrix);

            if (castShadows)
            {
                Backend.BindShaderVariable(shaderParams.ClipPlane, ref shadowCameraClipPlane);
                Backend.BindShaderVariable(shaderParams.ShadowBias, light.ShadowBias);

                var texelSize = 1.0f / (light.Type == LighType.Directional ? DirectionalShadowsRenderTarget[0].Width : SpotShadowsRenderTarget.Width);
                Backend.BindShaderVariable(shaderParams.TexelSize, texelSize);

                if (light.Type == LighType.PointLight)
                {
                    Backend.BindShaderVariable(shaderParams.SamplerShadowCube, 4);
                }
                else if (light.Type == LighType.Directional)
                {
                    Backend.BindShaderVariable(shaderParams.SamplerShadow1, 4);
                    Backend.BindShaderVariable(shaderParams.SamplerShadow2, 5);
                    Backend.BindShaderVariable(shaderParams.SamplerShadow3, 6);

                    Backend.BindShaderVariable(shaderParams.ShadowViewProj1, ref shadowViewProjections[0]);
                    Backend.BindShaderVariable(shaderParams.ShadowViewProj2, ref shadowViewProjections[1]);
                    Backend.BindShaderVariable(shaderParams.ShadowViewProj3, ref shadowViewProjections[2]);
                    Backend.BindShaderVariable(shaderParams.ClipDistances, ref clipDistances);
                }
                else
                {
                    Backend.BindShaderVariable(shaderParams.SamplerShadow, 4);
                    Backend.BindShaderVariable(shaderParams.ShadowViewProj, ref shadowViewProjection);
                }
            }

            if (light.Type == LighType.Directional)
            {
                Backend.DrawMesh(QuadMesh.MeshHandle);
            }
            else if (light.Type == LighType.PointLight)
            {
                Backend.DrawMesh(UnitSphere.SubMeshes[0].Handle);
            }
            else
            {
                Backend.DrawMesh(UnitCone.SubMeshes[0].Handle);
            }

            Backend.EndInstance();
        }
예제 #57
0
파일: Track.cs 프로젝트: STPKITT/OpenNFS1
        public void Render(Vector3 cameraPosition, TrackNode currentNode)
        {
            _skybox.Render();
            _effect.View = Engine.Instance.Camera.View;
            _effect.Projection = Engine.Instance.Camera.Projection;
            _effect.World = Matrix.Identity;

            int segmentIndex = currentNode.Number / 4;
            var startSegment = TerrainSegments[segmentIndex];

            var renderedSegments = new List<TerrainSegment>();

            Engine.Instance.Device.SetVertexBuffer(TerrainVertexBuffer);
            _effect.CurrentTechnique.Passes[0].Apply();
            Engine.Instance.Device.RasterizerState = RasterizerState.CullNone;
            Engine.Instance.Device.SamplerStates[0] = GameConfig.WrapSampler;

            var frustum = new BoundingFrustum(Engine.Instance.Camera.View * Engine.Instance.Camera.Projection);

            // draw segments from the player vehicle forwards. Stop when a segment is out of view
            var segment = startSegment;
            for (int i = 0; i < GameConfig.MaxSegmentRenderCount; i++)
            {
                if (segment == null) break;
                if (frustum.Intersects(segment.BoundingBox))
                {
                    RenderSegment(segment);
                    renderedSegments.Add(segment);
                }
                else
                {
                    break;
                }
                segment = segment.Next;
            }

            // draw segments from the player vehicle backwards. Stop when a segment is out of view
            segment = startSegment.Prev;
            for (int i = 0; i < GameConfig.MaxSegmentRenderCount; i++)
            {
                if (segment == null) break;
                if (frustum.Intersects(segment.BoundingBox))
                {
                    RenderSegment(segment);
                    renderedSegments.Add(segment);
                }
                segment = segment.Prev;
            }

            DrawScenery(renderedSegments);

            if (FenceVertexBuffer != null)
            {
                Engine.Instance.Device.SetVertexBuffer(FenceVertexBuffer);
                _effect.World = Matrix.Identity;
                _effect.CurrentTechnique.Passes[0].Apply();
                Engine.Instance.Device.SamplerStates[0] = GameConfig.WrapSampler;
                foreach (var renderedSegment in renderedSegments)
                {
                    DrawFenceStrips(renderedSegment);
                }
            }

            if (GameConfig.DrawDebugInfo)
            {
                var node = currentNode;
                for (int i = 0; i < GameConfig.MaxSegmentRenderCount; i++)
                {
                    Engine.Instance.GraphicsUtils.AddCube(Matrix.CreateTranslation(node.GetLeftBoundary()), Color.Red);
                    Engine.Instance.GraphicsUtils.AddCube(Matrix.CreateTranslation(node.GetRightBoundary()), Color.Red);
                    Engine.Instance.GraphicsUtils.AddCube(Matrix.CreateTranslation(node.GetLeftVerge()), Color.Blue);
                    Engine.Instance.GraphicsUtils.AddCube(Matrix.CreateTranslation(node.GetRightVerge()), Color.Blue);
                    Engine.Instance.GraphicsUtils.AddCube(Matrix.CreateTranslation(node.Position), Color.Yellow);

                    if (node.Number % TriFile.NbrRowsPerSegment == 0)
                    {
                        Engine.Instance.GraphicsUtils.AddLine(node.GetLeftBoundary(), node.GetRightBoundary(), Color.White);
                    }

                    node = node.Next;
                    if (node == null) break;
                }

                GameConsole.WriteLine(String.Format("Position node: {0}, segment: {1}", currentNode.Number, (int)(currentNode.Number / TriFile.NbrRowsPerSegment)));
                GameConsole.WriteLine(String.Format("Node property: {0}, flags: {1}, {2}, {3}", currentNode.NodeProperty, currentNode.Flag1, currentNode.Flag2, currentNode.Flag3));
            }
        }
        /// <summary>
        /// Get the total number of visible dwarves, and resize our instance arrays accordingly
        /// </summary>
        /// <param name="frustum"></param>
        private void RefreshMeshCounts(BoundingFrustum frustum)
        {
            // Reset the counts of each part to 0
            for (int i = 0; i < this.meshPartCount.Length; i++)
                this.meshPartCount[i] = 0;

            // Loop through, and see if they are visible
            // If the dwarf is visible, make sure we add to the body part counters
            for (int i = 0; i < this.numInstances; i++)
            {

                Dwarf dwarf = this.dwarves[i];
                bool intersects = true;
                frustum.Intersects(ref dwarf.boundingSphere, out intersects);
                if (intersects)
                {
                    this.meshPartCount[dwarf.HeadPart]++;
                    this.meshPartCount[dwarf.BodyPart]++;
                    this.meshPartCount[dwarf.LegPart]++;
                }
                dwarf.IsVisible = intersects;
            }

            // Resize all the arrays accordingly
            for (int i = 0; i < this.meshInstances.Count; i++)
            {
                Array.Resize(ref this.meshInstances[i].transforms, meshPartCount[i]);
                Array.Resize(ref this.meshInstances[i].animations, meshPartCount[i]);
            }
        }
예제 #59
0
파일: Game1.cs 프로젝트: JamesPersaud/GOOS
        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Draw(GameTime gameTime)
        {
            //Jumping
            if (!fpsCam.InDeathThroes)
                fpsCam.Setjump(currentjump + 10.0f);

            graphics.GraphicsDevice.Clear(new Color(new Vector3(0.002f, 0.002f, 0.002f)));

            // enable the depth buffer since geometry will be drawn
            graphics.GraphicsDevice.RenderState.DepthBufferEnable = true;
            graphics.GraphicsDevice.RenderState.DepthBufferWriteEnable = true;
            graphics.GraphicsDevice.RenderState.CullMode = CullMode.CullCounterClockwiseFace;

            // always set the shared effects parameters
            viewParameter.SetValue(fpsCam.ViewMatrix);
            cameraPositionParameter.SetValue(fpsCam.Position);

            //Further optimisation needed - each quad should know which square it's in and the player's field of view should be taken into account

            // MAIN DRAW
            //Particles
            smokePlumeParticles.SetCamera(fpsCam.ViewMatrix, fpsCam.ProjectionMatrix);
            fireParticles.SetCamera(fpsCam.ViewMatrix, fpsCam.ProjectionMatrix);
            antifireParticles.SetCamera(fpsCam.ViewMatrix, fpsCam.ProjectionMatrix);

            BoundingSphere sphere = new BoundingSphere();
            BoundingFrustum frustum = new BoundingFrustum(fpsCam.ViewMatrix * fpsCam.ProjectionMatrix);
            Matrix ww;

            //Only render the monster in play mode.
            if (!Stage.GameState.DemoMode)
                //Render The Stage
                Stage.Render(true, false, false, fpsCam, 160.0f);

            if (!Stage.GameState.DemoMode)
            {
                //Test render - a purple cube at the teleporter location.
                Matrix mw = Matrix.Identity * Matrix.CreateTranslation(TeleporterRenderLocation);
                BasicMaterial.DrawComplexModelWithMaterial(testmodel, ref mw, string.Empty);
            }
            else
            {
                Matrix mw = Matrix.Identity * Matrix.CreateTranslation(0,0,100);
                BasicMaterial.DrawComplexModelWithMaterial(testmodel, ref mw, string.Empty);
            }

            //Render walls
            foreach (Quad q in Stage.Map.Floors)
            {
                if (q.Origin.X * 2 < fpsCam.Position.X + (320 * OptionsViewDistance / 100) && q.Origin.X * 2 > fpsCam.Position.X - (320 * OptionsViewDistance / 100)
                    && q.Origin.Z * 2 < fpsCam.Position.Z + (320 * OptionsViewDistance / 100) && q.Origin.Z * 2 > fpsCam.Position.Z - (320 * OptionsViewDistance / 100))
                {
                    sphere = new BoundingSphere(new Vector3(q.Origin.X * 2, q.Origin.Y, q.Origin.Z * 2), 16.0f);

                    if (frustum.Intersects(sphere))
                    {
                        ww = Matrix.Identity * Matrix.CreateTranslation(q.Origin);
                        FloorMaterial.DrawQuadWithMaterial(q, ref ww);
                    }
                }
            }
            foreach (Quad q in Stage.Map.Ceilings)
            {
                if (q.Origin.X * 2 < fpsCam.Position.X + (320 * OptionsViewDistance / 100) && q.Origin.X * 2 > fpsCam.Position.X - (320 * OptionsViewDistance / 100)
                    && q.Origin.Z * 2 < fpsCam.Position.Z + (320 * OptionsViewDistance / 100) && q.Origin.Z * 2 > fpsCam.Position.Z - (320 * OptionsViewDistance / 100))
                {
                    sphere = new BoundingSphere(new Vector3(q.Origin.X * 2, q.Origin.Y, q.Origin.Z * 2), 16.0f);

                    if (frustum.Intersects(sphere))
                    {
                        ww = Matrix.Identity * Matrix.CreateTranslation(q.Origin);
                        CeilingMaterial.DrawQuadWithMaterial(q, ref ww);
                    }
                }
            }
            foreach (Quad q in Stage.Map.Walls)
            {
                if (q.Origin.X * 2 < fpsCam.Position.X + (320 * OptionsViewDistance / 100) && q.Origin.X * 2 > fpsCam.Position.X - (320 * OptionsViewDistance / 100)
                    && q.Origin.Z * 2 < fpsCam.Position.Z + (320 * OptionsViewDistance / 100) && q.Origin.Z * 2 > fpsCam.Position.Z - (320 * OptionsViewDistance / 100))
                {

                    sphere = new BoundingSphere(new Vector3(q.Origin.X * 2, q.Origin.Y, q.Origin.Z * 2), 16.0f);

                    if (frustum.Intersects(sphere))
                    {
                        ww = Matrix.Identity * Matrix.CreateTranslation(q.Origin);
                        WallMaterial.DrawQuadWithMaterial(q, ref ww);
                    }
                }
            }
            //draw smoke only when teleporter is near.
            if (Vector3.Distance(fpsCam.Position, TeleporterLocation) < (320 * OptionsViewDistance / 100))
                smokePlumeParticles.Draw(gameTime);
                //fireParticles.Draw(gameTime);

            //draw fire only when monster is near.
            if (Vector3.Distance(fpsCam.Position, monster.CurrentLocation) < (320 * OptionsViewDistance / 100))
            {
                antifireParticles.Draw(gameTime);
                fireParticles.Draw(gameTime);
            }
                //smokePlumeParticles.Draw(gameTime);

            //only the walls that are close to me are obscuring the particles.

            bloom.Draw(gameTime);
            base.Draw(gameTime); // DO this before the sprites so the sprites aren't post processed.
            //Now post process

            spriteBatch.Begin(SpriteBlendMode.AlphaBlend);

            if (Stage.GameState.DemoMode)
            {
                //spriteBatch.DrawString(smallfont, "DEBUG Zombie:  " + demoZombie.CurrentLocation.ToString(), new Vector2(10, 40), Color.WhiteSmoke);
            }

            //compass - don't draw in demo or pause (no pausing to plan strategy!)
            if (!Stage.GameState.DemoMode && !Stage.GameState.Pause)
            {
                spriteBatch.DrawString(smallfont, "LEVEL: " + Level.ToString(), new Vector2(10, 40), Color.WhiteSmoke);
                spriteBatch.DrawString(smallfont, "SCORE: " + Score.ToString(), new Vector2(10, 60), Color.WhiteSmoke);
                spriteBatch.DrawString(smallfont, "TIME : " + TimeOnLevel.ToString(), new Vector2(10, 80), Color.WhiteSmoke);

                spriteBatch.Draw(CompassTexture,
                    new Vector2(100, Stage.ConfigurationSettings.Height - 100),
                    null,
                    Color.White,
                    fpsCam.leftrightRot,
                    new Vector2(100, 100),
                    Vector2.One,
                    SpriteEffects.None,
                    0.0f);

                spriteBatch.Draw(CompassPointer,
                    new Vector2(100, Stage.ConfigurationSettings.Height - 100),
                    null,
                    Color.White,
                    0,
                    new Vector2(5, 112),
                    Vector2.One,
                    SpriteEffects.None,
                    0.1f);

                //For some reason this comes out with the opposite sign from which it should.
                float angletowardsmonster = Collision.GetAngleBetween_XZ(fpsCam.Position, monster.CurrentLocation) - MathHelper.ToRadians(90) - fpsCam.leftrightRot;
                //Fix it.
                if (angletowardsmonster > 0)
                    angletowardsmonster -= angletowardsmonster * 2;
                else if (angletowardsmonster < 0)
                    angletowardsmonster = Math.Abs(angletowardsmonster);

                spriteBatch.Draw(CompassSkull,
                    new Vector2(100, Stage.ConfigurationSettings.Height - 100),
                    null,
                    Color.White,
                    angletowardsmonster,
                    new Vector2(5, 100),
                    Vector2.One,
                    SpriteEffects.None,
                    0.1f);

                //For some reason this comes out with the opposite sign from which it should.
                float angletowardsteleporter = Collision.GetAngleBetween_XZ(fpsCam.Position, TeleporterLocation) - MathHelper.ToRadians(90) - fpsCam.leftrightRot;
                //Fix it.
                if (angletowardsteleporter > 0)
                    angletowardsteleporter -= angletowardsteleporter * 2;
                else if (angletowardsteleporter < 0)
                    angletowardsteleporter = Math.Abs(angletowardsteleporter);

                spriteBatch.Draw(CompassArrow,
                    new Vector2(100, Stage.ConfigurationSettings.Height - 100),
                    null,
                    Color.White,
                    angletowardsteleporter,
                    new Vector2(5, 100),
                    Vector2.One,
                    SpriteEffects.None,
                    0.1f);

                //Don't draw the "clue" messages in pause or demo modes.
                //if (!((monster.Actions & FLAG_Actions.FIGHTING) == FLAG_Actions.FIGHTING) && !fpsCam.InDeathThroes)
                //{
                //    if (SeeMonster)
                //        spriteBatch.DrawString(smallfont, "It's here, RUN!", new Vector2(10, 140), Color.Crimson);
                //    else if (HearMonster)
                //        spriteBatch.DrawString(smallfont, "You can hear something moving...", new Vector2(10, 140), Color.Crimson);
                //}
                //else
                //{
                //    spriteBatch.DrawString(font, "AARRGHGHGHH!", new Vector2(10, 120), Color.Crimson);
                //}

                //Minimap
                int dimention = 8;
                int mapwidth = dimention * Stage.Map.Width;
                int mapheight = dimention * Stage.Map.Height;
                float offset_x = Stage.ConfigurationSettings.width - mapwidth - dimention;
                float offset_y = dimention;

                for (int y = 0; y < Stage.Map.Height; y++)
                    for (int x = 0; x < Stage.Map.Width; x++)
                    {
                        if (Stage.Map.GetSquareAt(x, y).type == MapSquareType.Open)
                            if (VisitedGridSquares.Contains(new Point(x, y)))
                            {
                                spriteBatch.Draw(MiniMap_Open, new Vector2(offset_x + x * dimention, offset_y + y * dimention), new Rectangle(8, 8, 8, 8), Color.White);
                                if (fpsCam.LastGridSquareX == x && fpsCam.LastGridSquareY == y)
                                    spriteBatch.Draw(MiniMap_Player, new Vector2(offset_x + x * dimention, offset_y + y * dimention), new Rectangle(0, 0, dimention, dimention), Color.White);
                            }
                    }
            }

            //The banner is not drawn in demo mode since the UI component displays the big banner. But it is drawn in pause mode.
            if(!Stage.GameState.DemoMode)
                spriteBatch.Draw(Banner,
                    new Vector2(0, 0),
                    null,
                    Color.White,
                    0.0f,
                    new Vector2(0, 0),
                    Vector2.One,
                    SpriteEffects.None,
                    0.1f);

            spriteBatch.End();
        }
 public bool Intersects(BoundingFrustum fr)
 {
     return (fr.Intersects(BoundingBox));
 }