public void GenerateConnections() { for (int i = 0; i < vertSize; i++) { VertexStruct vertex = vertices[i]; int ConnectionOffset = vertex.Unk2 - 1; if (ConnectionOffset != -1) { bool bEndOfArray = false; ConnectionStruct CurConnection = connections[ConnectionOffset]; while (CurConnection.NodeID == i && !bEndOfArray) { VertexStruct ConnectedVertex = vertices[CurConnection.ConnectedNodeID]; vertex.OutgoingConnections.Add(ConnectedVertex); ConnectedVertex.IncomingConnections.Add(vertex); ConnectionOffset++; if (ConnectionOffset >= connections.Length) { bEndOfArray = true; } else { CurConnection = connections[ConnectionOffset]; } } } } }
public void ReplaceVertex(ref NativeHeap <VertexStruct> vertexHeap, VertexStruct vold, ref VertexStruct vNew, NativeArray <int> idToHeapIndex) { int idx; for (idx = 0; idx < 3; idx++) { if (vold.ID == vertexs[idx]) { for (int i = 0; i < 3; i++) { if (i == idx) { continue; } VertexStruct v = vertexHeap[idToHeapIndex[vertexs[i]]]; v.RemoveAtVertex(vold); if (!v.Contains(vNew.ID)) { v.AddNeighborVertex(vNew.ID); } if (!vNew.Contains(vertexs[i])) { vNew.AddNeighborVertex(vertexs[i]); } vertexHeap[idToHeapIndex[vertexs[i]]] = v; } vertexs[idx] = vNew.ID; break; } } faceIndex[idx] = vNew.currentFaceCount; vNew.AddFaceTriangle(Index); ComputeNormal(vertexHeap, vold, idToHeapIndex); }
public VertexBuffer(VertexStruct[] vertices, ushort[] indices) { if(vertices == null) throw new ArgumentException("Vertices may not be null"); this.numVerts = vertices.Length; this.numIndices = indices.Length; int[] handles = new int[2]; GL.GenBuffers(2, handles); this.vertexHandle = handles[0]; this.indexHandle = handles[1]; GL.BindBuffer(BufferTarget.ArrayBuffer, this.vertexHandle); GL.BindBuffer(BufferTarget.ElementArrayBuffer, this.indexHandle); int size = numVerts * VertexStruct.strideElements * VertexStruct.elementSize; unsafe { fixed (float* pVertices = &vertices[0].x) { GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)size, (IntPtr)pVertices, bufferUsage); } fixed (ushort* pIndices = &indices[0]) { GL.BufferData(BufferTarget.ElementArrayBuffer, (IntPtr)(numIndices * 2), (IntPtr)pIndices, bufferUsage); } } GL.BindBuffer(BufferTarget.ArrayBuffer, 0); GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0); }
/// <summary> /// 临时缓存的三角形集合 /// </summary> unsafe void Collapse(VertexStruct u, int v, NativeArray <StructRelevanceSphere> aRelevanceSpheres) { if (v == -1) //v=9779 坍塌目标 { u.Destructor(); //析构掉 return; } int i; //u临近的顶点 把临近顶点添加到tmpVertices队列里面 tmpVerticesList.Clear(); for (i = 0; i < u.currentNeightCount; i++) //u是一个顶点 { int nb = u.pneighbors.Get <int>(i); if (nb != u.ID) { tmpVerticesList.Add(nb); } } //Debug tempTriangleList.Clear(); for (i = 0; i < u.currentFaceCount; i++) { if (GetTriangles(u.pfaces.Get <int>(i)).HasVertex(v)) //获取到三角形 { tempTriangleList.Add(u.pfaces.Get <int>(i)); } } // Delete triangles on edge uv for (i = tempTriangleList.Length - 1; i >= 0; i--) { TriangleStruct t = GetTriangles(tempTriangleList[i]); //获取t的三个顶点信息 t.Destructor(ref m_VertexHeap, ref triangles, ref u, idToHeapIndex); triangles[tempTriangleList[i]] = t; } // Update remaining triangles to have v instead of u //缓存vNew VertexStruct vNewVertex = m_VertexHeap[idToHeapIndex[v]]; for (i = u.currentFaceCount - 1; i >= 0; i--) { TriangleStruct t = GetTriangles(u.pfaces.Get <int>(i)); t.ReplaceVertex(ref m_VertexHeap, u, ref vNewVertex, idToHeapIndex); triangles[u.pfaces.Get <int>(i)] = t; //更新 } //更新VNewIndex m_VertexHeap[idToHeapIndex[v]] = vNewVertex; u.Destructor(); // Recompute the edge collapse costs for neighboring vertices for (i = 0; i < tmpVerticesList.Length; i++) { VertexStruct st = m_VertexHeap[idToHeapIndex[tmpVerticesList[i]]]; ComputeEdgeCostAtVertex(ref st, aRelevanceSpheres); m_VertexHeap[idToHeapIndex[tmpVerticesList[i]]] = st; m_VertexHeap.ModifyValue(st.HeapIndex, st); } }
public void ReadFromFile(BinaryReader reader) { unk0 = reader.ReadInt32(); fileIDHPD = reader.ReadInt32(); unk3HPD = reader.ReadInt32(); bitFlagsHPD = reader.ReadInt32(); vertSize = reader.ReadInt32(); triSize = reader.ReadInt32(); //writer.WriteLine(string.Format("{0}, ) StreamWriter writer = File.CreateText("NAV_AI_OBJ_DATA_" + fileIDHPD + ".txt"); writer.WriteLine(string.Format("{0} {1} {2} {3}", unk0, fileIDHPD, unk3HPD, bitFlagsHPD)); //List<string> data = new List<string>(); List <Vector3> Points = new List <Vector3>(); vertices = new VertexStruct[vertSize]; for (int i = 0; i < vertSize; i++) { VertexStruct vertex = new VertexStruct(); vertex.Unk7 = reader.ReadUInt32() & 0x7FFFFFFF; vertex.Position = Vector3Extenders.ReadFromFile(reader); Vector3 pos = vertex.Position; float y = pos.Y; pos.Y = -pos.Z; pos.Z = y; vertex.Position = pos; //writer.WriteLine(vertex.Position); vertex.Unk0 = reader.ReadSingle(); vertex.Unk1 = reader.ReadSingle(); vertex.Unk2 = reader.ReadInt32(); vertex.Unk3 = reader.ReadInt16(); vertex.Unk4 = reader.ReadInt16(); vertex.Unk5 = reader.ReadInt32(); vertex.Unk6 = reader.ReadInt32(); vertices[i] = vertex; Points.Add(vertex.Position); } writer.WriteLine(""); connections = new ConnectionStruct[triSize]; for (int i = 0; i < triSize; i++) { ConnectionStruct connection = new ConnectionStruct(); connection.Flags = reader.ReadUInt32() & 0x7FFFFFFF; connection.NodeID = reader.ReadUInt32() & 0x7FFFFFFF; connection.ConnectedNodeID = reader.ReadUInt32() & 0x7FFFFFFF; connections[i] = connection; //writer.WriteLine(string.Format("{0} {1} {2}", connection.Flags, connection.NodeID, connection.ConnectedNodeID)); } //Read KynogonRuntimeMesh runtimeMesh = new KynogonRuntimeMesh(); runtimeMesh.ReadFromFile(reader, writer); }
public VertexStruct[] GetVertexStructTrigger() { VertexStruct[] arrayData = new VertexStruct[vertsTrigger.Count]; for (int i = 0; i < vertsTrigger.Count; i++) { arrayData[i].vertice = vertsTrigger[i]; } return(arrayData); }
public Group(string name, Material material, VertexStruct[] vertices, ushort[] indices) { this.name = name; this.material = material; this.vertices = vertices; this.indices = indices; this.vertexBuffer = new VertexBuffer(vertices, indices); }
float ComputeEdgeCollapseCost(VertexStruct u, VertexStruct v, float fRelevanceBias) { bool bUseEdgeLength = UseEdgeLength; bool bUseCurvature = UseCurvature; float borderCurvature = fBorderCurvature; int i; float fEdgeLength = bUseEdgeLength ? (Vector3.Magnitude(v.Position - u.Position) / OriginalMeshSize) : 1.0f; float fCurvature = 0.001f; if (fEdgeLength < float.Epsilon) { return(borderCurvature * (1 - Vector3.Dot(u.Normal, v.Normal) + 2 * Vector3.Distance(u.UV, v.UV))); } else { List <TriangleStruct> sides = new List <TriangleStruct>(); for (i = 0; i < u.currentFaceCount; i++) { TriangleStruct ut = GetTriangles(u.pfaces.Get <int>(i)); if (HasVertex(ut, v.ID)) { sides.Add(ut); } } if (bUseCurvature) { for (i = 0; i < u.currentFaceCount; i++) { float fMinCurv = 1.0f; for (int j = 0; j < sides.Count; j++) { float dotprod = Vector3.Dot(GetTriangles(u.pfaces.Get <int>(i)).Normal, sides[j].Normal); fMinCurv = Mathf.Min(fMinCurv, (1.0f - dotprod) / 2.0f); } fCurvature = Mathf.Max(fCurvature, fMinCurv); } } bool isBorder = u.IsBorder(triangles); if (isBorder && sides.Count > 1) { fCurvature = 1.0f; } if (borderCurvature > 1 && isBorder) { fCurvature = borderCurvature; } } fCurvature += fRelevanceBias; return(fEdgeLength * fCurvature); }
public VertexStruct[] GetVertexStruct() { VertexStruct[] arrayData = new VertexStruct[verts.Count]; for (int i = 0; i < verts.Count; i++) { arrayData[i].vertice = verts[i]; arrayData[i].uv = uvs[i]; arrayData[i].color = colors[i]; } return(arrayData); }
/// <summary> /// 查找Vertex在全局堆中的位置 /// </summary> /// <param name="vertexHeap">Heap堆</param> /// <param name="id">顶点ID</param> /// <returns></returns> int FindIndexVertex(NativeHeap <VertexStruct> vertexHeap, int id) { for (int i = 0; i < vertexHeap.Length; i++) { VertexStruct vertex = vertexHeap[i]; if (vertex.ID == id) { return(i); } } return(-1); }
public void ReadFromFile(BinaryReader reader) { unk0 = reader.ReadInt32(); unk2 = reader.ReadInt32(); unk3 = reader.ReadInt32(); unk4 = reader.ReadInt32(); vertSize = reader.ReadInt32(); triSize = reader.ReadInt32(); vertices = new VertexStruct[vertSize]; for (int i = 0; i < vertSize; i++) { VertexStruct vertex = new VertexStruct(); vertex.unk7 = reader.ReadInt32(); vertex.position = Vector3Extenders.ReadFromFile(reader); float pos = vertex.position.Y; //f**k the third var thing vertex.position.Y = vertex.position.Z; vertex.position.Z = pos; vertex.unk0 = reader.ReadSingle(); vertex.unk1 = reader.ReadSingle(); vertex.unk2 = reader.ReadInt32(); vertex.unk3 = reader.ReadInt16(); vertex.unk4 = reader.ReadInt16(); vertex.unk5 = reader.ReadInt32(); vertex.unk6 = reader.ReadInt32(); vertices[i] = vertex; } //unk6 = reader.ReadInt32(); //unk7 = reader.ReadInt32(); //unk8 = reader.ReadInt16(); //unk9 = reader.ReadInt16(); //int x = 2; //indices = new uint[(triSize - 1) * 3]; //for (int i = 0; i < (triSize - 1) * 3; i++) //{ // if (x == 0) // { // indices[i] = reader.ReadUInt32(); // x = 2; // } // else // { // indices[i] = (uint)reader.ReadInt24(); // reader.ReadByte(); // x--; // } //} //TODO:: }
public void Execute() { //提取顶部元素 int vertexNum = m_VertexHeap.Length; while (vertexNum-- > 0) { VertexStruct mn = m_VertexHeap.ExtractTop(); //Debug.Log("mn的Position为" + mn.Position.ToString() + "mn的ID" + mn.ID + "m_VertexHeap Length" + m_VertexHeap.Length + "坍塌目标" + mn.collapse // + "mnHeapIndex" + mn.HeapIndex + "mn的object" + mn.m_fObjDist); m_aVertexPermutation[mn.ID] = vertexNum; m_aVertexMap[mn.ID] = mn.collapse != -1 ? mn.collapse : -1; Collapse(mn, mn.collapse, Spheres); //坍塌目标的结构如何改写 } }
/// <summary> /// Checks collision between box A and the supplied coordinates. If they collide, return true. /// </summary> protected bool CheckCollision(VertexStruct PlayerPosition, BoxStruct Box) { if ( (PlayerPosition.PositionX >= Box.MinX && PlayerPosition.PositionX <= Box.MaxX) && (PlayerPosition.PositionY >= Box.MinY && PlayerPosition.PositionY <= Box.MaxY) && (PlayerPosition.PositionZ >= Box.MinZ && PlayerPosition.PositionZ <= Box.MaxZ) ) { return(true); } else { return(false); } }
private void InternalInit(Vector3[] vrtxs, Vector4[] colors, Vector2[] uvs, int[] indxs, int[] indxsWithAdj, Vector3[] normals) { Vector3 normal; Verticies = vrtxs; Indexes = indxs; IndexesWithAdj = indxsWithAdj; Colors = colors; UVs = uvs; Normals = normals; int n = vrtxs.Length; m_Points = new VertexStruct[n]; SVPoints = new PositionsColorsStruct[n]; m_BoundingMinimum = Vector3.One * float.MaxValue; m_BoundingMaximum = Vector3.One * float.MinValue; for (int i = 0; i < n; i++) { normal = (normals == null ? Vector3.Zero : normals[i]); CalculateTangentBinormal(normal, out Vector3 tangent, out Vector3 binormal); m_Points[i] = new VertexStruct() { Position = new Vector4(vrtxs[i], 1), Color = (colors == null ? Vector4.One : colors[i]), UV0 = new Vector4(uvs == null ? Vector2.Zero : uvs[i], 0, 0), UV1 = Vector4.Zero, Normal = new Vector4(normal, 0), Tangent = new Vector4(tangent, 0), }; m_BoundingMinimum = Vector3.Min(m_BoundingMinimum, vrtxs[i]); m_BoundingMaximum = Vector3.Max(m_BoundingMaximum, vrtxs[i]); SVPoints[i] = new PositionsColorsStruct() { Pos = m_Points[i].Position, Color = m_Points[i].Color, }; } }
/// <summary> /// Returns the player position for collision checking. /// </summary> /// <returns></returns> protected VertexStruct GetPlayerPosition() { // Get Player Position. VertexStruct PlayerPosition = new VertexStruct(); // Get XYZ int Character_Pointer = Program.Sonic_Heroes_Process.ReadMemory <int>((IntPtr)SonicHeroesVariables.Characters_Addresses.CurrentPlayerControlledCharacter_Pointer, 4); int Character_Memory_Position_X = Character_Pointer + (int)SonicHeroesVariables.Characters_Addresses_Offsets.XPosition; int Character_Memory_Position_Y = Character_Pointer + (int)SonicHeroesVariables.Characters_Addresses_Offsets.YPosition; int Character_Memory_Position_Z = Character_Pointer + (int)SonicHeroesVariables.Characters_Addresses_Offsets.ZPosition; // Gets the character's position coordinates. PlayerPosition.PositionX = Program.Sonic_Heroes_Process.ReadMemory <float>((IntPtr)Character_Memory_Position_X, 4); PlayerPosition.PositionY = Program.Sonic_Heroes_Process.ReadMemory <float>((IntPtr)Character_Memory_Position_Y, 4); PlayerPosition.PositionZ = Program.Sonic_Heroes_Process.ReadMemory <float>((IntPtr)Character_Memory_Position_Z, 4); // Return Player Position. return(PlayerPosition); }
void ComputeEdgeCostAtVertex(ref VertexStruct v, NativeArray <StructRelevanceSphere> aRelevanceSpheres) { if (v.currentNeightCount == 0) { v.collapse = -1; //-1表示没有下一个坍塌目标 v.m_fObjDist = -0.01f; return; } v.m_fObjDist = MAX_VERTEX_COLLAPSE_COST; v.collapse = -1; float fRelevanceBias = 0.0f; if (aRelevanceSpheres.Length != 0) { for (int nSphere = 0; nSphere < aRelevanceSpheres.Length; nSphere++) { Matrix4x4 mtxSphere = aRelevanceSpheres[nSphere].Transformation; Vector3 v3World = v.PositionWorld; Vector3 v3Local = mtxSphere.inverse.MultiplyPoint(v3World); if (v3Local.magnitude <= 0.5f) { // Inside fRelevanceBias = aRelevanceSpheres[nSphere].Relevance; } } } for (int i = 0; i < v.currentNeightCount; i++) { float dist = ComputeEdgeCollapseCost(v, m_VertexHeap[idToHeapIndex[v.pneighbors.Get <int>(i)]], fRelevanceBias); if (v.collapse == -1 || dist < v.m_fObjDist) //-1表示没有坍塌目标的存在 { v.collapse = v.pneighbors.Get <int>(i); v.m_fObjDist = dist; } } }
/// <summary> /// Checks for collision with all boxes and if true, invokes the necessary delegates. /// </summary> public virtual void HandleCollision_OnFrame(WindowRenderTarget nulltarget) { // Get Player Postion. VertexStruct PlayerPosition = GetPlayerPosition(); // Iterate over all frame delegates. for (int x = 0; x < FrameDelegates.Count; x++) { // Check Collision for Each Set of Delegates. for (int y = 0; y < FrameDelegates[x].collisionBoxes.Count; y++) { // Checks Collision bool PlayerInsideBox = CheckCollision(PlayerPosition, FrameDelegates[x].collisionBoxes[y]); // Invoke if collision set. if (PlayerInsideBox) { FrameDelegates[x].collisionDelegate?.Invoke(); break; } } } }
public void ComputeNormal(NativeHeap <VertexStruct> vertexHeap, VertexStruct vertex, NativeArray <int> idToHeapIndex) { Vector3 v0 = Vector3.zero; Vector3 v1 = Vector3.zero; Vector3 v2 = Vector3.zero; if (vertexs[0] == vertex.ID) { v0 = vertex.Position; } else { v0 = vertexHeap[idToHeapIndex[vertexs[0]]].Position; } if (vertexs[1] == vertex.ID) { v1 = vertex.Position; } else { v1 = vertexHeap[idToHeapIndex[vertexs[1]]].Position; } if (vertexs[2] == vertex.ID) { v2 = vertex.Position; } else { v2 = vertexHeap[idToHeapIndex[vertexs[2]]].Position; } Normal = Vector3.Cross((v1 - v0), (v2 - v1)); if (Normal.magnitude == 0.0f) { return; } Normal = Normal / Normal.magnitude; }
public static void RenderTriangles(int[] Indices, ref VertexStruct[] Vertices) { GL.Begin(BeginMode.Triangles); foreach (int ThisIndex in Indices) { if (Convert.ToBoolean(NGraphics.GeometryMode & (UInt32)GeometryMode.TEXTURE_GEN) == true) { Vertices[ThisIndex].Normals.Normalize(); TexGen(ref Vertices[ThisIndex].TexCoord, Vertices[ThisIndex].Normals); if (EnableCombiner == true) { GL.Arb.MultiTexCoord2(TextureUnit.Texture0, Vertices[ThisIndex].TexCoord.X, Vertices[ThisIndex].TexCoord.Y); GL.Arb.MultiTexCoord2(TextureUnit.Texture1, Vertices[ThisIndex].TexCoord.X, Vertices[ThisIndex].TexCoord.Y); } else { GL.TexCoord2(Vertices[ThisIndex].TexCoord.X, Vertices[ThisIndex].TexCoord.Y); } } else { double S0 = Vertices[ThisIndex].TexCoord.X * (NGraphics.Textures[0].ScaleS * NGraphics.Textures[0].ShiftScaleS) / 32.0f / NGraphics.Textures[0].RealWidth; double T0 = Vertices[ThisIndex].TexCoord.Y * (NGraphics.Textures[0].ScaleT * NGraphics.Textures[0].ShiftScaleT) / 32.0f / NGraphics.Textures[0].RealHeight; double S1 = Vertices[ThisIndex].TexCoord.X * (NGraphics.Textures[1].ScaleS * NGraphics.Textures[1].ShiftScaleS) / 32.0f / NGraphics.Textures[1].RealWidth; double T1 = Vertices[ThisIndex].TexCoord.Y * (NGraphics.Textures[1].ScaleT * NGraphics.Textures[1].ShiftScaleT) / 32.0f / NGraphics.Textures[1].RealHeight; if (EnableCombiner == true) { GL.Arb.MultiTexCoord2(TextureUnit.Texture0, S0, T0); GL.Arb.MultiTexCoord2(TextureUnit.Texture1, S1, T1); } else { GL.TexCoord2(S0, T0); } } if (ParseMode != 2) { if (Convert.ToBoolean(NGraphics.GeometryMode & (UInt32)GeometryMode.LIGHTING) == false) { GL.Color4(Vertices[ThisIndex].Colors.R, Vertices[ThisIndex].Colors.G, Vertices[ThisIndex].Colors.B, Vertices[ThisIndex].Colors.A); } GL.Normal3(Vertices[ThisIndex].Normals.X, Vertices[ThisIndex].Normals.Y, Vertices[ThisIndex].Normals.Z); } GL.Vertex3(Vertices[ThisIndex].Position.X, Vertices[ThisIndex].Position.Y, Vertices[ThisIndex].Position.Z); } GL.End(); }
public void ReadFromFile(BinaryReader reader) { StreamWriter writer = File.CreateText("NAV_AI_OBJ_DATA.txt"); unk0 = reader.ReadInt32(); unk2 = reader.ReadInt32(); unk3 = reader.ReadInt32(); unk4 = reader.ReadInt32(); vertSize = reader.ReadInt32(); triSize = reader.ReadInt32(); //writer.WriteLine(string.Format("{0}, ) //List<string> data = new List<string>(); vertices = new VertexStruct[vertSize]; for (int i = 0; i < vertSize; i++) { VertexStruct vertex = new VertexStruct(); vertex.unk7 = reader.ReadUInt32() & 0x7FFFFFFF; vertex.position = Vector3Extenders.ReadFromFile(reader); //float pos = vertex.position.Y; //vertex.position.Y = vertex.position.Z; //vertex.position.Z = pos; vertex.unk0 = reader.ReadSingle(); vertex.unk1 = reader.ReadSingle(); vertex.unk2 = reader.ReadInt32(); vertex.unk3 = reader.ReadInt16(); vertex.unk4 = reader.ReadInt16(); vertex.unk5 = reader.ReadInt32(); vertex.unk6 = reader.ReadInt32(); //data.Add(string.Format("v {0} {1} {2}", vertex.position.X, vertex.position.Z, vertex.position.Y)); vertices[i] = vertex; } //data.Add(""); //data.Add("g mesh"); indices = new uint[triSize * 3]; int index = 0; for (int i = 0; i < triSize; i++) { indices[index] = reader.ReadUInt32() & 0x7FFFFFFF; indices[index + 1] = reader.ReadUInt32() & 0x7FFFFFFF; indices[index + 2] = reader.ReadUInt32() & 0x7FFFFFFF; //data.Add(string.Format("f {0} {1} {2}", indices[index] + 1, indices[index + 1] + 1, indices[index + 2] + 1)); index += 3; } //KynogonRuntimeMesh long mesh_pos = reader.BaseStream.Position; string magicName = new string(reader.ReadChars(18)); if (magicName != "KynogonRuntimeMesh") { throw new FormatException("Did not find KynogonRuntimeMesh"); } short mesh_unk0 = reader.ReadInt16(); int magicVersion = reader.ReadInt32(); if (magicVersion != 2) { throw new FormatException("Version did not equal 2"); } int mesh_unk1 = reader.ReadInt32(); int mesh_unk2 = reader.ReadInt32(); BoundingBox bbox = BoundingBoxExtenders.ReadFromFile(reader); int cellSizeX = reader.ReadInt32(); int cellSizeY = reader.ReadInt32(); float radius = reader.ReadSingle(); int map_unk3 = reader.ReadInt32(); int height = reader.ReadInt32(); int offset = reader.ReadInt32(); //this is a potential offset; int[] grid = new int[(cellSizeX * cellSizeY) + 1]; List <UnkSet0[]> gridSets = new List <UnkSet0[]>(); for (int i = 0; i < grid.Length; i++) { grid[i] = reader.ReadInt32(); } for (int i = 0; i < grid.Length; i++) { if (i + 1 >= grid.Length) { break; } if (i == 189) { Console.WriteLine("st"); } int numSet0 = reader.ReadInt32(); UnkSet0[] set0s = new UnkSet0[numSet0]; gridSets.Add(set0s); writer.WriteLine("-----------------------"); writer.WriteLine(string.Format("{0} {1}", i, numSet0)); writer.WriteLine(""); if (numSet0 == 0) { continue; } //NOTE: EVERY OFFSET IN UNKSET0 BEGINS FROM MESH_POS HIGHER IN THE CODE FILE. int offset0 = reader.ReadInt32(); for (int x = 0; x < numSet0; x++) { UnkSet0 set = new UnkSet0(); set.X = reader.ReadSingle(); set.Y = reader.ReadSingle(); set.Offset = reader.ReadInt32(); set0s[x] = set; } //NOTE: EVERY BLOCK OF DATA SEEMS TO START WITH 96, THIS IS HOWEVER UNCONFIRMED. for (int z = 0; z < numSet0; z++) { UnkSet0 set = set0s[z]; //NOTE: MOST OF THE OFFSETS BEGIN HERE, JUST AFTER THE SETS HAVE BEEN DEFINED ABOVE. set.cellUnk0 = reader.ReadInt32(); if (set.cellUnk0 != mesh_unk2) { throw new FormatException(); } writer.WriteLine(""); set.cellUnk1 = reader.ReadInt32(); set.cellUnk2 = reader.ReadInt32(); set.cellUnk3 = reader.ReadInt32(); set.cellUnk4 = reader.ReadSingle(); set.cellUnk5 = reader.ReadSingle(); set.cellUnk6 = reader.ReadSingle(); set.cellUnk7 = reader.ReadSingle(); set.cellUnk8 = reader.ReadInt32(); set.cellUnk9 = reader.ReadInt32(); //-1? set.cellUnk10 = reader.ReadInt32(); //1; set.cellUnk11 = reader.ReadInt32(); set.cellUnk12 = reader.ReadInt32(); //0 set.cellUnk13 = reader.ReadInt32(); //-1; set.cellUnk14 = reader.ReadInt32(); //0 set.cellUnk15 = reader.ReadInt32(); //-1; set.cellUnk16 = reader.ReadInt32(); //8; set.cellUnk17 = reader.ReadInt32(); //112; set.cellUnk18 = reader.ReadInt32(); //0; set.cellUnk19 = reader.ReadInt32(); //-1; writer.WriteLine(string.Format("Unk1: {0}", set.cellUnk1)); writer.WriteLine(string.Format("Unk2: {0}", set.cellUnk2)); writer.WriteLine(string.Format("Unk3: {0}", set.cellUnk3)); writer.WriteLine(string.Format("Unk4: {0}", set.cellUnk4)); writer.WriteLine(string.Format("Unk5: {0}", set.cellUnk5)); writer.WriteLine(string.Format("Unk6: {0}", set.cellUnk6)); writer.WriteLine(string.Format("Unk7: {0}", set.cellUnk7)); writer.WriteLine(string.Format("Unk8: {0}", set.cellUnk8)); writer.WriteLine(string.Format("Unk9: {0}", set.cellUnk9)); writer.WriteLine(string.Format("Unk10: {0}", set.cellUnk10)); writer.WriteLine(string.Format("Unk11: {0}", set.cellUnk11)); writer.WriteLine(string.Format("Unk12: {0}", set.cellUnk12)); writer.WriteLine(string.Format("Unk13: {0}", set.cellUnk13)); writer.WriteLine(string.Format("Unk14: {0}", set.cellUnk14)); writer.WriteLine(string.Format("Unk15: {0}", set.cellUnk15)); writer.WriteLine(string.Format("Unk16: {0}", set.cellUnk16)); writer.WriteLine(string.Format("Unk17: {0}", set.cellUnk17)); writer.WriteLine(string.Format("Unk18: {0}", set.cellUnk18)); writer.WriteLine(string.Format("Unk19: {0}", set.cellUnk19)); writer.WriteLine(""); //THIS BIT IS UNKNOWN, UPTO CELLUNK20 set.unk10Boxes = new Unk10DataSet[set.cellUnk10]; writer.WriteLine("Unk10 Boxes"); for (int x = 0; x < set.cellUnk10; x++) { Unk10DataSet unk10Set = new Unk10DataSet(); unk10Set.B1 = BoundingBoxExtenders.ReadFromFile(reader); unk10Set.UnkOffset = reader.ReadInt32(); unk10Set.Unk20 = reader.ReadInt32(); set.unk10Boxes[x] = unk10Set; writer.WriteLine(string.Format("Minimum: {0} ", unk10Set.B1.Minimum.ToString())); writer.WriteLine(string.Format("Maximum: {0} ", unk10Set.B1.Maximum.ToString())); writer.WriteLine(string.Format("UnkOffset: {0} ", unk10Set.UnkOffset)); writer.WriteLine(string.Format("Unk20: {0} ", unk10Set.Unk20)); writer.WriteLine(""); } //END OF CONFUSING BIT. //THIS BIT IS UNKNOWN, BUT IS CELLUNK12 set.unk12Boxes = new Unk12DataSet[set.cellUnk12]; writer.WriteLine("Unk12 Boxes"); for (int x = 0; x < set.cellUnk12; x++) { Unk12DataSet unk12Set = new Unk12DataSet(); unk12Set.B1 = BoundingBoxExtenders.ReadFromFile(reader); unk12Set.Unk01 = reader.ReadInt32(); unk12Set.Unk02 = reader.ReadInt32(); unk12Set.Unk03 = reader.ReadSingle(); unk12Set.Unk04 = reader.ReadSingle(); unk12Set.Unk05 = reader.ReadSingle(); set.unk12Boxes[x] = unk12Set; writer.WriteLine(string.Format("Minimum: {0} ", unk12Set.B1.Minimum.ToString())); writer.WriteLine(string.Format("Maximum: {0} ", unk12Set.B1.Maximum.ToString())); writer.WriteLine(string.Format("Unk01: {0} ", unk12Set.Unk01)); writer.WriteLine(string.Format("Unk02: {0} ", unk12Set.Unk02)); writer.WriteLine(string.Format("Unk03: {0} ", unk12Set.Unk03)); writer.WriteLine(string.Format("Unk04: {0} ", unk12Set.Unk04)); writer.WriteLine(string.Format("Unk05: {0} ", unk12Set.Unk05)); writer.WriteLine(""); } //END OF CONFUSING BIT. //THIS LOOPS THROUGH OFFSETS TO BBOX'S writer.WriteLine("Unk14 Offsets"); set.unk14Offsets = new int[set.cellUnk14]; for (int x = 0; x < set.cellUnk14; x++) { set.unk14Offsets[x] = reader.ReadInt32(); writer.WriteLine(string.Format("{0} ", set.unk14Offsets[x])); } //ALWAYS A 4-BYTE INTEGER WHICH DENOTES THE END OF THE BATCH if (set.cellUnk14 > 0) { set.unk14End = reader.ReadInt32(); } if (set.cellUnk14 > 0) { set.unk14Data = reader.ReadBytes(set.unk14End - set.unk14Offsets[0]); } writer.WriteLine(""); //set.unk14Boxes = new BoundingBox[set.cellUnk14]; //writer.WriteLine("Unk14 Boxes"); //for (int x = 0; x < set.cellUnk14; x++) //{ // set.unk14Boxes[x] = BoundingBoxExtenders.ReadFromFile(reader); // writer.WriteLine(string.Format("{0} ", set.unk14Boxes[x].ToString())); //} //writer.WriteLine(""); //CONTINUE ONTO THE NEXT BATCH set.unk16Offsets = new int[set.cellUnk16]; writer.WriteLine("Unk16 Offsets"); for (int x = 0; x < set.cellUnk16; x++) { set.unk16Offsets[x] = reader.ReadInt32(); writer.WriteLine(string.Format("{0} ", set.unk16Offsets[x])); } writer.WriteLine(""); //ALWAYS A 4-BYTE INTEGER WHICH DENOTES THE END OF THE BATCH if (set.cellUnk16 > 0) { set.unk16End = reader.ReadInt32(); } set.unk16Boxes = new BoundingBox[set.cellUnk16]; writer.WriteLine("Unk16 Boxes"); for (int x = 0; x < set.cellUnk16; x++) { set.unk16Boxes[x] = BoundingBoxExtenders.ReadFromFile(reader); writer.WriteLine(string.Format("{0} ", set.unk16Boxes[x])); } writer.WriteLine(""); if (set.cellUnk18 > 1) { throw new FormatException(); } set.unk18Set = new Unk18DataSet[set.cellUnk18]; writer.WriteLine("Unk18 Boxes"); for (int x = 0; x < set.cellUnk18; x++) { //THIS COULD BE AN OFFSET LIST WITH SOMEKIND OF FLOAT/ROTATION DATA Unk18DataSet dataSet = new Unk18DataSet(); dataSet.Unk0 = reader.ReadInt32(); dataSet.Unk1 = reader.ReadSingle(); dataSet.Unk2 = reader.ReadSingle(); dataSet.Unk3 = reader.ReadSingle(); //THIS COULD BE THE FINAL AREA WITH THE 12 BYTES SIMPLY PADDING OUT dataSet.Unk4 = reader.ReadInt32(); dataSet.Unk5 = reader.ReadBytes(12); //BOUNDING BOX FOR THIS KIND OF DATA. dataSet.B1 = BoundingBoxExtenders.ReadFromFile(reader); dataSet.B2 = BoundingBoxExtenders.ReadFromFile(reader); dataSet.B3 = BoundingBoxExtenders.ReadFromFile(reader); set.unk18Set[x] = dataSet; writer.WriteLine(string.Format("Unk01: {0} ", dataSet.Unk1)); writer.WriteLine(string.Format("Unk02: {0} ", dataSet.Unk2)); writer.WriteLine(string.Format("Unk03: {0} ", dataSet.Unk3)); writer.WriteLine(string.Format("Unk04: {0} ", dataSet.Unk4)); writer.WriteLine(string.Format("Unk05: {0} ", dataSet.Unk5)); writer.WriteLine(string.Format("Minimum: {0} ", dataSet.B1.Minimum.ToString())); writer.WriteLine(string.Format("Maximum: {0} ", dataSet.B1.Maximum.ToString())); writer.WriteLine(string.Format("Minimum: {0} ", dataSet.B2.Minimum.ToString())); writer.WriteLine(string.Format("Maximum: {0} ", dataSet.B2.Maximum.ToString())); writer.WriteLine(string.Format("Minimum: {0} ", dataSet.B3.Minimum.ToString())); writer.WriteLine(string.Format("Maximum: {0} ", dataSet.B3.Maximum.ToString())); } writer.WriteLine(""); set0s[z] = set; } Console.WriteLine("Completed: " + i); //byte[] data = reader.ReadBytes(size); //File.WriteAllBytes("grid_" + i + ".bin", data); } //File.WriteAllLines("model.obj", data.ToArray()); }
public void ReadFromFile(BinaryReader reader) { unk0 = reader.ReadInt32(); fileIDHPD = reader.ReadInt32(); unk3HPD = reader.ReadInt32(); bitFlagsHPD = reader.ReadInt32(); vertSize = reader.ReadInt32(); triSize = reader.ReadInt32(); List <Vector3> Points = new List <Vector3>(); vertices = new VertexStruct[vertSize]; for (int i = 0; i < vertSize; i++) { VertexStruct vertex = new VertexStruct(); vertex.Unk7 = reader.ReadUInt32(); // ^ 0x80000000 vertex.Position = Vector3Utils.ReadFromFile(reader); // TODO: Construct KynogonUtils to accomodate this Vector3 pos = vertex.Position; float y = pos.Y; pos.Y = -pos.Z; pos.Z = y; vertex.Position = pos; vertex.Unk0 = reader.ReadSingle(); vertex.Unk1 = reader.ReadSingle(); vertex.Unk2 = reader.ReadInt32(); vertex.Unk3 = reader.ReadInt16(); vertex.Unk4 = reader.ReadInt16(); vertex.Unk5 = reader.ReadInt32(); vertex.Unk6 = reader.ReadInt32(); vertices[i] = vertex; Points.Add(vertex.Position); } connections = new ConnectionStruct[triSize]; for (int i = 0; i < triSize; i++) { ConnectionStruct connection = new ConnectionStruct(); connection.Flags = reader.ReadUInt32() ^ 0x80000000; connection.NodeID = reader.ReadUInt32(); connection.ConnectedNodeID = reader.ReadUInt32(); connections[i] = connection; } //Read KynogonRuntimeMesh runtimeMesh = new KynogonRuntimeMesh(); runtimeMesh.ReadFromFile(reader); // read footer /*if (!runtimeMesh.bDEBUG_HASEXTRADATA) * { * Name = StringHelpers.ReadString(reader); * uint SizeofName = reader.ReadUInt32(); * uint Header = reader.ReadUInt32(); * }*/ Footer = reader.ReadBytes((int)(reader.BaseStream.Length - reader.BaseStream.Position)); GenerateConnections(); DumpToASCII("NAV_OBJ_DATA_" + fileIDHPD + ".txt"); }
public unsafe void Compute(List <Vertex> vertices, Mesh m_OriginalMesh, TriangleList[] triangleArray, RelevanceSphere[] aRelevanceSpheres, float[] costs, int[] collapses, int[] m_aVertexPermutation, int[] m_VertexHeap, bool bUseEdgeLength, bool bUseCurvature, float bBorderCurvature, float fOriginalMeshSize) { computerHeapJob = new ComputeHeapJob(); this.m_aVertexPermutation = m_aVertexPermutation; this.m_VertexHeap = m_VertexHeap; computerHeapJob.UseEdgeLength = bUseEdgeLength; computerHeapJob.UseCurvature = bUseCurvature; computerHeapJob.fBorderCurvature = bBorderCurvature; computerHeapJob.OriginalMeshSize = fOriginalMeshSize; computerHeapJob.m_aVertexPermutation = new NativeArray <int>(m_aVertexPermutation, Allocator.TempJob); computerHeapJob.m_aVertexMap = new NativeArray <int>(m_VertexHeap, Allocator.TempJob); computerHeapJob.idToHeapIndex = new NativeArray <int>(vertices.Count, Allocator.TempJob); computerHeapJob.tempTriangleList = new NativeList <int>(Allocator.TempJob); computerHeapJob.tmpVerticesList = new NativeList <int>(Allocator.TempJob); NativeHeap <VertexStruct> minNativeHeap = NativeHeap <VertexStruct> .CreateMinHeap(vertices.Count, Allocator.TempJob); int intSize = UnsafeUtility.SizeOf <int>(); int intAlignment = UnsafeUtility.AlignOf <int>(); //------------------------顶点数据--------------------------------- for (int i = 0; i < vertices.Count; i++) { Vertex v = vertices[i]; VertexStruct sv = new VertexStruct() { ID = v.m_nID, m_fObjDist = costs[i], Position = v.m_v3Position, collapse = collapses[i] == -1 ? -1 : vertices[collapses[i]].m_nID, isBorder = v.IsBorder() ? 1 : 0, Normal = v.Normal, UV = v.UV, }; sv.NewVertexNeighbors(v.m_listNeighbors.Count, intSize, intAlignment, Allocator.TempJob); sv.NewFaceTriangle(v.m_listFaces.Count, intSize, intAlignment, Allocator.TempJob); sv.idToHeapIndex = computerHeapJob.idToHeapIndex; for (int j = 0; j < v.m_listNeighbors.Count; j++) { sv.AddNeighborVertex(v.m_listNeighbors[j].m_nID); } for (int j = 0; j < v.m_listFaces.Count; j++) { sv.AddFaceTriangle(v.m_listFaces[j].Index); } minNativeHeap.Insert(sv); } //------------------------顶点数据结束----------------------------- //------------------------三角形数据------------------------------- List <TriangleStruct> structTrangle = new List <TriangleStruct>(); for (int n = 0; n < triangleArray.Length; n++) { List <Triangle> triangles = triangleArray[n].m_listTriangles; for (int i = 0; i < triangles.Count; i++) { Triangle t = triangles[i]; TriangleStruct st = new TriangleStruct() { Index = t.Index, Indices = (int *)UnsafeUtility.Malloc(t.Indices.Length * intAlignment, intAlignment, Allocator.TempJob), Normal = t.Normal, faceIndex = (int *)UnsafeUtility.Malloc(t.FaceIndex.Length * intSize, intAlignment, Allocator.TempJob), vertexs = t.Vertices.Length == 0 ? null : (int *)UnsafeUtility.Malloc(t.Vertices.Length * intSize, intAlignment, Allocator.TempJob), }; for (int j = 0; j < t.Indices.Length; j++) { st.Indices[j] = t.Indices[j]; } for (int j = 0; j < t.FaceIndex.Length; j++) { st.faceIndex[j] = t.FaceIndex[j]; } for (int j = 0; j < t.Vertices.Length; j++) { st.vertexs[j] = t.Vertices[j].m_nID; } structTrangle.Add(st); } } //------------------------三角形数据结束 computerHeapJob.Spheres = new NativeArray <StructRelevanceSphere>(aRelevanceSpheres.Length, Allocator.TempJob); for (int i = 0; i < aRelevanceSpheres.Length; i++) { RelevanceSphere rs = aRelevanceSpheres[i]; StructRelevanceSphere srs = new StructRelevanceSphere() { Transformation = Matrix4x4.TRS(rs.m_v3Position, rs.m_q4Rotation, rs.m_v3Scale), Relevance = rs.m_fRelevance, }; computerHeapJob.Spheres[i] = srs; } computerHeapJob.triangles = new NativeArray <TriangleStruct>(structTrangle.ToArray(), Allocator.TempJob); computerHeapJob.m_VertexHeap = minNativeHeap; handle = computerHeapJob.Schedule(); //Debug.Log(" computerHeapJob.m_VertexHeap.Length" + computerHeapJob.m_VertexHeap.Length); }
/// <summary> /// 析构方法 /// </summary> public void Destructor(ref NativeHeap <VertexStruct> vertexHeap, ref NativeArray <TriangleStruct> triangleArray, ref VertexStruct vold, NativeArray <int> idToHeapIndex) { //动态数组 int i; for (i = 0; i < 3; i++) { if (vertexs[i] != -1) { VertexStruct v; if (vertexs[i] == vold.ID) { v = vold; } else { v = vertexHeap[idToHeapIndex[vertexs[i]]]; } Pointer ptr = v.pfaces; int triangleIndices = ptr.Get <int>(v.currentFaceCount - 1); ptr.Set <int>(faceIndex[i], triangleIndices); TriangleStruct t = triangleArray[triangleIndices]; t.faceIndex[t.IndexOf(v.ID)] = faceIndex[i]; //修改完重新赋值 v.RemoveAtTriangele(v.currentFaceCount - 1); //直接修改里面的内容了 triangleArray[triangleIndices] = t; v.pfaces = ptr; if (vertexs[i] == vold.ID) { vold = v; } else { vertexHeap[idToHeapIndex[vertexs[i]]] = v; } } } for (i = 0; i < 3; i++) { int i2 = (i + 1) % 3; if (vertexs[i] == -1 || vertexs[i2] == -1) { continue; } VertexStruct v; VertexStruct v2; int indexI = -1; int indexI2 = -1; if (vertexs[i] == vold.ID) { v = vold; } else { indexI = 1; v = vertexHeap[idToHeapIndex[vertexs[i]]]; } if (vertexs[i2] == vold.ID) { v2 = vold; } else { indexI2 = 1; v2 = vertexHeap[idToHeapIndex[vertexs[i2]]]; } v.RemoveIfNonNeighbor(vertexs[i2], triangleArray); if (indexI != -1) { vertexHeap[idToHeapIndex[vertexs[i]]] = v; } else { vold = v; } v2.RemoveIfNonNeighbor(vertexs[i], triangleArray); if (indexI2 != -1) { vertexHeap[idToHeapIndex[vertexs[i2]]] = v2; } else { vold = v2; } } }