/// <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; } }
/// <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); } }
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); } }