示例#1
0
        public void Constructor_MinMax()
        {
            var actual = new AABBf(new float3(0, 0, 0), new float3(1, 1, 1));

            Assert.Equal(new float3(0, 0, 0), actual.min);
            Assert.Equal(new float3(1, 1, 1), actual.max);
        }
示例#2
0
文件: Camera.cs 项目: LksWllmnn/Fusee
        private void UserSideFrustumCulling(IList <SceneNode> nodeChildren, Frustum frustum)
        {
            foreach (SceneNode node in nodeChildren)
            {
                if (node.Name == "Frustum" || node.Name.Contains("Cam"))
                {
                    continue;
                }

                Mesh mesh = node.GetComponent <Mesh>();
                if (mesh != null)
                {
                    //We only perform the test for meshes that do have a calculated - non-zero sized - bounding box.
                    if (mesh.BoundingBox.Size != float3.Zero)
                    {
                        AABBf worldSpaceBoundingBox = node.GetComponent <Transform>().Matrix() * mesh.BoundingBox;
                        if (!worldSpaceBoundingBox.InsideOrIntersectingFrustum(frustum))
                        {
                            mesh.Active = false;
                        }
                        else
                        {
                            mesh.Active = true;
                        }
                    }
                }

                if (node.Children.Count != 0)
                {
                    UserSideFrustumCulling(node.Children, frustum);
                }
            }
        }
示例#3
0
        public void Size_Is1()
        {
            var aabbf  = new AABBf(new float3(0, 0, 0), new float3(1, 1, 1));
            var actual = aabbf.Size;

            Assert.Equal(new float3(1, 1, 1), actual);
        }
示例#4
0
        public void Center_Is1()
        {
            var aabbf = new AABBf(new float3(0, 0, 0), new float3(2, 2, 2));

            var actual = aabbf.Center;

            Assert.Equal(new float3(1, 1, 1), actual);
        }
示例#5
0
        public static IEnumerable <object[]> GetUnion()
        {
            var a = new AABBf(new float3(0, 0, 0), new float3(1, 1, 1));
            var b = new AABBf(new float3(1, 1, 1), new float3(2, 2, 2));

            yield return(new object[] { a, b, new AABBf(new float3(0, 0, 0), new float3(2, 2, 2)) });

            yield return(new object[] { b, a, new AABBf(new float3(0, 0, 0), new float3(2, 2, 2)) });
        }
示例#6
0
        public void IntersectsAABBf_IsTrue()
        {
            var aabb  = new AABBf(new float3(0, 0, -1), new float3(6, 1, 1));
            var plane = new PlaneF()
            {
                A = 1, B = 0, C = 0, D = 5
            };

            Assert.True(plane.Intersects(aabb));
        }
示例#7
0
        public void InsideOrIntersectingOBBf_IsFalse()
        {
            var aabb  = new AABBf(new float3(6, 0, 0), new float3(7, 1, 1));
            var plane = new PlaneF()
            {
                A = 1, B = 0, C = 0, D = 5
            };

            Assert.False(plane.InsideOrIntersecting(aabb));
        }
        public void ComputeCoverage(RenderableMesh mesh, AABBf meshBounds, out long sideCoverage, out long topCoverage)
        {
            float longestSide = Math.Max(Math.Max(meshBounds.MaxX - meshBounds.MinX, meshBounds.MaxY - meshBounds.MinY), meshBounds.MaxZ - meshBounds.MinZ);
            float farPlane = longestSide * 2.0f;

            float x = (meshBounds.MinX + meshBounds.MaxX) / 2.0f;
            float y = meshBounds.MinY;
            float z = (meshBounds.MinZ + meshBounds.MaxZ) / 2.0f;
            Vector3 origin = new Vector3(x, y, z);
            Vector3 up = Vector3.UnitY;
            Vector3 look = -Vector3.UnitX;

            for (int i = 0; i < m_occlusionQueries.Length; i++)
            {
                Matrix4 orbit = Matrix4.CreateRotationY(MathHelper.DegreesToRadians((365 / 64.0f) * i));

                Matrix4 projection = Matrix4.CreatePerspectiveFieldOfView(MathHelper.DegreesToRadians(90), 1.0f, 0.1f, farPlane);
                Matrix4 view = Matrix4.LookAt(origin + Vector3.Transform(new Vector3(longestSide, 0, 0), orbit), origin, Vector3.TransformNormal(up, orbit));

                RenderView(view, projection, mesh, m_occlusionQueries[i]);

                //Bitmap bmp = GLEx.BitmapColorBuffer(m_pixelWidth, m_pixelHeight);
                //bmp.Save("C:\\test_" + i + ".bmp");
            }

            // Gather all the occlusion queries we performed
            long[] m_occlusionQueryResults = new long[64];
            for (int i = 0; i < m_occlusionQueries.Length; i++)
            {
                int ready = 0;
                while (ready == 0)
                {
                    GL.GetQueryObject(m_occlusionQueries[i], GetQueryObjectParam.QueryResultAvailable, out ready);
                }

                GL.GetQueryObject(m_occlusionQueries[i], GetQueryObjectParam.QueryResult, out m_occlusionQueryResults[i]);
            }

            // Reset the current frame buffer.
            GL.Ext.BindFramebuffer(FramebufferTarget.FramebufferExt, 0);

            long totalSidePixels = 0;
            long totalTopPixels = 0;
            for (int i = 0; i < m_occlusionQueries.Length; i++)
            {
                totalSidePixels += m_occlusionQueryResults[i];
            }

            sideCoverage = totalSidePixels;
            topCoverage = totalTopPixels;
        }
