/// <summary>
        /// Determines if the ray intersects with the given bounding box.
        /// </summary>
        /// <param name="boundingBox">Bounding box to check intersection with</param>
        /// <returns></returns>
        public bool IntersectsWith(FAABox boundingBox, out float intersectionDist)
        {
            Vector3 dirFrac = new Vector3(1.0f / Direction.X, 1.0f / Direction.Y, 1.0f / Direction.Z);

            float t1 = (boundingBox.Min.X - Origin.X) * dirFrac.X;
            float t2 = (boundingBox.Max.X - Origin.X) * dirFrac.X;
            float t3 = (boundingBox.Min.Y - Origin.Y) * dirFrac.Y;
            float t4 = (boundingBox.Max.Y - Origin.Y) * dirFrac.Y;
            float t5 = (boundingBox.Min.Z - Origin.Z) * dirFrac.Z;
            float t6 = (boundingBox.Max.Z - Origin.Z) * dirFrac.Z;

            float tmin = Math.Max(Math.Max(Math.Min(t1, t2), Math.Min(t3, t4)), Math.Min(t5, t6));
            float tmax = Math.Min(Math.Min(Math.Max(t1, t2), Math.Max(t3, t4)), Math.Max(t5, t6));

            if (tmax < 0)
            {
                intersectionDist = tmax;
                return false;
            }

            if (tmin > tmax)
            {
                intersectionDist = tmax;
                return false;
            }

            else
            {
                intersectionDist = tmin;
                return true;
            }
        }
예제 #2
0
        /// <summary>
        /// Determines if the ray intersects with the given bounding box.
        /// </summary>
        /// <param name="boundingBox">Bounding box to check intersection with</param>
        /// <returns></returns>
        public bool IntersectsWith(FAABox boundingBox, out float intersectionDist)
        {
            Vector3 dirFrac = new Vector3(1.0f / Direction.X, 1.0f / Direction.Y, 1.0f / Direction.Z);

            float t1 = (boundingBox.Min.X - Origin.X) * dirFrac.X;
            float t2 = (boundingBox.Max.X - Origin.X) * dirFrac.X;
            float t3 = (boundingBox.Min.Y - Origin.Y) * dirFrac.Y;
            float t4 = (boundingBox.Max.Y - Origin.Y) * dirFrac.Y;
            float t5 = (boundingBox.Min.Z - Origin.Z) * dirFrac.Z;
            float t6 = (boundingBox.Max.Z - Origin.Z) * dirFrac.Z;

            float tmin = Math.Max(Math.Max(Math.Min(t1, t2), Math.Min(t3, t4)), Math.Min(t5, t6));
            float tmax = Math.Min(Math.Min(Math.Max(t1, t2), Math.Max(t3, t4)), Math.Max(t5, t6));

            if (tmax < 0)
            {
                intersectionDist = tmax;
                return(false);
            }

            if (tmin > tmax)
            {
                intersectionDist = tmax;
                return(false);
            }

            else
            {
                intersectionDist = tmin;
                return(true);
            }
        }
