Ejemplo n.º 1
0
        /// <summary>
        /// Updates the axis aligned bounding box that exactly contains the bounds of all objects.
        /// </summary>
        private void UpdateBounds()
        {
            if (boundingBoxNeedsUpdate)
            {
                var maxBounds    = 1E6F;
                var hasBoundable = false;
                var queryBounds  = new BoundingBox(-Vector3.One * maxBounds, Vector3.One * maxBounds);
                if (boundsQuery == null)
                {
                    boundsQuery = spatialQuery.CreateSpatialQuery <ISpatialQueryable>();
                }

                boundingBox.Min = Vector3.Zero;
                boundingBox.Max = Vector3.Zero;
                boundsQuery.FindAll(ref queryBounds, boundable =>
                {
                    if (hasBoundable)
                    {
                        var childBounds = boundable.BoundingBox;
                        BoundingBox.CreateMerged(ref boundingBox, ref childBounds, out boundingBox);
                    }
                    else
                    {
                        boundingBox  = boundable.BoundingBox;
                        hasBoundable = true;
                    }
                });
                boundingBoxNeedsUpdate = false;
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Initializes a new instance of the <see cref="DrawingContext"/> class.
        /// </summary>
        public DrawingContext3D(GraphicsDevice graphics, ISpatialQuery spatialQuery) : base(graphics, spatialQuery)
        {
            if (graphics == null)
            {
                throw new ArgumentNullException("graphics");
            }
            if (spatialQuery == null)
            {
                throw new ArgumentNullException("spatialQuery");
            }

            this.defaultLight = new DirectionalLight(graphics)
            {
                DiffuseColor  = Vector3.Zero,
                SpecularColor = Vector3.Zero,
                Direction     = Vector3.Down,
                Enabled       = false
            };
            this.directionalLights = new DirectionalLightCollection(defaultLight);

            this.rootPass.Passes.Insert(0, mainPass = new DrawingPass()
            {
                ClearBackground = true, TransparencySortEnabled = true
            });
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Draws this pass using the specified drawing context.
        /// </summary>
        public override void Draw(DrawingContext context, IList <IDrawableObject> drawables)
        {
            if (shadowCasterQuery == null)
            {
                shadowCasterQuery = context.CreateSpatialQuery <IDrawableObject>(drawable => drawable.CastShadow);
            }

            light.UpdateShadowFrustum(context, shadowCasterQuery);
            shadowCasterQuery.FindAll(light.ShadowFrustum, shadowCasters);

            Matrix oldView       = context.matrices.view;
            Matrix oldProjection = context.matrices.projection;

            Begin();

            // Leave the border pixels untouched so the shadow will not be stretched
            // when using clamped sampling.
            var viewport = context.graphics.Viewport;

            context.graphics.Viewport = new Viewport(viewport.X + 1, viewport.Y + 1, viewport.Width - 2, viewport.Height - 2);

            context.matrices.View       = light.ShadowFrustum.Matrix;
            context.matrices.Projection = Matrix.Identity;

            context.graphics.SamplerStates[0]  = SamplerState.PointClamp;
            context.graphics.BlendState        = BlendState.Opaque;
            context.graphics.DepthStencilState = DepthStencilState.Default;

            for (int i = 0; i < shadowCasters.Count; ++i)
            {
                var shadowCaster = shadowCasters[i];
                if (!shadowCaster.OnAddedToView(context))
                {
                    continue;
                }

                var material = shadowCaster.Material;
                if (material == null)
                {
                    material = depthMaterial;
                }
                else
                {
                    material = material.GetMaterialByUsage(MaterialUsage.Depth);
                }

                if (material != null)
                {
                    shadowCaster.Draw(context, material);
                }
            }

            shadowCasters.Clear();
            End(context);

            context.matrices.View       = oldView;
            context.matrices.Projection = oldProjection;
        }
Ejemplo n.º 4
0
 private void FindSprites(DrawingContext context)
 {
     if (spriteQuery == null)
     {
         spriteQuery      = context.CreateSpatialQuery <ISprite>(sprite => sprite.Visible);
         findSpriteAction = new Action <ISprite>(AddSprite);
     }
     spriteQuery.FindAll(context.ViewFrustum, findSpriteAction);
 }
Ejemplo n.º 5
0
        private void UpdateFriendsAndOpponents()
        {
            if (myFriends != null)
            {
                friends = new SpatialQuery <Navigator, Steerable>(myFriends)
                {
                    Condition = null, Converter = NavigatorToSteerer
                };

                if (myOpponents != null)
                {
                    friendsAndOpponents = new SpatialQuery <Navigator, Steerable>(myFriends, myOpponents)
                    {
                        Condition = null, Converter = NavigatorToSteerer
                    }
                }
                ;
                else
                {
                    friendsAndOpponents = friends;
                }
            }
            else
            {
                friends = null;

                if (myOpponents != null)
                {
                    friendsAndOpponents = new SpatialQuery <Navigator, Steerable>(myOpponents)
                    {
                        Condition = null, Converter = NavigatorToSteerer
                    }
                }
                ;
                else
                {
                    friendsAndOpponents = null;
                }
            }

            separation.Neighbors = friends;
            separation.Enabled   = friends != null;

            steerableAvoidance.Neighbors = friendsAndOpponents;
            steerableAvoidance.Enabled   = friendsAndOpponents != null;
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Initializes a new instance of the <see cref="DrawingContext"/> class.
        /// </summary>
        public DrawingContext(GraphicsDevice graphics, ISpatialQuery spatialQuery)
        {
            if (graphics == null)
            {
                throw new ArgumentNullException("graphics");
            }
            if (spatialQuery == null)
            {
                throw new ArgumentNullException("spatialQuery");
            }

            this.graphics        = graphics;
            this.spatialQuery    = spatialQuery;
            this.BackgroundColor = new Color(95, 120, 157);
            this.drawables       = spatialQuery.CreateSpatialQuery <IDrawableObject>(drawable => drawable.OnAddedToView(this));

            this.matrices = new MatrixCollection();
            this.textures = new TextureCollection();
            this.rootPass = new PassGroup();
            this.rootPass.Passes.Add(new SpritePass());
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Draws the debug overlay of the target scene.
        /// </summary>
        internal void DrawDiagnostics()
        {
            if (debugDrawables == null)
            {
                debugDrawables = CreateSpatialQuery <IDebugDrawable>(drawable => drawable.Visible);
                debugBounds    = CreateSpatialQuery <ISpatialQueryable>(queryable => true);
                debugPrimitive = new DynamicPrimitive(graphics)
                {
                    DepthBias = 0.0002f
                };
                debugDrawablesInViewFrustum = new FastList <IDebugDrawable>();
                debugBoundsInViewFrustum    = new FastList <ISpatialQueryable>();
            }

            BoundingFrustum viewFrustum = ViewFrustum;

            debugDrawables.FindAll(viewFrustum, debugDrawablesInViewFrustum);
            debugBounds.FindAll(viewFrustum, debugBoundsInViewFrustum);

            // TODO:
            //debugPrimitive.AddBox(BoundingBox, null, Constants.SceneBoundsColor, 4);

            for (int i = 0; i < debugBoundsInViewFrustum.Count; ++i)
            {
                //debugPrimitive.AddBox(debugBoundsInViewFrustum[i].BoundingBox, null, Constants.BoundingBoxColor, Constants.MiddleLineWidth);
            }

            for (int i = 0; i < debugDrawablesInViewFrustum.Count; ++i)
            {
                debugDrawablesInViewFrustum[i].Draw(this, debugPrimitive);
            }

            graphics.DepthStencilState = DepthStencilState.Default;
            debugPrimitive.Draw(this, null);
            debugPrimitive.Clear();
            debugDrawablesInViewFrustum.Clear();
            debugBoundsInViewFrustum.Clear();
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Draws this pass using the specified drawing context.
        /// </summary>
        public override void Draw(DrawingContext context, IList <IDrawableObject> drawables)
        {
            var context3D = context as DrawingContext3D;

            Begin(context3D);
            {
                if (drawingPass == null)
                {
                    drawingPass = new DrawingPass();
                    drawingPass.MaterialUsage = MaterialUsage.DepthAndNormal;
                }
                drawingPass.Draw(context, drawables);
            }
            End(context3D);

            context.textures[TextureUsage.DepthBuffer]  = depthBuffer;
            context.textures[TextureUsage.NormalBuffer] = normalBuffer;

            if (lightQuery == null)
            {
                lightQuery     = context.CreateSpatialQuery <IDeferredLight>(null);
                deferredLights = new FastList <IDeferredLight>();
            }

            BeginLights(context3D);
            {
                lightQuery.FindAll(context.ViewFrustum, deferredLights);
                for (int i = 0; i < deferredLights.Count; ++i)
                {
                    DrawLight(context3D, deferredLights[i]);
                }
                deferredLights.Clear();
            }
            EndLights(context3D);

            context.textures[TextureUsage.LightBuffer] = lightBuffer;
        }
Ejemplo n.º 9
0
 public static void FindAll <T>(this ISpatialQuery <T> spatialQuery, BoundingFrustum boundingFrustum, Action <T> result)
 {
     spatialQuery.FindAll(boundingFrustum, new SpatialQueryDelegateAdapter <T>(result));
 }
Ejemplo n.º 10
0
 public static void FindAll <T>(this ISpatialQuery <T> spatialQuery, ref BoundingBox boundingBox, Action <T> result)
 {
     spatialQuery.FindAll(ref boundingBox, new SpatialQueryDelegateAdapter <T>(result));
 }
Ejemplo n.º 11
0
 public static void FindAll <T>(this ISpatialQuery <T> spatialQuery, ref Ray ray, Action <T> result)
 {
     spatialQuery.FindAll(ref ray, new SpatialQueryDelegateAdapter <T>(result));
 }
Ejemplo n.º 12
0
 public static ISpatialQuery <T> CreateSpatialQuery <T>(this ISpatialQuery spatialQuery) where T : class
 {
     return(spatialQuery.CreateSpatialQuery <T>(null));
 }
Ejemplo n.º 13
0
        public void Draw(DrawingContext context, Material material)
        {
            Vector3[] positions;
            ushort[]  indices;

            if (geometryQuery == null)
            {
                geometryQuery = context.CreateSpatialQuery <IGeometry>(null);
            }

            if (primitive == null)
            {
                primitive = new DynamicPrimitive(context.GraphicsDevice);
            }

            // Ray picking
            var mouseState = Mouse.GetState();
            var pickRay    = context.GraphicsDevice.Viewport.CreatePickRay(mouseState.X, mouseState.Y, context.View, context.Projection);

            geometryQuery.FindAll(ref pickRay, geometry =>
            {
                if (geometry.TryGetTriangles(out positions, out indices))
                {
                    var rayInGeometrySpace = pickRay.Transform(Matrix.Invert(geometry.Transform));
                    for (int i = 0; i < indices.Length; i += 3)
                    {
                        var triangle = new Triangle(positions[indices[i]], positions[indices[i + 1]], positions[indices[i + 2]]);
                        if (triangle.Intersects(rayInGeometrySpace).HasValue)
                        {
                            primitive.AddTriangle(triangle, geometry.Transform, new Color(255, 255, 0), 2);
                        }
                    }
                }
            });

            // Box picking
            var speed    = 0.01f;
            var keyboard = Keyboard.GetState();

            if (keyboard.IsKeyDown(Keys.Left))
            {
                pickBox.Min += Vector3.Left * speed;
                pickBox.Max += Vector3.Left * speed;
            }
            if (keyboard.IsKeyDown(Keys.Right))
            {
                pickBox.Min += Vector3.Right * speed;
                pickBox.Max += Vector3.Right * speed;
            }
            if (keyboard.IsKeyDown(Keys.Up))
            {
                pickBox.Min += Vector3.Forward * speed;
                pickBox.Max += Vector3.Forward * speed;
            }
            if (keyboard.IsKeyDown(Keys.Down))
            {
                pickBox.Min += Vector3.Backward * speed;
                pickBox.Max += Vector3.Backward * speed;
            }
            if (keyboard.IsKeyDown(Keys.PageUp))
            {
                pickBox.Min += Vector3.Up * speed;
                pickBox.Max += Vector3.Up * speed;
            }
            if (keyboard.IsKeyDown(Keys.PageDown))
            {
                pickBox.Min += Vector3.Down * speed;
                pickBox.Max += Vector3.Down * speed;
            }

            primitive.AddBox(pickBox, null, Color.Black, 2);

            geometryQuery.FindAll(ref pickBox, geometry =>
            {
                Matrix transform = geometry.Transform;
                if (geometry.TryGetTriangles(out positions, out indices))
                {
                    for (int i = 0; i < indices.Length; i += 3)
                    {
                        var triangle = new Triangle(positions[indices[i]], positions[indices[i + 1]], positions[indices[i + 2]]);

                        Vector3.Transform(ref triangle.V1, ref transform, out triangle.V1);
                        Vector3.Transform(ref triangle.V2, ref transform, out triangle.V2);
                        Vector3.Transform(ref triangle.V3, ref transform, out triangle.V3);

                        var count = triangle.Intersects(ref pickBox, intersections, 0);
                        if (count > 2)
                        {
                            intersections[count++] = intersections[0];
                            primitive.AddLine(intersections.Take(count), null, new Color(255, 0, 0), 1);
                        }
                    }
                }
            });


            // Box Frustum test
            primitive.AddFrustum(testFrustum, null, new Color(0, 128, 0) * 0.2f, 4);
            var intersectionCount = pickBox.Intersects(testFrustum, intersections, 0);

            if (intersectionCount > 2)
            {
                intersections[intersectionCount++] = intersections[0];
                primitive.AddLine(intersections.Take(intersectionCount), null, new Color(0, 0, 255), 4);
            }

            primitive.Draw(context, null);
            primitive.Clear();
        }
Ejemplo n.º 14
0
 /// <summary>
 /// Computes the shadow frustum of this light based on the current
 /// view frustum and objects in the current view frustum;
 /// </summary>
 public virtual void UpdateShadowFrustum(DrawingContext context, ISpatialQuery <IDrawableObject> shadowCasterQuery)
 {
 }