示例#9
0
        public void OnMesh(Mesh mesh)
        {
            var box = _state.ModelView * mesh.BoundingBox;

            if (!_boxValid)
            {
                _result   = box;
                _boxValid = true;
            }
            else
            {
                _result = AABBf.Union(_result, box);
            }
        }
示例#10
0
        public static IEnumerable <object[]> GetTransform()
        {
            var a = new AABBf(new float3(0, 0, 0), new float3(1, 1, 1));

            var xRot = new float4x4(1, 0, 0, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1);
            var yRot = new float4x4(0, 0, 1, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 1);
            var zRot = new float4x4(0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);

            yield return(new object[] { xRot, a, new AABBf(new float3(0, -1, 0), new float3(1, 0, 1)) });

            yield return(new object[] { yRot, a, new AABBf(new float3(0, 0, -1), new float3(1, 1, 0)) });

            yield return(new object[] { zRot, a, new AABBf(new float3(-1, 0, 0), new float3(0, 1, 1)) });
        }
示例#11
0
        public void OnMesh(MeshComponent meshComponent)
        {
            AABBf box = _state.ModelView * meshComponent.BoundingBox;

            if (!_boxValid)
            {
                _result   = box;
                _boxValid = true;
            }
            else
            {
                _result = AABBf.Union((AABBf)_result, box);
            }
        }
示例#12
0
        /// <summary>
        /// Creates a orthographic projection matrix from a bounding box. This matrix is named "crop" matrix in the literature.
        /// </summary>
        /// <param name="aabb">The bounding box.</param>
        /// <returns></returns>
        public static float4x4 CreateOrthographic(AABBf aabb)
        {
            aabb.min.z = 0;
            var scaleX  = 2.0f / (aabb.max.x - aabb.min.x);
            var scaleY  = 2.0f / (aabb.max.y - aabb.min.y);
            var offsetX = -0.5f * (aabb.max.x + aabb.min.x) * scaleX;
            var offsetY = -0.5f * (aabb.max.y + aabb.min.y) * scaleY;
            var scaleZ  = 1.0f / (aabb.max.z - aabb.min.z);
            var offsetZ = -aabb.min.z * scaleZ;

            return(new float4x4(scaleX, 0, 0, offsetX,
                                0, scaleY, 0, offsetY,
                                0, 0, scaleZ, offsetZ,
                                0, 0, 0, 1));
        }
示例#13
0
        /// <summary>
        /// Calculates the axis aligned bounding box in light space.
        /// </summary>
        /// <param name="lightView">The view matrix of the light.</param>
        /// <param name="frustumCorners">The world space frustum corners of a cascade.</param>
        /// <returns></returns>
        private static AABBf FrustumAABBLightSpace(float4x4 lightView, float3[] frustumCorners)
        {
            for (int i = 0; i < frustumCorners.Length; i++)
            {
                var corner = frustumCorners[i];
                corner            = lightView * corner; //light space frustum corners
                frustumCorners[i] = corner;
            }

            var lightSpaceFrustumAABB = new AABBf(frustumCorners[0], frustumCorners[0]);

            foreach (var p in frustumCorners)
            {
                lightSpaceFrustumAABB |= p;
            }

            return(lightSpaceFrustumAABB);
        }