예제 #3
0
        public override FAABox GetBoundingBox()
        {
            FAABox modelABB = m_objRender != null?m_objRender.GetAABB() : m_actorMesh.BoundingBox;

            modelABB.ScaleBy(Transform.LocalScale);

            return(new FAABox(modelABB.Min + Transform.Position, modelABB.Max + Transform.Position));
        }
        public Halfspace ContainsAAB(FAABox box)
        {
            Vector3[] corners       = box.GetVertices();
            int       totalPointsIn = 0;

            // Test all 8 corners of the AABox against the 6 planes of the frustum. If all
            // points are behind 1 specific plane, then we're fully out. If all points are in
            // then the AABox is fully within the frustum.
            for (int p = 0; p < 6; p++)
            {
                int inCount = 8;
                int ptIn    = 1;

                for (int j = 0; j < 8; j++)
                {
                    // Test the point against the planes
                    if (m_planes[p].SideOfPlane(corners[j]) == Halfspace.Negative)
                    {
                        ptIn = 0;
                        inCount--;
                    }
                }

                // If all points of the AABox were outside of this particular plane p,
                // we know the AABox lies entirely outside and can early out.
                if (inCount == 0)
                {
                    return(Halfspace.Negative);
                }

                // Check if they're all in the correct side of the plane
                totalPointsIn += ptIn;
            }

            // If the totalPointsIn is 6, then they're inside the view.
            if (totalPointsIn == 6)
            {
                return(Halfspace.Positive);
            }

            // Otherwise, they're partially in.
            return(Halfspace.Intersect);
        }
        public SimpleObjRenderer(Obj file)
        {
            m_vertexVBO   = GL.GenBuffer();
            m_indexVBO    = GL.GenBuffer();
            m_texcoordVBO = file.TexCoords.Count > 0 ? GL.GenBuffer() : -1;
            m_normalVBO   = file.Normals.Count > 0 ? GL.GenBuffer() : -1;
            m_textureVBO  = file.Material.DiffuseTexture != null?GL.GenTexture() : -1;

            m_unhighlightedShader = new Shader("UnlitTexture");
            m_unhighlightedShader.CompileSource(File.ReadAllText("resources/shaders/UnlitTexture.vert"), ShaderType.VertexShader);
            m_unhighlightedShader.CompileSource(File.ReadAllText("resources/shaders/UnlitTexture.frag"), ShaderType.FragmentShader);
            m_unhighlightedShader.LinkShader();

            m_highlightedShader = new Shader("TransformGizmoHighlight");
            m_highlightedShader.CompileSource(File.ReadAllText("resources/shaders/UnlitTexture.vert"), ShaderType.VertexShader);
            m_highlightedShader.CompileSource(File.ReadAllText("resources/shaders/TransformGizmoHighlight.frag"), ShaderType.FragmentShader);
            m_highlightedShader.LinkShader();

            // Generate an array of all vertices instead of the compact form OBJ comes as.
            Vector3[] positions = null;
            Vector2[] texcoords = null;
            Vector3[] normals   = null;
            int[]     triangles = new int[file.Faces.Count * 3];
            m_triangleCount = file.Faces.Count;

            List <UniqueVertex> uniqueVerts = new List <UniqueVertex>();

            for (int i = 0; i < file.Faces.Count; i++)
            {
                Obj.ObjFace face = file.Faces[i];
                for (int k = 0; k < 3; k++)
                {
                    var vertex = new UniqueVertex();
                    vertex.Position = file.Vertices[face.Positions[k]];
                    if (face.TexCoords != null)
                    {
                        vertex.TexCoord = file.TexCoords[face.TexCoords[k]];
                    }
                    if (face.Normals != null)
                    {
                        vertex.Normal = file.Normals[face.Normals[k]];
                    }


                    int vertIndex = uniqueVerts.IndexOf(vertex);
                    if (vertIndex < 0)
                    {
                        uniqueVerts.Add(vertex);
                        vertIndex = uniqueVerts.Count - 1;
                    }

                    triangles[(i * 3) + k] = vertIndex;
                }
            }

            // Copy the data out of the interlaced buffers.
            positions = new Vector3[uniqueVerts.Count];
            texcoords = file.TexCoords.Count > 0 ? new Vector2[uniqueVerts.Count] : null;
            normals   = file.Normals.Count > 0 ? new Vector3[uniqueVerts.Count] : null;

            m_boundingBox = new FAABox();
            for (int i = 0; i < uniqueVerts.Count; i++)
            {
                positions[i] = uniqueVerts[i].Position;
                m_boundingBox.Encapsulate(positions[i]);

                if (texcoords != null)
                {
                    texcoords[i] = new Vector2(uniqueVerts[i].TexCoord.X, 1 - uniqueVerts[i].TexCoord.Y);
                }
                if (normals != null)
                {
                    normals[i] = uniqueVerts[i].Normal;
                }
            }

            // Positions
            GL.BindBuffer(BufferTarget.ArrayBuffer, m_vertexVBO);
            GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(12 * positions.Length), positions, BufferUsageHint.StaticDraw);

            // Upload Indexes
            GL.BindBuffer(BufferTarget.ElementArrayBuffer, m_indexVBO);
            GL.BufferData(BufferTarget.ElementArrayBuffer, (IntPtr)(4 * triangles.Length), triangles, BufferUsageHint.StaticDraw);

            // Texcoords
            if (m_texcoordVBO >= 0)
            {
                GL.BindBuffer(BufferTarget.ArrayBuffer, m_texcoordVBO);
                GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(8 * texcoords.Length), texcoords, BufferUsageHint.StaticDraw);
            }

            // Normals
            if (m_normalVBO >= 0)
            {
                GL.BindBuffer(BufferTarget.ArrayBuffer, m_normalVBO);
                GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(12 * normals.Length), normals, BufferUsageHint.StaticDraw);
            }

            // Texture
            if (m_textureVBO >= 0)
            {
                Obj.ObjMaterial mat = file.Material;

                GL.BindTexture(TextureTarget.Texture2D, m_textureVBO);
                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Repeat);
                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Repeat);
                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Nearest);
                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Nearest);

                // Black/white checkerboard
                float[] pixels = new[]
                {
                    0.0f, 0.0f, 0.0f, 255.0f, 255.0f, 255.0f,
                    255.0f, 255.0f, 255.0f, 0.0f, 0.0f, 0.0f
                };
                //GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgb, 2, 2, 0, PixelFormat.Rgb, PixelType.Float, pixels);

                System.Drawing.Imaging.BitmapData bmpData = mat.DiffuseTexture.LockBits(new System.Drawing.Rectangle(0, 0, mat.DiffuseTexture.Width, mat.DiffuseTexture.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
                GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, mat.DiffuseTexture.Width, mat.DiffuseTexture.Height, 0, PixelFormat.Bgra, PixelType.UnsignedByte, bmpData.Scan0);
                mat.DiffuseTexture.UnlockBits(bmpData);
            }
        }
        public Halfspace ContainsAAB(FAABox box)
        {
            Vector3[] corners = box.GetVertices();
            int totalPointsIn = 0;

            // Test all 8 corners of the AABox against the 6 planes of the frustum. If all
            // points are behind 1 specific plane, then we're fully out. If all points are in
            // then the AABox is fully within the frustum.
            for (int p = 0; p < 6; p++)
            {
                int inCount = 8;
                int ptIn = 1;

                for (int j = 0; j < 8; j++)
                {
                    // Test the point against the planes
                    if (m_planes[p].SideOfPlane(corners[j]) == Halfspace.Negative)
                    {
                        ptIn = 0;
                        inCount--;
                    }
                }

                // If all points of the AABox were outside of this particular plane p,
                // we know the AABox lies entirely outside and can early out.
                if (inCount == 0)
                    return Halfspace.Negative;

                // Check if they're all in the correct side of the plane
                totalPointsIn += ptIn;
            }

            // If the totalPointsIn is 6, then they're inside the view.
            if (totalPointsIn == 6)
                return Halfspace.Positive;

            // Otherwise, they're partially in.
            return Halfspace.Intersect;
        }
        public SimpleObjRenderer(Obj file)
        {
            m_vertexVBO = GL.GenBuffer();
            m_indexVBO = GL.GenBuffer();
            m_texcoordVBO = file.TexCoords.Count > 0 ? GL.GenBuffer() : -1;
            m_normalVBO = file.Normals.Count > 0 ? GL.GenBuffer() : -1;
            m_textureVBO = file.Material.DiffuseTexture != null ? GL.GenTexture() : -1;

            m_unhighlightedShader = new Shader("UnlitTexture");
            m_unhighlightedShader.CompileSource(File.ReadAllText("resources/shaders/UnlitTexture.vert"), ShaderType.VertexShader);
            m_unhighlightedShader.CompileSource(File.ReadAllText("resources/shaders/UnlitTexture.frag"), ShaderType.FragmentShader);
            m_unhighlightedShader.LinkShader();

            m_highlightedShader = new Shader("TransformGizmoHighlight");
            m_highlightedShader.CompileSource(File.ReadAllText("resources/shaders/UnlitTexture.vert"), ShaderType.VertexShader);
            m_highlightedShader.CompileSource(File.ReadAllText("resources/shaders/TransformGizmoHighlight.frag"), ShaderType.FragmentShader);
            m_highlightedShader.LinkShader();

            // Generate an array of all vertices instead of the compact form OBJ comes as.
            Vector3[] positions = null;
            Vector2[] texcoords = null;
            Vector3[] normals = null;
            int[] triangles = new int[file.Faces.Count * 3];
            m_triangleCount = file.Faces.Count;

            List<UniqueVertex> uniqueVerts = new List<UniqueVertex>();

            for (int i = 0; i < file.Faces.Count; i++)
            {
                Obj.ObjFace face = file.Faces[i];
                for (int k = 0; k < 3; k++)
                {
                    var vertex = new UniqueVertex();
                    vertex.Position = file.Vertices[face.Positions[k]];
                    if (face.TexCoords != null) vertex.TexCoord = file.TexCoords[face.TexCoords[k]];
                    if (face.Normals != null) vertex.Normal = file.Normals[face.Normals[k]];


                    int vertIndex = uniqueVerts.IndexOf(vertex);
                    if (vertIndex < 0)
                    {
                        uniqueVerts.Add(vertex);
                        vertIndex = uniqueVerts.Count - 1;
                    }

                    triangles[(i * 3) + k] = vertIndex;
                }
            }

            // Copy the data out of the interlaced buffers.
            positions = new Vector3[uniqueVerts.Count];
            texcoords = file.TexCoords.Count > 0 ? new Vector2[uniqueVerts.Count] : null;
            normals = file.Normals.Count > 0 ? new Vector3[uniqueVerts.Count] : null;

            m_boundingBox = new FAABox();
            for (int i = 0; i < uniqueVerts.Count; i++)
            {
                positions[i] = uniqueVerts[i].Position;
                m_boundingBox.Encapsulate(positions[i]);

                if (texcoords != null) texcoords[i] = new Vector2(uniqueVerts[i].TexCoord.X, 1 - uniqueVerts[i].TexCoord.Y);
                if (normals != null) normals[i] = uniqueVerts[i].Normal;
            }

            // Positions
            GL.BindBuffer(BufferTarget.ArrayBuffer, m_vertexVBO);
            GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(12 * positions.Length), positions, BufferUsageHint.StaticDraw);

            // Upload Indexes
            GL.BindBuffer(BufferTarget.ElementArrayBuffer, m_indexVBO);
            GL.BufferData(BufferTarget.ElementArrayBuffer, (IntPtr)(4 * triangles.Length), triangles, BufferUsageHint.StaticDraw);

            // Texcoords
            if (m_texcoordVBO >= 0)
            {
                GL.BindBuffer(BufferTarget.ArrayBuffer, m_texcoordVBO);
                GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(8 * texcoords.Length), texcoords, BufferUsageHint.StaticDraw);
            }

            // Normals
            if (m_normalVBO >= 0)
            {
                GL.BindBuffer(BufferTarget.ArrayBuffer, m_normalVBO);
                GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(12 * normals.Length), normals, BufferUsageHint.StaticDraw);
            }

            // Texture
            if (m_textureVBO >= 0)
            {
                Obj.ObjMaterial mat = file.Material;

                GL.BindTexture(TextureTarget.Texture2D, m_textureVBO);
                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Repeat);
                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Repeat);
                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Nearest);
                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Nearest);

                // Black/white checkerboard
                float[] pixels = new[]
                {
                    0.0f, 0.0f, 0.0f,   255.0f, 255.0f, 255.0f,
                    255.0f, 255.0f, 255.0f,   0.0f, 0.0f, 0.0f
                };
                //GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgb, 2, 2, 0, PixelFormat.Rgb, PixelType.Float, pixels);

                System.Drawing.Imaging.BitmapData bmpData = mat.DiffuseTexture.LockBits(new System.Drawing.Rectangle(0, 0, mat.DiffuseTexture.Width, mat.DiffuseTexture.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
                GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, mat.DiffuseTexture.Width, mat.DiffuseTexture.Height, 0, PixelFormat.Bgra, PixelType.UnsignedByte, bmpData.Scan0);
                mat.DiffuseTexture.UnlockBits(bmpData);
            }
        }