public OctreeNode(FAABox bounds, CollisionGroupNode node, List <CollisionTriangle> triangles) { Triangles = triangles; Bounds = bounds; Group = node; Children = new OctreeNode[8]; SortTriangles(); }
private FAABox[] SubdivideBounds() { Vector3 center = Bounds.Min + Bounds.Extents; FAABox[] new_octants = new FAABox[8]; new_octants[0] = new FAABox(Bounds.Min, center); new_octants[1] = new FAABox(new Vector3(center.X, Bounds.Min.Y, Bounds.Min.Z), new Vector3(Bounds.Max.X, center.Y, center.Z)); new_octants[2] = new FAABox(new Vector3(Bounds.Min.X, center.Y, Bounds.Min.Z), new Vector3(center.X, Bounds.Max.Y, center.Z)); new_octants[3] = new FAABox(new Vector3(center.X, center.Y, Bounds.Min.Z), new Vector3(Bounds.Max.X, Bounds.Max.Y, center.Z)); new_octants[4] = new FAABox(new Vector3(Bounds.Min.X, center.Y, center.Z), new Vector3(center.X, Bounds.Max.Y, Bounds.Max.Z)); new_octants[5] = new FAABox(center, Bounds.Max); new_octants[6] = new FAABox(new Vector3(Bounds.Min.X, Bounds.Min.Y, center.Z), new Vector3(center.X, center.Y, Bounds.Max.Z)); new_octants[7] = new FAABox(new Vector3(center.X, Bounds.Min.Y, center.Z), new Vector3(Bounds.Max.X, center.Y, Bounds.Max.Z)); return(new_octants); }
public void CalculateBounds() { float min_x = float.MaxValue; float min_y = float.MaxValue; float min_z = float.MaxValue; float max_x = float.MinValue; float max_y = float.MinValue; float max_z = float.MinValue; foreach (CollisionTriangle t in Triangles) { for (int i = 0; i < 3; i++) { if (min_x > t.Vertices[i].X) { min_x = t.Vertices[i].X; } if (min_y > t.Vertices[i].Y) { min_y = t.Vertices[i].Y; } if (min_z > t.Vertices[i].Z) { min_z = t.Vertices[i].Z; } if (max_x < t.Vertices[i].X) { max_x = t.Vertices[i].X; } if (max_y < t.Vertices[i].Y) { max_y = t.Vertices[i].Y; } if (max_z < t.Vertices[i].Z) { max_z = t.Vertices[i].Z; } } } Bounds = new FAABox(new Vector3(min_x, min_y, min_z), new Vector3(max_x, max_y, max_z)); }
private void CalculateModelBounds() { // Iterate through the shapes and calculate a bounding box which encompasses all of them. Vector3 min = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue); Vector3 max = new Vector3(float.MinValue, float.MinValue, float.MinValue); foreach (var shape in SHP1Tag.Shapes) { Vector3 sMin = shape.BoundingBox.Min; Vector3 sMax = shape.BoundingBox.Max; if (sMin.X < min.X) { min.X = sMin.X; } if (sMax.X > max.X) { max.X = sMax.X; } if (sMin.Y < min.Y) { min.Y = sMin.Y; } if (sMax.Y > max.Y) { max.Y = sMax.Y; } if (sMin.Z < min.Z) { min.Z = sMin.Z; } if (sMax.Z > max.Z) { max.Z = sMax.Z; } } BoundingBox = new FAABox(min, max); BoundingSphere = new FSphere(BoundingBox.Center, BoundingBox.Max.Length); }
private void CalculateAABB() { Vector3 min = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue); Vector3 max = new Vector3(float.MinValue, float.MinValue, float.MinValue); for (int i = 0; i < m_Vertices.Length; i++) { if (m_Vertices[i].X < min.X) { min.X = m_Vertices[i].X; } if (m_Vertices[i].Y < min.Y) { min.Y = m_Vertices[i].Y; } if (m_Vertices[i].Z < min.Z) { min.Z = m_Vertices[i].Z; } if (m_Vertices[i].X > max.X) { max.X = m_Vertices[i].X; } if (m_Vertices[i].Y > max.Y) { max.Y = m_Vertices[i].Y; } if (m_Vertices[i].Z > max.Z) { max.Z = m_Vertices[i].Z; } } m_aaBox = new FAABox(min, max); }
private void LoadTagDataFromFile(EndianBinaryReader reader, int tagCount, bool dumpTextures, bool dumpShaders) { for (int i = 0; i < tagCount; i++) { long tagStart = reader.BaseStream.Position; string tagName = reader.ReadString(4); int tagSize = reader.ReadInt32(); switch (tagName) { // INFO - Vertex Count, Scene Hierarchy case "INF1": INF1Tag = new INF1(); INF1Tag.LoadINF1FromStream(reader, tagStart); break; // VERTEX - Stores vertex arrays for pos/normal/color0/tex0 etc. // Contains VertexAttributes which describe how the data is stored/laid out. case "VTX1": VTX1Tag = new VTX1(); VTX1Tag.LoadVTX1FromStream(reader, tagStart, tagSize); break; // ENVELOPES - Defines vertex weights for skinning case "EVP1": EVP1Tag = new EVP1(); EVP1Tag.LoadEVP1FromStream(reader, tagStart); break; // DRAW (Skeletal Animation Data) - Stores which matrices (?) are weighted, and which are used directly case "DRW1": DRW1Tag = new DRW1(); DRW1Tag.LoadDRW1FromStream(reader, tagStart); break; // JOINTS - Stores the skeletal joints (position, rotation, scale, etc...) case "JNT1": JNT1Tag = new JNT1(); JNT1Tag.LoadJNT1FromStream(reader, tagStart); JNT1Tag.CalculateParentJointsForSkeleton(INF1Tag.HierarchyRoot); break; // SHAPE - Face/Triangle information for model. case "SHP1": SHP1Tag = new SHP1(); SHP1Tag.ReadSHP1FromStream(reader, tagStart, VTX1Tag.VertexData); break; // MATERIAL - Stores materials (which describes how textures, etc. are drawn) case "MAT3": MAT3Tag = new MAT3(); MAT3Tag.LoadMAT3FromStream(reader, tagStart); break; // TEXTURES - Stores binary texture images. case "TEX1": TEX1Tag = new TEX1(); TEX1Tag.LoadTEX1FromStream(reader, tagStart, dumpTextures); break; // MODEL - Seems to be bypass commands for Materials and invokes GX registers directly. case "MDL3": break; } // Skip the stream reader to the start of the next tag since it gets moved around during loading. reader.BaseStream.Position = tagStart + tagSize; } // To generate shaders we need to know which vertex attributes need to be enabled for the shader. However, // the shader has no knowledge in our book as to what attributes are enabled. Theoretically we could enable // them on the fly as something requested it, but that'd involve more code that I don't want to do right now. // To resolve, we iterate once through the hierarchy to see which mesh is called after a material and bind the // vertex descriptions. Material dummyMat = null; AssignVertexAttributesToMaterialsRecursive(INF1Tag.HierarchyRoot, ref dummyMat, MAT3Tag); // Now that the vertex attributes are assigned to the materials, generate a shader from the data. GenerateShadersForMaterials(MAT3Tag, dumpShaders); // Iterate through the shapes and calculate a bounding box which encompasses all of them. Vector3 min = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue); Vector3 max = new Vector3(float.MinValue, float.MinValue, float.MinValue); foreach (var shape in SHP1Tag.Shapes) { Vector3 sMin = shape.BoundingBox.Min; Vector3 sMax = shape.BoundingBox.Max; if (sMin.X < min.X) { min.X = sMin.X; } if (sMax.X > max.X) { max.X = sMax.X; } if (sMin.Y < min.Y) { min.Y = sMin.Y; } if (sMax.Y > max.Y) { max.Y = sMax.Y; } if (sMin.Z < min.Z) { min.Z = sMin.Z; } if (sMax.Z > max.Z) { max.Z = sMax.Z; } } BoundingBox = new FAABox(min, max); BoundingSphere = new FSphere(BoundingBox.Center, BoundingBox.Max.Length); }
public void Load(EndianBinaryReader stream) { int vertexCount = stream.ReadInt32(); int vertexOffset = stream.ReadInt32(); int triangleCount = stream.ReadInt32(); int triangleOffset = stream.ReadInt32(); Vector3[] meshVerts = new Vector3[vertexCount]; stream.BaseStream.Position = vertexOffset; Vector3 min = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue); Vector3 max = new Vector3(float.MinValue, float.MinValue, float.MinValue); for (int i = 0; i < vertexCount; i++) { meshVerts[i] = new Vector3(stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle()); if (meshVerts[i].X < min.X) { min.X = meshVerts[i].X; } if (meshVerts[i].Y < min.Y) { min.Y = meshVerts[i].Y; } if (meshVerts[i].Z < min.Z) { min.Z = meshVerts[i].Z; } if (meshVerts[i].X > max.X) { max.X = meshVerts[i].X; } if (meshVerts[i].Y > max.Y) { max.Y = meshVerts[i].Y; } if (meshVerts[i].Z > max.Z) { max.Z = meshVerts[i].Z; } } m_aaBox = new FAABox(min, max); int[] triangleIndexes = new int[triangleCount * 3]; stream.BaseStream.Position = triangleOffset; for (int i = 0; i < triangleCount; i++) { triangleIndexes[(i * 3) + 0] = stream.ReadUInt16(); triangleIndexes[(i * 3) + 1] = stream.ReadUInt16(); triangleIndexes[(i * 3) + 2] = stream.ReadUInt16(); stream.Skip(4); } GL.GenBuffers(1, out m_vbo); GL.GenBuffers(1, out m_ebo); // Upload Verts GL.BindBuffer(BufferTarget.ArrayBuffer, m_vbo); GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(12 * meshVerts.Length), meshVerts, BufferUsageHint.StaticDraw); // Upload eBO GL.BindBuffer(BufferTarget.ElementArrayBuffer, m_ebo); GL.BufferData(BufferTarget.ElementArrayBuffer, (IntPtr)(4 * triangleIndexes.Length), triangleIndexes, BufferUsageHint.StaticDraw); m_triangleCount = triangleCount; }