示例#14
0
        public static Mesh BuildMesh(AABBf aabb, Vector3 delta_p, List<AABBi> boxList)
        {
            Mesh mesh = BuildMesh(boxList);

            Vector4 aabb_min = new Vector4(aabb.MinX, aabb.MinY, aabb.MinZ, 0);
            Vector4 delta_p4 = new Vector4(delta_p, 1);
            for (int i = 0; i < mesh.Vertices.Length; i++)
            {
                mesh.Vertices[i] = aabb_min + Vector4.Multiply(mesh.Vertices[i], delta_p4);
            }

            return mesh;
        }
        public VoxelizingOctreeCell(VoxelizingOctree tree, VoxelizingOctreeCell root, Vector3 center, float length, int level)
        {
            Tree = tree;
            Root = root;
            Center = center;
            Length = length;
            Level = level;

            float half_length = length / 2.0f;

            Bounds = new AABBf();
            Bounds.MinX = center.X - half_length;
            Bounds.MinY = center.Y - half_length;
            Bounds.MinZ = center.Z - half_length;
            Bounds.MaxX = center.X + half_length;
            Bounds.MaxY = center.Y + half_length;
            Bounds.MaxZ = center.Z + half_length;

            VoxelBounds = new AABBi(
                (int)Math.Round((Bounds.MinX - tree.VoxelBounds.MinX) / tree.SmallestVoxelSideLength, MidpointRounding.AwayFromZero),
                (int)Math.Round((Bounds.MinY - tree.VoxelBounds.MinY) / tree.SmallestVoxelSideLength, MidpointRounding.AwayFromZero),
                (int)Math.Round((Bounds.MinZ - tree.VoxelBounds.MinZ) / tree.SmallestVoxelSideLength, MidpointRounding.AwayFromZero),
                (int)Math.Round((Bounds.MaxX - tree.VoxelBounds.MinX) / tree.SmallestVoxelSideLength, MidpointRounding.AwayFromZero),
                (int)Math.Round((Bounds.MaxY - tree.VoxelBounds.MinY) / tree.SmallestVoxelSideLength, MidpointRounding.AwayFromZero),
                (int)Math.Round((Bounds.MaxZ - tree.VoxelBounds.MinZ) / tree.SmallestVoxelSideLength, MidpointRounding.AwayFromZero));
        }
示例#16
0
        // computes the OBB for this set of points relative to this transform matrix.
        public static void ComputeOBB(Vector3[] points, ref Matrix4 matrix, out float[] sides)
        {
            AABBf aabb = new AABBf();

            Matrix4 matrixInverse = matrix;
            matrixInverse.Invert();
            for (int i = 0; i < points.Length; i++)
            {
                Vector3 t = Vector3.Transform(points[i], matrixInverse); // inverse rotate translate
                aabb.Add(t);
            }

            sides = new float[3];
            sides[0] = aabb.MaxX - aabb.MinX;
            sides[1] = aabb.MaxY - aabb.MinY;
            sides[2] = aabb.MaxZ - aabb.MinZ;

            Vector3 center = new Vector3();
            center.X = sides[0] * 0.5f + aabb.MinX;
            center.Y = sides[1] * 0.5f + aabb.MinY;
            center.Z = sides[2] * 0.5f + aabb.MinZ;

            Vector3 ocenter = Vector3.Transform(center, matrix);

            matrix = matrix * Matrix4.CreateTranslation(ocenter);
        }
