public void CreateDepths(Camera inputCamera) { if (inputCamera == null) { return; } BoundingFrustum frust = inputCamera.GetFrustum(); BoundingBox box = MathFunctions.GetBoundingBox(frust.GetCorners()); Vector3 forward = frust.Near.Normal; Vector3 z = Vector3.Zero; foreach (InstanceData instance in Data) { z = instance.Transform.Translation - inputCamera.Position; instance.Depth = z.LengthSquared(); if (instance.Depth < CullDistance) { // Half plane test. Faster. Much less accurate. //if (Vector3.Dot(z, forward) > 0) if (box.Contains(instance.Transform.Translation) != ContainmentType.Contains) { instance.Depth *= 100; } } else { instance.Depth *= 100; } } }
public static void AddBoundingFrustum(BoundingFrustum frustum, Color color, float life) { DebugShape shape = GetShapeForLines(12, life); frustum.GetCorners(corners); shape.Vertices[0] = new VertexPositionColor(corners[0], color); shape.Vertices[1] = new VertexPositionColor(corners[1], color); shape.Vertices[2] = new VertexPositionColor(corners[1], color); shape.Vertices[3] = new VertexPositionColor(corners[2], color); shape.Vertices[4] = new VertexPositionColor(corners[2], color); shape.Vertices[5] = new VertexPositionColor(corners[3], color); shape.Vertices[6] = new VertexPositionColor(corners[3], color); shape.Vertices[7] = new VertexPositionColor(corners[0], color); shape.Vertices[8] = new VertexPositionColor(corners[4], color); shape.Vertices[9] = new VertexPositionColor(corners[5], color); shape.Vertices[10] = new VertexPositionColor(corners[5], color); shape.Vertices[11] = new VertexPositionColor(corners[6], color); shape.Vertices[12] = new VertexPositionColor(corners[6], color); shape.Vertices[13] = new VertexPositionColor(corners[7], color); shape.Vertices[14] = new VertexPositionColor(corners[7], color); shape.Vertices[15] = new VertexPositionColor(corners[4], color); shape.Vertices[16] = new VertexPositionColor(corners[0], color); shape.Vertices[17] = new VertexPositionColor(corners[4], color); shape.Vertices[18] = new VertexPositionColor(corners[1], color); shape.Vertices[19] = new VertexPositionColor(corners[5], color); shape.Vertices[20] = new VertexPositionColor(corners[2], color); shape.Vertices[21] = new VertexPositionColor(corners[6], color); shape.Vertices[22] = new VertexPositionColor(corners[3], color); shape.Vertices[23] = new VertexPositionColor(corners[7], color); }
protected virtual void UpdateView() { Matrix rot = Matrix.CreateFromYawPitchRoll(pitchYawRoll.Y, pitchYawRoll.X, pitchYawRoll.Z); movement = Vector3.Transform(movement, rot); pos += movement; movement = Vector3.Zero; Vector3 forward = Vector3.Transform(Vector3.Forward, rot); target = pos + forward; Vector3 up = Vector3.Transform(Vector3.Up, rot); view = Matrix.CreateLookAt(pos, target, up); viewFrustum = new BoundingFrustum(view * proj); viewFrustum.GetCorners(frustumCorners); clippingFrustum = ClippingFrustum.FromPoints(frustumCorners); viewPoint = new Vector2() { X = pos.X, Y = pos.Z }; }
/// <summary> /// Unproject a screen coordinate into a ray /// </summary> public static Ray Unproject(Vector2 Point) { //Acquires the frustum of the area of the screen in view //Then it stores the corners of the area BoundingFrustum VisibleArea = new BoundingFrustum(Manager.View * Manager.Projection); Vector3[] corners = VisibleArea.GetCorners(); Vector3 Position = new Vector3(Point, 0.0f); Ray ray = new Ray(); //Point on the near plane of the visible area ray.Position = corners[0] * (1 - Position.X) * (1 - Position.Y) + corners[1] * Position.X * (1 - Position.Y) + corners[2] * Position.X * Position.Y + corners[3] * (1 - Position.X) * Position.Y; Position = corners[4] * (1 - Position.X) * (1 - Position.Y) + corners[5] * Position.X * (1 - Position.Y) + corners[6] * Position.X * Position.Y + corners[7] * (1 - Position.X) * Position.Y; //Direction between the two points ray.Direction = Vector3.Normalize(Position - ray.Position); return(ray); }
public void GetObjectsIntersecting <TObject>(BoundingFrustum frustum, HashSet <TObject> set, CollisionType queryType) where TObject : IBoundedObject { List <SpatialHash <IBoundedObject> > hashes = new List <SpatialHash <IBoundedObject> >(); switch ((int)queryType) { case (int)CollisionType.Static: case (int)CollisionType.Dynamic: hashes.Add(Hashes[queryType]); break; case ((int)CollisionType.Static | (int)CollisionType.Dynamic): hashes.Add(Hashes[CollisionType.Static]); hashes.Add(Hashes[CollisionType.Dynamic]); break; } BoundingBox frustumBox = MathFunctions.GetBoundingBox(frustum.GetCorners()); foreach (var obj in from hash in hashes from pair in hash.HashMap where pair.Value != null && frustumBox.Contains(pair.Key.ToVector3()) == ContainmentType.Contains from obj in pair.Value where obj is TObject && !set.Contains((TObject)obj) && obj.GetBoundingBox().Intersects(frustum) select obj) { set.Add((TObject)obj); } }
/// <summary> /// Project a point into 2D space /// </summary> public static Vector2 Project(BoundingFrustum VisibleArea, Vector3 Point) { //Acquires the frustum of the area of the screen in view. //Then it stores the corners of the area. Vector3[] corners = VisibleArea.GetCorners(); Ray ray = new Ray(Point, Point - Manager.CameraFocus - Manager.CameraLocation); float? DistanceToFar = ray.Intersects(VisibleArea.Far); float? DistanceToNear = ray.Intersects(VisibleArea.Near); Vector3 ScreenCoord; if (DistanceToFar.HasValue) { ScreenCoord = ray.Position + ray.Direction * DistanceToFar.Value; ScreenCoord = new Vector3( Vector3.Dot( Vector3.Normalize(corners[5] - corners[4]) , ScreenCoord - corners[4]) / (corners[5] - corners[4]).Length() , Vector3.Dot( Vector3.Normalize(corners[7] - corners[4]) , ScreenCoord - corners[4]) / (corners[7] - corners[4]).Length() , 0); } else { //Make sure this is off the screen return Vector2.One * (Manager.GameWindow.Width + Manager.GameWindow.Height); } return new Vector2(ScreenCoord.X * Manager.GameWindow.Width, ScreenCoord.Y * Manager.GameWindow.Height); }
public void BoundingFrustum_CalculatesCornersCorrectly() { 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 corners = new Vector3[BoundingFrustum.CornerCount]; frustum.GetCorners(corners); TheResultingValue(corners[0]).WithinDelta(0.0001f) .ShouldBe(-0.5522f, 0.4142f, 4f); TheResultingValue(corners[1]).WithinDelta(0.0001f) .ShouldBe(0.5522f, 0.4142f, 4f); TheResultingValue(corners[2]).WithinDelta(0.0001f) .ShouldBe(0.5522f, -0.4142f, 4f); TheResultingValue(corners[3]).WithinDelta(0.0001f) .ShouldBe(-0.5522f, -0.4142f, 4f); TheResultingValue(corners[4]).WithinDelta(0.0001f) .ShouldBe(-552.2851f, 414.2138f, -995.0007f); TheResultingValue(corners[5]).WithinDelta(0.0001f) .ShouldBe(552.2851f, 414.2138f, -995.0007f); TheResultingValue(corners[6]).WithinDelta(0.0001f) .ShouldBe(552.2851f, -414.2138f, -995.0007f); TheResultingValue(corners[7]).WithinDelta(0.0001f) .ShouldBe(-552.2851f, -414.2138f, -995.0007f); }
/// <summary> /// Draw a bounding frustrum representation /// </summary> /// <param name="frustum">Frustrum</param> /// <param name="camera">Camera</param> /// <param name="color">Color</param> public static void Draw(BoundingFrustum frustum, BaseCamera camera, Color color) { if (effect == null) { effect = new BasicEffect(YnG.GraphicsDevice); effect.VertexColorEnabled = true; effect.LightingEnabled = false; } Vector3[] corners = frustum.GetCorners(); for (int i = 0; i < 8; i++) { vertices[i].Position = corners[i]; vertices[i].Color = color; } effect.View = camera.View; effect.Projection = camera.Projection; foreach (EffectPass pass in effect.CurrentTechnique.Passes) { pass.Apply(); YnG.GraphicsDevice.DrawUserIndexedPrimitives(PrimitiveType.LineList, vertices, 0, 8, indices, 0, indices.Length / 2); } }
/// <summary> /// Unproject a screen coordinate into a ray /// </summary> public static Ray Unproject(Vector2 Point) { //Acquires the frustum of the area of the screen in view //Then it stores the corners of the area BoundingFrustum VisibleArea = new BoundingFrustum(Manager.View * Manager.Projection); Vector3[] corners = VisibleArea.GetCorners(); Vector3 Position = new Vector3(Point, 0.0f); Ray ray = new Ray(); //Point on the near plane of the visible area ray.Position = corners[0] * (1 - Position.X) * (1 - Position.Y) + corners[1] * Position.X * (1 - Position.Y) + corners[2] * Position.X * Position.Y + corners[3] * (1 - Position.X) * Position.Y; Position = corners[4] * (1 - Position.X) * (1 - Position.Y) + corners[5] * Position.X * (1 - Position.Y) + corners[6] * Position.X * Position.Y + corners[7] * (1 - Position.X) * Position.Y; //Direction between the two points ray.Direction = Vector3.Normalize(Position - ray.Position); return ray; }
public void UpdateFromBoundingFrustum(BoundingFrustum sourceBoundingFrustum) { #region Create the lines if necessary if (mLines.Count == 0) { for (int i = 0; i < NumberOfLines; i++) { Line line = ShapeManager.AddLine(); mLines.Add(line); } } #endregion Vector3[] corners = sourceBoundingFrustum.GetCorners(); mLines[0].SetFromAbsoluteEndpoints(corners[0], corners[1]); mLines[1].SetFromAbsoluteEndpoints(corners[1], corners[2]); mLines[2].SetFromAbsoluteEndpoints(corners[2], corners[3]); mLines[3].SetFromAbsoluteEndpoints(corners[3], corners[0]); mLines[4].SetFromAbsoluteEndpoints(corners[4], corners[5]); mLines[5].SetFromAbsoluteEndpoints(corners[5], corners[6]); mLines[6].SetFromAbsoluteEndpoints(corners[6], corners[7]); mLines[7].SetFromAbsoluteEndpoints(corners[7], corners[4]); mLines[8].SetFromAbsoluteEndpoints(corners[0], corners[4]); mLines[9].SetFromAbsoluteEndpoints(corners[1], corners[5]); mLines[10].SetFromAbsoluteEndpoints(corners[2], corners[6]); mLines[11].SetFromAbsoluteEndpoints(corners[3], corners[7]); sourceBoundingFrustum.Near.ToString(); }
public override void SetConstants(IGraphicsContext context) { base.SetConstants(context); var camera = context.CurrentCamera; Effect.Parameters["wPosCamera"].SetValue(camera.Position); Effect.Parameters["near_plane"].SetValue((float)camera.NearPlane); Effect.Parameters["far_plane"].SetValue((float)camera.FarPlane); Effect.Parameters["fov"].SetValue((float)camera.FieldOfView); Vector3[] frustumCornersWS = new Vector3[8]; Vector4[] frustumCornersVS = new Vector4[8]; Vector4[] farFrustumCornersVS = new Vector4[4]; BoundingFrustum frustum = new BoundingFrustum(context.RenderContext.ViewProjD.ToMatrix()); frustum.GetCorners(frustumCornersWS); var view = camera.ViewD.ToMatrix(); // TODO: take out the translation part of the view matrix Vector3.Transform(frustumCornersWS, ref view, frustumCornersVS); // 2 ____________ 1 // | | // | | // | | // 3|____________| 0 // for (int i = 4; i < 8; i++) { farFrustumCornersVS[i - 4] = frustumCornersVS[i]; } Effect.Parameters["frustumCornersVS"].SetValue(farFrustumCornersVS); }
static public float GetDistanceBetweenCameraNearPlaneAndBoundingBox(BoundingFrustum frustum, BoundingBox boundingBox) { Vector3[] corners = new Vector3[8]; boundingBox.GetCorners(corners); Vector3 nearPoint = frustum.GetCorners()[0]; float distanceSqr = float.MaxValue; for (int i = 0; i < corners.Length - 1; ++i) { Vector3 diffVect = corners[i] - nearPoint; float sqrDiffDist = diffVect.LengthSquared(); if (sqrDiffDist < distanceSqr) { distanceSqr = sqrDiffDist; } } // The distances between the points of a near plane aren't large enough that it will be noticeable, so we // don't bother calculating the center of the near plane, we just use a corner. return((float)Math.Sqrt(distanceSqr)); }
public void Draw( ref BoundingFrustum boundingFrustum, Effect effect, ref Color vertexColor) { var coners = boundingFrustum.GetCorners(); var vertices = new VertexPositionColor[8]; for (int i = 0; i < 8; i++) { vertices[i].Position = coners[i]; vertices[i].Color = vertexColor; } foreach (EffectPass pass in effect.CurrentTechnique.Passes) { pass.Apply(); graphicsDevice.DrawUserIndexedPrimitives<VertexPositionColor>( PrimitiveType.LineList, vertices, 0, 8, indices, 0, primitiveCount); } }
public static void Render(BoundingFrustum frustum, GraphicsDevice graphicsDevice, Matrix view, Matrix projection, Color color) { if ((effect == null) == true) { effect = new BasicEffect(graphicsDevice); effect.VertexColorEnabled = true; effect.LightingEnabled = false; } Vector3[] corners = frustum.GetCorners(); for (var I = 0; I <= 7; I++) { verts[I].Position = corners[I]; verts[I].Color = color; } effect.View = view; effect.Projection = projection; foreach (EffectPass pass in effect.CurrentTechnique.Passes) { pass.Apply(); graphicsDevice.DrawUserIndexedPrimitives(PrimitiveType.LineList, verts, 0, 8, indices, 0, Convert.ToInt32(indices.Length / 2)); } }
private void GetChunksIntersecting(BoundingFrustum Frustum, HashSet <VoxelChunk> chunks) { chunks.Clear(); var frustumBox = MathFunctions.GetBoundingBox(Frustum.GetCorners()); var minChunk = ChunkData.ConfineToBounds(GlobalVoxelCoordinate.FromVector3(frustumBox.Min).GetGlobalChunkCoordinate()); var maxChunk = ChunkData.ConfineToBounds(GlobalVoxelCoordinate.FromVector3(frustumBox.Max).GetGlobalChunkCoordinate()); for (var x = minChunk.X; x <= maxChunk.X; ++x) { for (var y = minChunk.Y; y <= maxChunk.Y; ++y) { for (var z = minChunk.Z; z <= maxChunk.Z; ++z) { var chunkCoord = new GlobalChunkCoordinate(x, y, z); var min = new GlobalVoxelCoordinate(chunkCoord, new LocalVoxelCoordinate(0, 0, 0)); var box = new BoundingBox(min.ToVector3(), min.ToVector3() + new Vector3(VoxelConstants.ChunkSizeX, VoxelConstants.ChunkSizeY, VoxelConstants.ChunkSizeZ)); if (Frustum.Contains(box) != ContainmentType.Disjoint) { chunks.Add(ChunkData.GetChunk(chunkCoord)); } } } } }
/// <summary> /// /// </summary> /// <param name="view"></param> /// <param name="projection"></param> /// <param name="frustum"></param> /// <param name="min"></param> /// <param name="max"></param> /// <returns></returns> bool GetFrustumExtent(Matrix view, Matrix projection, Rectangle viewport, BoundingFrustum frustum, out Vector4 min, out Vector4 max) { min = max = Vector4.Zero; var znear = projection.M34 * projection.M43 / projection.M33; var viewPoints = frustum.GetCorners() .Select(p0 => Vector3.TransformCoordinate(p0, view)) .ToArray(); var dr = Game.GetService <DebugRender>(); var lines = new[] { new Line(viewPoints[0], viewPoints[1]), new Line(viewPoints[1], viewPoints[2]), new Line(viewPoints[2], viewPoints[3]), new Line(viewPoints[3], viewPoints[0]), new Line(viewPoints[4], viewPoints[5]), new Line(viewPoints[5], viewPoints[6]), new Line(viewPoints[6], viewPoints[7]), new Line(viewPoints[7], viewPoints[4]), new Line(viewPoints[0], viewPoints[4]), new Line(viewPoints[1], viewPoints[5]), new Line(viewPoints[2], viewPoints[6]), new Line(viewPoints[3], viewPoints[7]), }; lines = lines.Where(line => line.Clip(znear)).ToArray(); if (!lines.Any()) { return(false); } var projPoints = new List <Vector3>(); foreach (var line in lines) { projPoints.Add(Vector3.TransformCoordinate(line.A, projection)); projPoints.Add(Vector3.TransformCoordinate(line.B, projection)); } min.X = projPoints.Min(p => p.X); min.Y = projPoints.Max(p => p.Y); min.Z = projPoints.Min(p => p.Z); max.X = projPoints.Max(p => p.X); max.Y = projPoints.Min(p => p.Y); max.Z = projPoints.Max(p => p.Z); min.X = (min.X * 0.5f + 0.5f) * viewport.Width; min.Y = (min.Y * -0.5f + 0.5f) * viewport.Height; max.X = (max.X * 0.5f + 0.5f) * viewport.Width; max.Y = (max.Y * -0.5f + 0.5f) * viewport.Height; return(true); }
public static void DrawWireframe(PrimitiveDrawer primitiveDrawer, Matrix cameraView, Matrix cameraProjection, BoundingFrustum frustum, Color color) { // The points returned correspond to the corners of the BoundingFrustum faces that are // perpendicular to the z-axis. The near face is the face with the larger z value, and // the far face is the face with the smaller z value. Points 0 to 3 correspond to the // near face in a clockwise order starting at its upper-left corner when looking toward // the origin from the positive z direction. Points 4 to 7 correspond to the far face // in a clockwise order starting at its upper-left corner when looking toward the // origin from the positive z direction. frustum.GetCorners(Corners); FrustumVertices[6].Position = Corners[0]; FrustumVertices[7].Position = Corners[1]; FrustumVertices[5].Position = Corners[2]; FrustumVertices[4].Position = Corners[3]; FrustumVertices[2].Position = Corners[4]; FrustumVertices[3].Position = Corners[5]; FrustumVertices[1].Position = Corners[6]; FrustumVertices[0].Position = Corners[7]; primitiveDrawer.Draw(Matrix.Identity, cameraView, cameraProjection, color, null, PrimitiveType.LineList, FrustumVertices, WireFrustumIndices, false); }
/// <summary> /// Test if a frustum is fully inside, outside, or just intersecting the sphere. /// </summary> /// <param name="frustum">The frustum for testing.</param> /// <returns>The containment type.</returns> public ContainmentType Contains(BoundingFrustum frustum) { //check if all corner is in sphere bool inside = true; Vector3[] corners = frustum.GetCorners(); foreach (Vector3 corner in corners) { if (this.Contains(corner) == ContainmentType.Disjoint) { inside = false; break; } } if (inside) { return(ContainmentType.Contains); } //check if the distance from sphere center to frustrum face < radius double dmin = 0; //TODO : calcul dmin if (dmin <= Radius * Radius) { return(ContainmentType.Intersects); } //else disjoint return(ContainmentType.Disjoint); }
public Projector() : base() { const float near = 0.2f; const float far = 2.3f; const float scale = 1.0f / ScreenDistance * near; projection = Matrix.CreatePerspectiveOffCenter( scale * Skreen.Left, scale * Skreen.Right, scale * -Skreen.Height / 2, scale * Skreen.Height / 2, near, far); view = Matrix.CreateTranslation(0.0f, -Skreen.Height / 2, -ScreenDistance); // this.Width = Screen.PixelWidth; // this.Height = Screen.PixelHeight; // this.Left = WinScreen.AllScreens.Where(s => s != WinScreen.PrimaryScreen).First().Bounds.Left; // this.WindowState = FormWindowState.Maximized; // this.FormBorderStyle = FormBorderStyle.None; var num = Skreen.PixelHeight; var frustum = new BoundingFrustum(view * projection); var corners = frustum.GetCorners(); var tpos = corners[4]; var tray = (corners[7] - corners[4]) / (float)num; var bpos = corners[5]; var bray = (corners[6] - corners[5]) / (float)num; SweptPlanes = new Plane[num]; var projectorPos = Vector3.Zero;//.Invert(this.View).Translation; for (int i = 0; i < num; ++i) SweptPlanes[i] = new Plane(projectorPos, tpos + (float)i * tray, bpos + (float)i * bray); }
public void SetCameraParameters(Camera camera) { gbufferEffect.Parameters["wPosCamera"].SetValue(camera.Position); gbufferEffect.Parameters["near_plane"].SetValue(camera.NearPlane); gbufferEffect.Parameters["far_plane"].SetValue(camera.FarPlane); gbufferEffect.Parameters["fov"].SetValue(camera.FieldOfView); Vector3[] frustumCornersWS = new Vector3[8]; Vector4[] frustumCornersVS = new Vector4[8]; Vector4[] farFrustumCornersVS = new Vector4[4]; Matrix view = camera.ViewD.ToMatrix(); MatrixD viewProj = MatrixD.Multiply(camera.ViewD, camera.ProjD); BoundingFrustum frustum = new BoundingFrustum(viewProj.ToMatrix()); frustum.GetCorners(frustumCornersWS); // TODO: take out the translation part of the view matrix Vector3.Transform(frustumCornersWS, ref view, frustumCornersVS); // 2 ____________ 1 // | | // | | // | | // 3|____________| 0 // for (int i = 4; i < 8; i++) { farFrustumCornersVS[i - 4] = frustumCornersVS[i]; } gbufferEffect.Parameters["frustumCornersVS"].SetValue(farFrustumCornersVS); }
/// <summary> /// Project a point into 2D space /// </summary> public static Vector2 Project(Vector3 Point) { //Acquires the frustum of the area of the screen in view. //Then it stores the corners of the area. BoundingFrustum VisibleArea = new BoundingFrustum(Manager.View * Manager.Projection); Vector3[] corners = VisibleArea.GetCorners(); Ray ray = new Ray(Point, Point - Manager.CameraFocus - Manager.CameraLocation); float? DistanceToFar = ray.Intersects(VisibleArea.Far); float? DistanceToNear = ray.Intersects(VisibleArea.Near); Vector3 ScreenCoord; if (DistanceToFar.HasValue) { ScreenCoord = ray.Position + ray.Direction * DistanceToFar.Value; ScreenCoord = new Vector3( Vector3.Dot( Vector3.Normalize(corners[5] - corners[4]) , ScreenCoord - corners[4]) / (corners[5] - corners[4]).Length() , Vector3.Dot( Vector3.Normalize(corners[7] - corners[4]) , ScreenCoord - corners[4]) / (corners[7] - corners[4]).Length() , 0); } else { //Make sure this is off the screen return(Vector2.One * (Manager.GameWindow.Width + Manager.GameWindow.Height)); } return(new Vector2(ScreenCoord.X * Manager.GameWindow.Width, ScreenCoord.Y * Manager.GameWindow.Height)); }
public void GetChunksIntersecting(BoundingFrustum frustum, HashSet<VoxelChunk> chunks) { chunks.Clear(); BoundingBox frustumBox = MathFunctions.GetBoundingBox(frustum.GetCorners()); GetChunksIntersecting(frustumBox, chunks); chunks.RemoveWhere(chunk => frustum.Contains(chunk.GetBoundingBox()) == ContainmentType.Disjoint); }
/// <summary> /// Camera Far Plane Bounding Frustum (in view space). /// With the help of the bounding frustum, the position can be cheaply reconstructed from a depth value. /// </summary> public void BoundingFrustumViewSpace(Vector3[] cornersViewSpace) { if (cornersViewSpace.Length != 4) throw new ArgumentOutOfRangeException("cornersViewSpace"); boundingFrustum.Matrix = ViewMatrix * ProjectionMatrix; boundingFrustum.GetCorners(cornersWorldSpace); // Transform form world space to view space for (int i = 0; i < 4; i++) { cornersViewSpace[i] = Vector3.Transform(cornersWorldSpace[i + 4], ViewMatrix); } // Swap the last 2 values. Vector3 temp = cornersViewSpace[3]; cornersViewSpace[3] = cornersViewSpace[2]; cornersViewSpace[2] = temp; } // BoundingFrustumViewSpace
/// <summary> /// /// </summary> /// <param name="view"></param> /// <param name="projection"></param> /// <param name="frustum"></param> /// <param name="min"></param> /// <param name="max"></param> /// <returns></returns> bool GetFrustumExtent ( Matrix view, Matrix projection, Rectangle viewport, BoundingFrustum frustum, out Vector4 min, out Vector4 max ) { min = max = Vector4.Zero; var znear = projection.M34 * projection.M43 / projection.M33; var viewPoints = frustum.GetCorners() .Select( p0 => Vector3.TransformCoordinate( p0, view ) ) .ToArray(); //var dr = Game.GetService<DebugRender>(); var lines = new[]{ new Line( viewPoints[0], viewPoints[1] ), new Line( viewPoints[1], viewPoints[2] ), new Line( viewPoints[2], viewPoints[3] ), new Line( viewPoints[3], viewPoints[0] ), new Line( viewPoints[4], viewPoints[5] ), new Line( viewPoints[5], viewPoints[6] ), new Line( viewPoints[6], viewPoints[7] ), new Line( viewPoints[7], viewPoints[4] ), new Line( viewPoints[0], viewPoints[4] ), new Line( viewPoints[1], viewPoints[5] ), new Line( viewPoints[2], viewPoints[6] ), new Line( viewPoints[3], viewPoints[7] ), }; lines = lines.Where( line => line.Clip(znear) ).ToArray(); if (!lines.Any()) { return false; } var projPoints = new List<Vector3>(); foreach ( var line in lines ) { projPoints.Add( Vector3.TransformCoordinate( line.A, projection ) ); projPoints.Add( Vector3.TransformCoordinate( line.B, projection ) ); } min.X = projPoints.Min( p => p.X ); min.Y = projPoints.Max( p => p.Y ); min.Z = projPoints.Min( p => p.Z ); max.X = projPoints.Max( p => p.X ); max.Y = projPoints.Min( p => p.Y ); max.Z = projPoints.Max( p => p.Z ); min.X = ( min.X * 0.5f + 0.5f ) * viewport.Width; min.Y = ( min.Y * -0.5f + 0.5f ) * viewport.Height; max.X = ( max.X * 0.5f + 0.5f ) * viewport.Width; max.Y = ( max.Y * -0.5f + 0.5f ) * viewport.Height; return true; }
public void ComputeLightViewProjection() { switch (lightSource.Type) { case LightType.Directional: tmpVec1 = lightSource.TransformedDirection; // Matrix with that will rotate in points the direction of the light Matrix.CreateLookAt(ref zero, ref tmpVec1, ref up, out tmpMat1); // Get the corners of the frustum Vector3[] frustumCorners = lightFrustum.GetCorners(); // Transform the positions of the corners into the direction of the light for (int i = 0; i < frustumCorners.Length; i++) { Vector3.Transform(ref frustumCorners[i], ref tmpMat1, out frustumCorners[i]); } // Find the smallest box around the points BoundingBox lightBox = BoundingBox.CreateFromPoints(frustumCorners); Vector3 boxSize = lightBox.Max - lightBox.Min; Vector3 halfBoxSize = boxSize * 0.5f; // The position of the light should be in the center of the back // pannel of the box. tmpVec1 = lightBox.Min + halfBoxSize; tmpVec1.Z = lightBox.Min.Z; // We need the position back in world coordinates so we transform // the light position by the inverse of the lights rotation Matrix.Invert(ref tmpMat1, out tmpMat2); Vector3.Transform(ref tmpVec1, ref tmpMat2, out tmpVec1); // Create the view matrix for the light tmpVec2 = tmpVec1 + lightSource.TransformedDirection; Matrix.CreateLookAt(ref tmpVec1, ref tmpVec2, ref up, out tmpMat1); // Create the projection matrix for the light // The projection is orthographic since we are using a directional light Matrix.CreateOrthographic(boxSize.X, boxSize.Y, -boxSize.Z, boxSize.Z, out tmpMat2); Matrix.Multiply(ref tmpMat1, ref tmpMat2, out lightViewProjection); break; case LightType.Point: case LightType.SpotLight: tmpVec1 = lightSource.TransformedPosition; tmpVec2 = lightSource.TransformedDirection; Matrix.CreateLookAt(ref tmpVec1, ref tmpVec2, ref up, out tmpMat1); Matrix.Multiply(ref tmpMat1, ref lightProjection, out lightViewProjection); break; } }
protected override void AddVerticesAndIndices() { ushort baseIndex = checked ((ushort)_vertices.Count); FrustumCorners corners = _frustum.GetCorners(); _vertices.Add(new WireframeVertex(corners.NearTopLeft, Color)); _vertices.Add(new WireframeVertex(corners.NearTopRight, Color)); _vertices.Add(new WireframeVertex(corners.NearBottomRight, Color)); _vertices.Add(new WireframeVertex(corners.NearBottomLeft, Color)); _vertices.Add(new WireframeVertex(corners.FarTopLeft, Color)); _vertices.Add(new WireframeVertex(corners.FarTopRight, Color)); _vertices.Add(new WireframeVertex(corners.FarBottomRight, Color)); _vertices.Add(new WireframeVertex(corners.FarBottomLeft, Color)); _indices.Add((ushort)(baseIndex + 0)); _indices.Add((ushort)(baseIndex + 1)); _indices.Add((ushort)(baseIndex + 0)); _indices.Add((ushort)(baseIndex + 1)); _indices.Add((ushort)(baseIndex + 2)); _indices.Add((ushort)(baseIndex + 1)); _indices.Add((ushort)(baseIndex + 2)); _indices.Add((ushort)(baseIndex + 3)); _indices.Add((ushort)(baseIndex + 2)); _indices.Add((ushort)(baseIndex + 3)); _indices.Add((ushort)(baseIndex + 0)); _indices.Add((ushort)(baseIndex + 3)); _indices.Add((ushort)(baseIndex + 0)); _indices.Add((ushort)(baseIndex + 4)); _indices.Add((ushort)(baseIndex + 0)); _indices.Add((ushort)(baseIndex + 4)); _indices.Add((ushort)(baseIndex + 7)); _indices.Add((ushort)(baseIndex + 4)); _indices.Add((ushort)(baseIndex + 7)); _indices.Add((ushort)(baseIndex + 3)); _indices.Add((ushort)(baseIndex + 7)); _indices.Add((ushort)(baseIndex + 4)); _indices.Add((ushort)(baseIndex + 5)); _indices.Add((ushort)(baseIndex + 4)); _indices.Add((ushort)(baseIndex + 5)); _indices.Add((ushort)(baseIndex + 6)); _indices.Add((ushort)(baseIndex + 5)); _indices.Add((ushort)(baseIndex + 6)); _indices.Add((ushort)(baseIndex + 7)); _indices.Add((ushort)(baseIndex + 6)); _indices.Add((ushort)(baseIndex + 1)); _indices.Add((ushort)(baseIndex + 5)); _indices.Add((ushort)(baseIndex + 1)); _indices.Add((ushort)(baseIndex + 2)); _indices.Add((ushort)(baseIndex + 6)); _indices.Add((ushort)(baseIndex + 2)); }
protected override void AddVerticesAndIndices() { int baseIndex = _vertices.Count; FrustumCorners corners = _frustum.GetCorners(); _vertices.Add(new VertexPositionNormalTexture(corners.NearTopLeft, Vector3.One * 0.5f, Vector2.One * 0.5f)); _vertices.Add(new VertexPositionNormalTexture(corners.NearTopRight, Vector3.One * 0.5f, Vector2.One * 0.5f)); _vertices.Add(new VertexPositionNormalTexture(corners.NearBottomRight, Vector3.One * 0.5f, Vector2.One * 0.5f)); _vertices.Add(new VertexPositionNormalTexture(corners.NearBottomLeft, Vector3.One * 0.5f, Vector2.One * 0.5f)); _vertices.Add(new VertexPositionNormalTexture(corners.FarTopLeft, Vector3.Zero, Vector2.Zero)); _vertices.Add(new VertexPositionNormalTexture(corners.FarTopRight, Vector3.Zero, Vector2.Zero)); _vertices.Add(new VertexPositionNormalTexture(corners.FarBottomRight, Vector3.Zero, Vector2.Zero)); _vertices.Add(new VertexPositionNormalTexture(corners.FarBottomLeft, Vector3.Zero, Vector2.Zero)); _indices.Add((ushort)(baseIndex + 0)); _indices.Add((ushort)(baseIndex + 1)); _indices.Add((ushort)(baseIndex + 0)); _indices.Add((ushort)(baseIndex + 1)); _indices.Add((ushort)(baseIndex + 2)); _indices.Add((ushort)(baseIndex + 1)); _indices.Add((ushort)(baseIndex + 2)); _indices.Add((ushort)(baseIndex + 3)); _indices.Add((ushort)(baseIndex + 2)); _indices.Add((ushort)(baseIndex + 3)); _indices.Add((ushort)(baseIndex + 0)); _indices.Add((ushort)(baseIndex + 3)); _indices.Add((ushort)(baseIndex + 0)); _indices.Add((ushort)(baseIndex + 4)); _indices.Add((ushort)(baseIndex + 0)); _indices.Add((ushort)(baseIndex + 4)); _indices.Add((ushort)(baseIndex + 7)); _indices.Add((ushort)(baseIndex + 4)); _indices.Add((ushort)(baseIndex + 7)); _indices.Add((ushort)(baseIndex + 3)); _indices.Add((ushort)(baseIndex + 7)); _indices.Add((ushort)(baseIndex + 4)); _indices.Add((ushort)(baseIndex + 5)); _indices.Add((ushort)(baseIndex + 4)); _indices.Add((ushort)(baseIndex + 5)); _indices.Add((ushort)(baseIndex + 6)); _indices.Add((ushort)(baseIndex + 5)); _indices.Add((ushort)(baseIndex + 6)); _indices.Add((ushort)(baseIndex + 7)); _indices.Add((ushort)(baseIndex + 6)); _indices.Add((ushort)(baseIndex + 1)); _indices.Add((ushort)(baseIndex + 5)); _indices.Add((ushort)(baseIndex + 1)); _indices.Add((ushort)(baseIndex + 2)); _indices.Add((ushort)(baseIndex + 6)); _indices.Add((ushort)(baseIndex + 2)); }
public IEnumerable <VoxelChunk> EnumerateChunksInBounds(BoundingFrustum Frustum) { return(EnumerateChunksInBounds(MathFunctions.GetBoundingBox(Frustum.GetCorners())) .Where(c => { var min = new GlobalVoxelCoordinate(c.ID, new LocalVoxelCoordinate(0, 0, 0)); var box = new BoundingBox(min.ToVector3(), min.ToVector3() + new Vector3(VoxelConstants.ChunkSizeX, VoxelConstants.ChunkSizeY, VoxelConstants.ChunkSizeZ)); var r = Frustum.Contains(box) != ContainmentType.Disjoint; return r; })); }
public void UpdateComponents(Matrix viewProjection) { boundingFrustum = new BoundingFrustum(viewProjection); Vector3[] corners = boundingFrustum.GetCorners(); for (int i = 0; i < 8; i++) { vertices[i].Position = corners[i]; } vertexBuffer.SetData(vertices); }
public static BoundingBox GetCameraBoundingBox(Matrix viewTransform, Matrix projectionTransform) { BoundingFrustum cameraFrustum = new BoundingFrustum(Matrix.Identity); cameraFrustum.Matrix = viewTransform * projectionTransform; // Get the corners of the frustum Vector3[] frustumCorners = cameraFrustum.GetCorners(); BoundingBox bounds = BoundingBox.CreateFromPoints(frustumCorners); return bounds; }
/// <summary> /// Clips a box against a frustum and split the input triangle when they interests. /// </summary> public static int Intersects(this BoundingBox box, BoundingFrustum frustum, Vector3[] intersections, int startIndex) { var count = 0; frustum.GetCorners(FrustumCorners); for (int i = 0; i < TriangleIndices.Length; i += 3) { count += Triangle.Intersects(ref FrustumCorners[TriangleIndices[i]], ref FrustumCorners[TriangleIndices[i + 1]], ref FrustumCorners[TriangleIndices[i + 2]], ref box, intersections, startIndex + count); } return(startIndex + count); }
public ContainmentType Contains(BoundingFrustum frustum) { Vector3[] corners = frustum.GetCorners(); for (int i = 0; i < corners.Length; i++) { if (Contains(corners[i]) == ContainmentType.Disjoint) { return(i > 0 ? ContainmentType.Disjoint : ContainmentType.Intersects); } } return(ContainmentType.Contains); }
private Vector3[] GetFarFrustumCorners(Matrix view, Matrix projection) { BoundingFrustum frustum = new BoundingFrustum(view * projection); var cornersWS = frustum.GetCorners(); Vector3[] cornersVS = new Vector3[cornersWS.Length]; Vector3.Transform(cornersWS, ref view, cornersVS); Vector3[] farFrustumCorners = new Vector3[4]; for (int i = 0; i < 4; ++i) { //farFrustumCorners[i] = Vector3.Transform(cornersVS[i + 4], Matrix.Invert(playerCam.view)); farFrustumCorners[i] = cornersVS[i + 4]; } return(farFrustumCorners); }
private void UpdateVisibility(BoundingFrustum frustum) { var boundingBox = TreeBoundingBox; // This is to allow non-virtual calls to the culling methods var info = new CullingInfo(); info.Frustum = frustum; info.FrustumBoundingBox = BoundingBox.FromPoints(frustum.GetCorners()); info.Tree = tree; info.CullablesReferenceCounts = cullablesReferenceCounts; info.Culler = culler; updateVisibility(tree.GetRoot(), ref info, ref boundingBox, false); }
// IMPORTANT: Bounding box you are trying to change need to have positive/negative infinite values, so initialize it with InitialBox (static member) static public void AddFrustum(ref BoundingFrustum frustum, ref BoundingBox bb) { if (pts == null) pts = new Vector3[8]; frustum.GetCorners(pts); AddPoint(ref pts[0], ref bb); AddPoint(ref pts[1], ref bb); AddPoint(ref pts[2], ref bb); AddPoint(ref pts[3], ref bb); AddPoint(ref pts[4], ref bb); AddPoint(ref pts[5], ref bb); AddPoint(ref pts[6], ref bb); AddPoint(ref pts[7], ref bb); }
public ContainmentType Contains(BoundingFrustum frustum) { //TODO: bad done here need a fix. //Because question is not frustum contain box but reverse and this is not the same int i; ContainmentType contained; Vector3[] corners = frustum.GetCorners(); // First we check if frustum is in box for (i = 0; i < corners.Length; i++) { this.Contains(ref corners[i], out contained); if (contained == ContainmentType.Disjoint) { break; } } if (i == corners.Length) // This means we checked all the corners and they were all contain or instersect { return(ContainmentType.Contains); } if (i != 0) // if i is not equal to zero, we can fastpath and say that this box intersects { return(ContainmentType.Intersects); } // If we get here, it means the first (and only) point we checked was actually contained in the frustum. // So we assume that all other points will also be contained. If one of the points is disjoint, we can // exit immediately saying that the result is Intersects i++; for (; i < corners.Length; i++) { this.Contains(ref corners[i], out contained); if (contained != ContainmentType.Contains) { return(ContainmentType.Intersects); } } // If we get here, then we know all the points were actually contained, therefore result is Contains return(ContainmentType.Contains); }
/// <summary> /// From https://jcoluna.wordpress.com/2011/01/18/xna-4-0-light-pre-pass/ /// Compute the frustum corners for a camera. /// Its used to reconstruct the pixel position using only the depth value. /// Read here for more information /// http://mynameismjp.wordpress.com/2009/03/10/reconstructing-position-from-depth/ /// </summary> /// <param name="cameraFrustum"></param> private void ComputeFrustumCorners(BoundingFrustum cameraFrustum) { cameraFrustum.GetCorners(_cornersWorldSpace); //this is the inverse of our camera transform Vector3.Transform(_cornersWorldSpace, ref _view, _cornersViewSpace); //put the frustum into view space for (int i = 0; i < 4; i++) //take only the 4 farthest points { _currentFrustumCorners[i] = _cornersViewSpace[i + 4]; } Vector3 temp = _currentFrustumCorners[3]; _currentFrustumCorners[3] = _currentFrustumCorners[2]; _currentFrustumCorners[2] = temp; _ambientOcclusionShader.FrustumCorners = _currentFrustumCorners; //Shaders.deferredEnvironmentParameter_FrustumCorners.SetValue(_currentFrustumCorners); }
public static void AddBoundingFrustum(BoundingFrustum frustum, Color color) { // Get a DebugShape we can use to draw the frustum DebugShape shape = GetShapeForLines(12); // Get the corners of the frustum frustum.GetCorners(corners); // Fill in the vertices for the bottom of the frustum shape.Vertices[0] = new VertexPositionColor(corners[0], color); shape.Vertices[1] = new VertexPositionColor(corners[1], color); shape.Vertices[2] = new VertexPositionColor(corners[1], color); shape.Vertices[3] = new VertexPositionColor(corners[2], color); shape.Vertices[4] = new VertexPositionColor(corners[2], color); shape.Vertices[5] = new VertexPositionColor(corners[3], color); shape.Vertices[6] = new VertexPositionColor(corners[3], color); shape.Vertices[7] = new VertexPositionColor(corners[0], color); // Fill in the vertices for the top of the frustum shape.Vertices[8] = new VertexPositionColor(corners[4], color); shape.Vertices[9] = new VertexPositionColor(corners[5], color); shape.Vertices[10] = new VertexPositionColor(corners[5], color); shape.Vertices[11] = new VertexPositionColor(corners[6], color); shape.Vertices[12] = new VertexPositionColor(corners[6], color); shape.Vertices[13] = new VertexPositionColor(corners[7], color); shape.Vertices[14] = new VertexPositionColor(corners[7], color); shape.Vertices[15] = new VertexPositionColor(corners[4], color); // Fill in the vertices for the vertical sides of the frustum shape.Vertices[16] = new VertexPositionColor(corners[0], color); shape.Vertices[17] = new VertexPositionColor(corners[4], color); shape.Vertices[18] = new VertexPositionColor(corners[1], color); shape.Vertices[19] = new VertexPositionColor(corners[5], color); shape.Vertices[20] = new VertexPositionColor(corners[2], color); shape.Vertices[21] = new VertexPositionColor(corners[6], color); shape.Vertices[22] = new VertexPositionColor(corners[3], color); shape.Vertices[23] = new VertexPositionColor(corners[7], color); }
public static void Render(BoundingFrustum frustum, GraphicsDevice graphicsDevice, Matrix view, Matrix projection, Color color) { if (_basicEffect.IsNull()) _basicEffect = new BasicEffect(graphicsDevice) { VertexColorEnabled = true, LightingEnabled = false }; var corners = frustum.GetCorners(); for (var i = 0; i < 8; i++) { Vertices[i].Position = corners[i]; Vertices[i].Color = color; } _basicEffect.View = view; _basicEffect.Projection = projection; foreach (var pass in _basicEffect.CurrentTechnique.Passes) { pass.Apply(); graphicsDevice.DrawUserIndexedPrimitives(PrimitiveType.LineList, Vertices, 0, 8, Indices, 0, Indices.Length/2); } }
Matrix CreateLightViewProjectionMatrix() { // Matrix with that will rotate in points the direction of the light Matrix lightRotation = Matrix.CreateLookAt(Vector3.Zero, -lightDir, Vector3.Up); // Get the corners of the frustum //float FOV = MathHelper.Clamp( // (25 * (mouseCamera.cameraPosition.Y / 5)), // == 90 at height: 18 // 10, 90 ); float FOV = MathHelper.ToRadians(45); float FAR_PLANE = 20000; //float FAR_PLANE = (100 * (MathHelper.Clamp( // (mouseCamera.cameraPosition.Y / 10), // 1f, 10f) )); // // * MathHelper.Clamp( mouseCamera.updownRot, 0.5f, 1f) ); Matrix newProjMatrix = Matrix.CreatePerspectiveFieldOfView( MathHelper.ToRadians( FOV ), //MathHelper.PiOver4, 1.0f, 1f, FAR_PLANE); BoundingFrustum newFrustum = new BoundingFrustum(Matrix.CreateLookAt (mouseCamera.cameraPosition, mouseCamera.cameraPosition + lightDir, Vector3.Up) * newProjMatrix); //cameraFrustum.Matrix = viewMatrix * parentGame.projectionMatrix; //Vector3[] frustumCorners = mouseCamera.cameraFrustum.GetCorners(); Vector3[] frustumCorners = newFrustum.GetCorners(); // Transform the positions of the corners into the direction of the light for (int i = 0; i < frustumCorners.Length; i++) { frustumCorners[i] = Vector3.Transform(frustumCorners[i], lightRotation); } // Find the smallest box around the points BoundingBox lightBox = BoundingBox.CreateFromPoints(frustumCorners); Vector3 boxSize = lightBox.Max - lightBox.Min ; Vector3 halfBoxSize = boxSize * 0.5f; // The position of the light should be in the center of the back // pannel of the box. Vector3 lightPosition = lightBox.Min + halfBoxSize; lightPosition.Z = lightBox.Min.Z; // We need the position back in world coordinates so we transform // the light position by the inverse of the lights rotation lightPosition = Vector3.Transform(lightPosition, Matrix.Invert(lightRotation)); // Create the view matrix for the light Matrix lightView = Matrix.CreateLookAt(lightPosition, lightPosition - lightDir, Vector3.Up); // Create the projection matrix for the light // The projection is orthographic since we are using a directional light Matrix lightProjection = Matrix.CreateOrthographic(boxSize.X, boxSize.Y, -boxSize.Z, boxSize.Z); return lightView * lightProjection; }
/// <summary> /// Updates this cameras position (used to smooth the movement) /// </summary> public void Update() { if (firstRun) { finalPosition = Position; finalTarget = Target; } firstRun = false; if (ControlType == CameraControlType.ThirdPerson) { Position = Vector3.Lerp(Position, finalPosition, SmoothFactor); finalTarget = Target; } else if (ControlType == CameraControlType.FirstPerson) { Target = Vector3.Lerp(Target, finalTarget, SmoothFactor); finalPosition = Position; } if (ControlType == CameraControlType.ThirdPerson) finalPosition = finalTarget + Vector3.Transform(Vector3.Backward, Matrix.CreateFromYawPitchRoll(Yaw, -Pitch, 0)) * Distance; else if (ControlType == CameraControlType.FirstPerson) finalTarget = finalPosition + Vector3.Transform(Vector3.Forward, Matrix.CreateFromYawPitchRoll(Yaw, Pitch, 0)) * Distance; // Compute the view and projection matrix View = Matrix.CreateLookAt(Position, Target, Vector3.Transform(Vector3.Up, Matrix.CreateFromYawPitchRoll(Yaw, -Pitch, Roll))); Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, game.GraphicsDevice.Viewport.AspectRatio, NearPlane, FarPlane); // Compute frustum and corners Frustum = new BoundingFrustum(View * Projection); Vector3[] frustumCorners = Frustum.GetCorners(); for (int i = 0; i < 4; i++) frustumCorners[i] = frustumCorners[i + 4]; Array.Resize(ref frustumCorners, 4); Vector3 corner = frustumCorners[2]; frustumCorners[2] = frustumCorners[3]; frustumCorners[3] = corner; FrustumCorners = frustumCorners; }
public void Render(GameTime g, Camera cam) { float dt = (float)g.ElapsedGameTime.TotalSeconds; float elapsed = (float)g.TotalGameTime.TotalSeconds; device.SetRenderTargets(colorTarget, normalTarget, depthTarget); clearGBufferEffect.Parameters["farplane"].SetValue(cam.FarPlane); postProcessor.DrawFullScreenQuad(clearGBufferEffect); device.BlendState = BlendState.Opaque; device.DepthStencilState = DepthStencilState.Default; BoundingFrustum frustum = new BoundingFrustum(cam.View * cam.Projection); //renderGBufferEffect.Parameters["frustumCorners"].SetValue(frustum.GetCorners()); foreach (Model m in models) { foreach (ModelMesh mesh in m.Meshes) { foreach (ModelMeshPart meshPart in mesh.MeshParts) { Effect effect = meshPart.Effect; effect.Parameters["World"].SetValue(Matrix.Identity); effect.Parameters["View"].SetValue(cam.View); effect.Parameters["Projection"].SetValue(cam.Projection); } mesh.Draw(); } } //Texture2D result = postProcessor.Process(normalTarget, colorTarget, depthTarget, normalTarget); device.SetRenderTarget(colorTarget); device.Clear(Color.Red); //PostProcessor.DrawFullScreenQuad(depthTarget); Vector3[] corners = frustum.GetCorners(); Vector3[] farCorners = new Vector3[4]; for (int i = 0; i < corners.Length; i++) { corners[i] = Vector3.Transform(corners[i], cam.View); } for (int i = 0; i < 4; i++) { farCorners[i] = corners[i + 4] - corners[i]; } ssaoEffect.Parameters["frustumCorners"].SetValue(farCorners); ssaoEffect.Parameters["depthMap"].SetValue(depthTarget); ssaoEffect.Parameters["normalMap"].SetValue(normalTarget); ssaoEffect.Parameters["noiseMap"].SetValue(NoiseMap); ssaoEffect.Parameters["halfPixel"].SetValue(new Vector2(0.5f / (float)device.PresentationParameters.BackBufferWidth, 0.5f / (float)device.PresentationParameters.BackBufferHeight)); ssaoEffect.Parameters["Projection"].SetValue(cam.Projection); ssaoEffect.Parameters["invProjection"].SetValue(Matrix.Invert(cam.Projection)); Matrix tempView = cam.View; tempView.M41 = 0; tempView.M42 = 0; tempView.M43 = 0; tempView.M44 = 0; ssaoEffect.Parameters["View"].SetValue(tempView); ssaoEffect.Parameters["radius"].SetValue(radius); PostProcessor.DrawFullScreenQuad(ssaoEffect); Texture2D result = postProcessor.Process(colorTarget, colorTarget, depthTarget, normalTarget); device.SetRenderTarget(null); device.Clear(Color.Red); postProcessor.DrawFullScreenQuad(result); }
public static void Intersects(ref Ray ray, ref BoundingFrustum boundingFrustum, out float? result) { // TODO: Make test case of this if (boundingFrustum.Contains(ray.Position) == ContainmentType.Contains) { // the ray is inside the frustum result = 0.0f; } else { result = null; var corners = boundingFrustum.GetCorners(); for (int i = 0; i < (BoundingFrustum.PlaneCount * 2); i++) { var v1 = corners[Geometry.TriangleIndices[i + 0]]; var v2 = corners[Geometry.TriangleIndices[i + 1]]; var v3 = corners[Geometry.TriangleIndices[i + 2]]; Intersects(ref ray, ref v1, ref v2, ref v3, out result); if (result.HasValue) break; } } }
public static void Render(BoundingFrustum frustum, GraphicsDevice graphicsDevice, Matrix view, Matrix projection, Color color) { VertexPositionColorNormal[] boxVertices = new VertexPositionColorNormal[8]; Vector3[] corners = frustum.GetCorners(); for (int i = 0; i < 8; i++) { boxVertices[i].Position = corners[i]; boxVertices[i].Color = Color.White; boxVertices[i].Normal = Vector3.Up; } short[] boxLines = new short[] { 0, 1, 1, 2, 2, 3, 3, 0, 0, 4, 1, 5, 2, 6, 3, 7, 4, 5, 5, 6, 6, 7, 7, 4 }; VertexBuffer buffer = new VertexBuffer( graphicsDevice, VertexPositionColorNormal.VertexDeclaration, boxVertices.Length, BufferUsage.WriteOnly); buffer.SetData(boxVertices); IndexBuffer indexBuffer = new IndexBuffer(graphicsDevice, typeof(short), boxLines.Length, BufferUsage.WriteOnly); indexBuffer.SetData(boxLines); graphicsDevice.Indices = indexBuffer; graphicsDevice.SetVertexBuffer(buffer); effect.World = Matrix.Identity; effect.View = view; effect.Projection = projection; effect.DiffuseColor = color.ToVector3(); foreach (EffectPass pass in effect.CurrentTechnique.Passes) { pass.Apply(); graphicsDevice.DrawIndexedPrimitives(PrimitiveType.LineList, 0, 0, boxVertices.Length, 0, boxLines.Length / 2); } }
public void DrawCamera(RTSRenderer renderer, Rectangle scissor) { BoundingFrustum f = new BoundingFrustum(renderer.Camera.View * renderer.Camera.Projection); Vector3[] corners = f.GetCorners(); for(int i = 0; i < 4; i++) { Vector3 dir = corners[i + 4] - corners[i]; float min = dir.Length(); dir /= min; Ray r = new Ray(corners[i], dir); foreach(Plane p in mapPlanes) { float? v = r.Intersects(p); if(v != null && v.Value < min) { min = v.Value; } } corners[i + 4] = r.Position + (r.Direction * min); } VertexPositionColor[] verts = { new VertexPositionColor(corners[0], CAMERA_COLOR_START), new VertexPositionColor(corners[1], CAMERA_COLOR_START), new VertexPositionColor(corners[3], CAMERA_COLOR_START), new VertexPositionColor(corners[2], CAMERA_COLOR_START), new VertexPositionColor(corners[4], CAMERA_COLOR_END), new VertexPositionColor(corners[5], CAMERA_COLOR_END), new VertexPositionColor(corners[7], CAMERA_COLOR_END), new VertexPositionColor(corners[6], CAMERA_COLOR_END) }; renderer.G.BlendState = BlendState.Additive; renderer.G.DepthStencilState = DepthStencilState.None; renderer.G.RasterizerState = RasterizerState.CullNone; fxCamera.CurrentTechnique.Passes[0].Apply(); Viewport vp = renderer.G.Viewport; renderer.G.Viewport = new Viewport(scissor); renderer.G.DrawUserIndexedPrimitives(PrimitiveType.TriangleList, verts, 0, 8, FRUSTUM_INDS, 0, 12); renderer.G.Viewport = vp; }
private void DrawNodeFrustum(TerrainNode node) { // calculate the width of the patch; first we need a vertex on both sides of the patch, in planet space Vector3 p1 = node.Position.AsVector3 + node.VertexBuffer.Vertices[1 * 33 + 1].Position; Vector3 p2 = node.Position.AsVector3 + node.VertexBuffer.Vertices[1 * 33 + 33].Position; // need to move them to the sphere radius p1.Normalize(); p1 *= (float)sphere.Radius; p2.Normalize(); p2 *= (float)sphere.Radius; // now we can calculate the opposite and hypotenuse lengths float opposite = Vector3.Distance(p1, p2) * 0.5f; // width is distance between p1 and p2, and we need just half of it float hypotenuse = (float)sphere.Radius; // once we have the width we can calculate the field of view float fieldOfView = (float)(2.0 * Math.Asin(opposite / hypotenuse)); // now we can create the view and projection matrixes Matrix view = Matrix.CreateLookAt(Vector3.Zero, node.Position.AsVector3, Vector3.Up); Matrix projection = Matrix.CreatePerspectiveFieldOfView(fieldOfView, 1.0f, 1.0f, 9000.0f); // which then lets us create the bounding frustum BoundingFrustum frustum = new BoundingFrustum(view * projection); Vector3[] corners = frustum.GetCorners(); // draw lines between corners VertexPositionColor[] vertices = new VertexPositionColor[24]; Position3 p = Position3.Zero; Position3 p0 = node.Position; p0.Normalize(); p0 *= 9000.0f; // line 1 vertices[0] = new VertexPositionColor(corners[0], Color.White); vertices[1] = new VertexPositionColor(corners[1], Color.White); // line 2 vertices[2] = new VertexPositionColor(corners[1], Color.White); vertices[3] = new VertexPositionColor(corners[2], Color.White); // line 3 vertices[4] = new VertexPositionColor(corners[2], Color.White); vertices[5] = new VertexPositionColor(corners[3], Color.White); // line 4 vertices[6] = new VertexPositionColor(corners[3], Color.White); vertices[7] = new VertexPositionColor(corners[0], Color.White); // line 5 vertices[8] = new VertexPositionColor(corners[4], Color.White); vertices[9] = new VertexPositionColor(corners[5], Color.White); // line 6 vertices[10] = new VertexPositionColor(corners[5], Color.White); vertices[11] = new VertexPositionColor(corners[6], Color.White); // line 7 vertices[12] = new VertexPositionColor(corners[6], Color.White); vertices[13] = new VertexPositionColor(corners[7], Color.White); // line 8 vertices[14] = new VertexPositionColor(corners[7], Color.White); vertices[15] = new VertexPositionColor(corners[4], Color.White); // line 9 vertices[16] = new VertexPositionColor(corners[0], Color.White); vertices[17] = new VertexPositionColor(corners[4], Color.White); // line 10 vertices[18] = new VertexPositionColor(corners[1], Color.White); vertices[19] = new VertexPositionColor(corners[5], Color.White); // line 11 vertices[20] = new VertexPositionColor(corners[2], Color.White); vertices[21] = new VertexPositionColor(corners[6], Color.White); // line 12 vertices[22] = new VertexPositionColor(corners[3], Color.White); vertices[23] = new VertexPositionColor(corners[7], Color.White); GraphicsDevice device = graphics.GraphicsDevice; // TODO : device.RenderState.CullMode = CullMode.None; // get world space position for drawing the frustum Position3 worldSpacePosition = sphere.Position; // translate to camera space by subtracting the camera position, scale by planet scale Position3 cameraSpacePosition = (worldSpacePosition - mainCamera.Position) * sphere.Scale; // create world matrix Matrix cameraSpaceMatrix = sphere.ScaleMatrix * Matrix.CreateTranslation(cameraSpacePosition.AsVector3); testEffect.Projection = mainCamera.ProjectionMatrix; testEffect.World = cameraSpaceMatrix; testEffect.View = mainCamera.ViewMatrix; //testEffect.EnableDefaultLighting(); testEffect.VertexColorEnabled = true; testEffect.CurrentTechnique.Passes[0].Apply(); GraphicsDevice.DrawUserPrimitives(PrimitiveType.LineList, vertices, 0, 12); }
/// <summary> /// Renders the bounding frustum for debugging purposes. /// </summary> /// <param name="frustum">The frustum to render.</param> /// <param name="graphicsDevice">The graphics device to use when rendering.</param> /// <param name="view">The current view matrix.</param> /// <param name="projection">The current projection matrix.</param> /// <param name="color">The color to use drawing the lines of the frustum.</param> public static void Render( BoundingFrustum frustum, GraphicsDevice graphicsDevice, Matrix view, Matrix projection, Color color) { if (effect == null) { effect = new BasicEffect(graphicsDevice, null); effect.VertexColorEnabled = true; effect.LightingEnabled = false; vertDecl = new VertexDeclaration(graphicsDevice, VertexPositionColor.VertexElements); } Vector3[] corners = frustum.GetCorners(); for (int i = 0; i < 8; i++) { verts[i].Position = corners[i]; verts[i].Color = color; } graphicsDevice.VertexDeclaration = vertDecl; effect.View = view; effect.Projection = projection; effect.Begin(); foreach (EffectPass pass in effect.CurrentTechnique.Passes) { pass.Begin(); graphicsDevice.DrawUserIndexedPrimitives( PrimitiveType.LineList, verts, 0, 8, indices, 0, indices.Length / 2); pass.End(); } effect.End(); }
public static void DrawBoundingFrustum(BoundingFrustum boundingFrustum, Color color) { boundingFrustum.GetCorners(m_frustumCorners); DrawCorners(m_frustumCorners, color); }
// run from another thread during update to calc the view projection matrix and do culling public void CalcCascades(ref Matrix view, ref Matrix projection, float nearClip, float farClip, float clipRange) { // Get the corners of the frustum BoundingFrustum cameraFrustum = new BoundingFrustum(view * projection); cameraFrustum.GetCorners(frustumCornersWS); Matrix eyeTransform = view; Vector3.Transform(frustumCornersWS, ref eyeTransform, frustumCornersVS); // Get camera near and far values float near = nearClip; float far = MathHelper.Min(farClip, ShadowDistance); splitDepthsTmp[0] = near; splitDepthsTmp[NUM_CASCADES] = far; // Compute cascade split depths for (int i = 1; i < splitDepthsTmp.Length - 1; i++) splitDepthsTmp[i] = near + (far - near) * (float)Math.Pow((i / (float)NUM_CASCADES), 2); //splitDepthsTmp[1] = 35.0f; for (int i = 0; i < NUM_CASCADES; i++) { // Convert the split depths to percent of view range, so we can pass them to shader later LightClipPlanes[i].X = (splitDepthsTmp[i] - nearClip) / clipRange; LightClipPlanes[i].Y = (splitDepthsTmp[i + 1] - nearClip) / clipRange; // Create the view projection matrix for this cascade LightViewProjectionMatrices[i] = CreateLightViewProjectionMatrix(directionToSun, far, splitDepthsTmp[i], splitDepthsTmp[i + 1], i); LightFrustums[i] = new Engine.Utilities.FastFrustum(ref LightViewProjectionMatrices[i]); } Renderer.Instance.DoShadowsCulling(LightFrustums); }
public void DrawFrustum( BoundingFrustum frustum, Color color ) { var points = frustum.GetCorners(); DrawLine( points[0], points[1], color ); DrawLine( points[1], points[2], color ); DrawLine( points[2], points[3], color ); DrawLine( points[3], points[0], color ); DrawLine( points[4], points[5], color ); DrawLine( points[5], points[6], color ); DrawLine( points[6], points[7], color ); DrawLine( points[7], points[4], color ); DrawLine( points[0], points[4], color ); DrawLine( points[1], points[5], color ); DrawLine( points[2], points[6], color ); DrawLine( points[3], points[7], color ); }
// Return true if bounding sphere of this object intersects bounding frustum public virtual bool GetIntersectionWithBoundingFrustum(ref BoundingFrustum boundingFrustum) { ContainmentType con = boundingFrustum.Contains(WorldAABB); if (con == ContainmentType.Contains) { return true; } if (con == ContainmentType.Intersects) { if (ModelLod0 == null) { return true; } for (int v = 0; v < ModelLod0.GetVerticesCount(); v++) { Vector3 vet = ModelLod0.GetVertex(v); Vector3 transformed = Vector3.Transform(vet, WorldMatrix); ContainmentType con2 = boundingFrustum.Contains(transformed); if (con2 != ContainmentType.Disjoint) { return true; } } boundingFrustum.GetCorners(m_frustumIntersectionCorners); MyLine l0 = new MyLine(m_frustumIntersectionCorners[0], m_frustumIntersectionCorners[4], true); MyLine l1 = new MyLine(m_frustumIntersectionCorners[1], m_frustumIntersectionCorners[5], true); MyLine l2 = new MyLine(m_frustumIntersectionCorners[2], m_frustumIntersectionCorners[6], true); MyLine l3 = new MyLine(m_frustumIntersectionCorners[3], m_frustumIntersectionCorners[7], true); var prun = ModelLod0.GetTrianglePruningStructure(); if (prun.GetIntersectionWithLine(this, ref l0).HasValue || prun.GetIntersectionWithLine(this, ref l1).HasValue || prun.GetIntersectionWithLine(this, ref l2).HasValue || prun.GetIntersectionWithLine(this, ref l3).HasValue) { return true; } } return false; }
/// <summary> /// Renders the outline of a bounding frustum /// </summary> /// <param name="frustum">Bounding frustum to render</param> /// <param name="color">Color of the frustum lines</param> public void DrawWireFrustum(BoundingFrustum frustum, Color color) { DrawWireShape(frustum.GetCorners(), cubeIndices, color); }
public static void AddBoundingFrustum(BoundingFrustum frustum, Color color, float life) { DebugShape shape = GetShapeForLines(12, life); frustum.GetCorners(Corners); shape.Vertices[0] = new VertexPositionColor(Corners[0], color); shape.Vertices[1] = new VertexPositionColor(Corners[1], color); shape.Vertices[2] = new VertexPositionColor(Corners[1], color); shape.Vertices[3] = new VertexPositionColor(Corners[2], color); shape.Vertices[4] = new VertexPositionColor(Corners[2], color); shape.Vertices[5] = new VertexPositionColor(Corners[3], color); shape.Vertices[6] = new VertexPositionColor(Corners[3], color); shape.Vertices[7] = new VertexPositionColor(Corners[0], color); shape.Vertices[8] = new VertexPositionColor(Corners[4], color); shape.Vertices[9] = new VertexPositionColor(Corners[5], color); shape.Vertices[10] = new VertexPositionColor(Corners[5], color); shape.Vertices[11] = new VertexPositionColor(Corners[6], color); shape.Vertices[12] = new VertexPositionColor(Corners[6], color); shape.Vertices[13] = new VertexPositionColor(Corners[7], color); shape.Vertices[14] = new VertexPositionColor(Corners[7], color); shape.Vertices[15] = new VertexPositionColor(Corners[4], color); shape.Vertices[16] = new VertexPositionColor(Corners[0], color); shape.Vertices[17] = new VertexPositionColor(Corners[4], color); shape.Vertices[18] = new VertexPositionColor(Corners[1], color); shape.Vertices[19] = new VertexPositionColor(Corners[5], color); shape.Vertices[20] = new VertexPositionColor(Corners[2], color); shape.Vertices[21] = new VertexPositionColor(Corners[6], color); shape.Vertices[22] = new VertexPositionColor(Corners[3], color); shape.Vertices[23] = new VertexPositionColor(Corners[7], color); }
public static void Intersects(ref BoundingFrustum boundingFrustum, ref Plane plane, out PlaneIntersectionType result) { var corners = boundingFrustum.GetCorners(); result = plane.Intersects(corners[0]); for (int i = 1; i < corners.Length; i++) if (plane.Intersects(corners[i]) != result) result = PlaneIntersectionType.Intersecting; }