示例#17
0
        public static void ComputeBestFitOBB(Vector3[] points, out float[] sides, out Matrix4 matrix, FitStrategy strategy)
        {
            matrix = Matrix4.Identity;
            AABBf aabb = new AABBf();
            for (int i = 0; i < points.Length; i++)
                aabb.Add(points[i]);

            float avolume = (aabb.MaxX - aabb.MinX) * (aabb.MaxY - aabb.MinY) * (aabb.MaxZ - aabb.MinZ);

            Plane plane;
            ComputeBestFitPlane(points, out plane);

            plane.ToMatrix(ref matrix);
            ComputeOBB(points, ref matrix, out sides);

            Matrix4 refmatrix = new Matrix4();
            refmatrix = matrix;

            float volume = sides[0] * sides[1] * sides[2];

            float stepSize = 5;
            switch (strategy)
            {
                case BestFit.FitStrategy.FS_FAST_FIT:
                    stepSize = 13; // 15 degree increments
                    break;
                case BestFit.FitStrategy.FS_MEDIUM_FIT:
                    stepSize = 7; // 10 degree increments
                    break;
                case BestFit.FitStrategy.FS_SLOW_FIT:
                    stepSize = 3; // 5 degree increments
                    break;
                case BestFit.FitStrategy.FS_SLOWEST_FIT:
                    stepSize = 1; // 1 degree increments
                    break;
            }

            Quaternion quat = new Quaternion();
            for (float a = 0; a < 180; a += stepSize)
            {
                Matrix4 temp;
                Matrix4.CreateRotationY(MathHelper.DegreesToRadians(a), out temp);
                QuaternionEx.CreateFromMatrix(ref temp, ref quat);

                Matrix4 pmatrix;
                Matrix4.Mult(ref temp, ref refmatrix, out pmatrix);

                float[] psides;
                ComputeOBB(points, ref pmatrix, out psides);
                float v = psides[0] * psides[1] * psides[2];
                if (v < volume)
                {
                    volume = v;
                    matrix = pmatrix;
                    sides[0] = psides[0];
                    sides[1] = psides[1];
                    sides[2] = psides[2];
                }
            }

            if (avolume < volume)
            {
                matrix = Matrix4.CreateTranslation(
                    (aabb.MinX + aabb.MaxX) * 0.5f,
                    (aabb.MinY + aabb.MaxY) * 0.5f,
                    (aabb.MinZ + aabb.MaxZ) * 0.5f);
                sides[0] = aabb.MaxX - aabb.MinX;
                sides[1] = aabb.MaxY - aabb.MinY;
                sides[2] = aabb.MaxZ - aabb.MinZ;
            }
        }
示例#18
0
 public void InsideOrIntersectingAABBf_IsTrue(PlaneF plane, AABBf aabb)
 {
     Assert.True(plane.InsideOrIntersecting(aabb));
 }
示例#19
0
 public void IntersectsAABBf_IsFalse(PlaneF plane, AABBf aabb)
 {
     Assert.False(plane.Intersects(aabb));
 }
        private void CreateUniformBoundingBox(List<Triangle> triangles, out AABBf originalBounds, out AABBf voxelBounds, out Vector3 center, out float length)
        {
            originalBounds = Triangle.CreateBoundingBox(triangles);
            Vector3 size = new Vector3(originalBounds.MaxX - originalBounds.MinX, originalBounds.MaxY - originalBounds.MinY, originalBounds.MaxZ - originalBounds.MinZ);
            float maxSize = Math.Max(size.X, Math.Max(size.Y, size.Z));

            center = new Vector3(
                originalBounds.MinX + (size.X / 2.0f),
                originalBounds.MinY + (size.Y / 2.0f),
                originalBounds.MinZ + (size.Z / 2.0f));

            length = maxSize;

            voxelBounds = new AABBf();
            voxelBounds.MinX = center.X - (length * 0.5f);
            voxelBounds.MinY = center.Y - (length * 0.5f);
            voxelBounds.MinZ = center.Z - (length * 0.5f);
            voxelBounds.MaxX = center.X + (length * 0.5f);
            voxelBounds.MaxY = center.Y + (length * 0.5f);
            voxelBounds.MaxZ = center.Z + (length * 0.5f);
        }
示例#21
0
        public void Transform_IsTransform(float4x4 m, AABBf box, AABBf expected)
        {
            var actual = m * box;

            Assert.Equal(expected, actual);
        }
示例#22
0
        public void Union_IsUnion(AABBf a, AABBf b, AABBf expected)
        {
            var actual = AABBf.Union(a, b);

            Assert.Equal(expected, actual);
        }