public static void Main() { Directory.CreateDirectory("LISTTRAK"); if (File.Exists(@"LISTTRAK\vars.txt")) { vars.Parse(@"LISTTRAK\vars.txt"); } using (TextWriter writer = new StreamWriter("output.txt")) { Regex r = new Regex(@"[0-9a-fA-F]{8}\.[0-9a-zA-Z]{3}", RegexOptions.IgnoreCase); foreach (var file in Directory.GetFiles(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"LISTTRAK")) .Where(x => r.IsMatch(Path.GetFileName(x))) .Select(x => new { FilePath = x, FileNumber = Convert.ToInt32(Path.GetFileNameWithoutExtension(x), 16) }) .OrderBy(x => x.FileNumber)) { writer.WriteLine("--------------------------------------------------"); writer.WriteLine("#{0} {1}", file.FileNumber, vars.GetText("TRACKS", file.FileNumber, string.Empty)); writer.WriteLine("--------------------------------------------------"); Dump(file.FilePath, writer); } } }
void RefreshLeftText() { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendFormat("{0} {1}/{2} <color=#00c864>{3}</color>", Path.GetFileNameWithoutExtension(modelFolders[modelFolderIndex]), modelIndex, modelCount - 1, varParser.GetText("BODYS", modelIndex)); if (EnableAnimation.BoolValue) { stringBuilder.Append("\r\n"); stringBuilder.AppendFormat("{0} {1}/{2} <color=#00c864>{3}</color>", Path.GetFileNameWithoutExtension(animFolders[modelFolderIndex]), animIndex, animCount - 1, varParser.GetText("ANIMS", animIndex)); } if (ShowAdditionalInfo.BoolValue) { stringBuilder.Append("\r\n\r\n"); stringBuilder.AppendFormat("Bounding box: <color=#00c864>{0} {1} {2}</color>\r\n", boundingUpper.x - boundingLower.x, boundingUpper.y - boundingLower.y, boundingUpper.z - boundingLower.z); } if (EnableAnimation.BoolValue && ShowAdditionalInfo.BoolValue && animFrames != null) { int index = 0; foreach (Frame frame in animFrames) { stringBuilder.AppendFormat("Frame {0}: <color=#00c864>{1} {2} {3} {4}</color>\r\n", index, frame.Time, frame.Offset.x, frame.Offset.y, -frame.Offset.z); index++; } } LeftText.text = stringBuilder.ToString(); frameDistance = Vector3.zero; }
void LoadBody(bool resetcamera = true) { int fileIndex = modelFiles[modelIndex].Key; string varName = varParser.GetText("BODYS", fileIndex); string folderName = modelFolders[modelFolderIndex]; leftTextBody = folderName.Substring(folderName.Length - 4) + " " + fileIndex + "/" + modelFiles[modelFiles.Count - 1].Key + " <color=#00c864>" + varName + "</color>"; RefreshLeftText(); //camera if (resetcamera) { autoRotate = true; cameraPosition = Vector2.zero; } //clear model SkinnedMeshRenderer filter = this.gameObject.GetComponent <SkinnedMeshRenderer>(); filter.sharedMesh = null; //delete all bones foreach (Transform child in transform) { GameObject.Destroy(child.gameObject); } //load data string filename = modelFiles[modelIndex].Value; byte[] allbytes = File.ReadAllBytes(filename); int i = 0; //header modelFlags = allbytes.ReadShort(i + 0); //bounding box allbytes.ReadBoundingBox(i + 2, out boundingLower, out boundingUpper); i += 0xE; i += allbytes.ReadShort(i + 0) + 2; //vertexes int count = allbytes.ReadShort(i + 0); i += 2; List <Vector3> vertices = new List <Vector3>(); for (int j = 0; j < count; j++) { Vector3 position = new Vector3(allbytes.ReadShort(i + 0), -allbytes.ReadShort(i + 2), allbytes.ReadShort(i + 4)); vertices.Add(position / 1000.0f); i += 6; } bones = new List <Transform>(); List <Matrix4x4> bindPoses = new List <Matrix4x4>(); Dictionary <int, int> bonesPerVertex = new Dictionary <int, int>(); List <Vector3> vertexNoTransform = vertices.ToList(); if ((modelFlags & 2) == 2) //check if model has bones { //bones count = allbytes.ReadShort(i + 0); i += 2; i += count * 2; Dictionary <int, Transform> bonesPerIndex = new Dictionary <int, Transform>(); bonesPerIndex.Add(255, transform); for (int n = 0; n < count; n++) { int startindex = allbytes.ReadShort(i + 0) / 6; int numpoints = allbytes.ReadShort(i + 2); int vertexindex = allbytes.ReadShort(i + 4) / 6; int parentindex = allbytes[i + 6]; int boneindex = allbytes[i + 7]; //create bone Transform bone = new GameObject("BONE").transform; bonesPerIndex.Add(boneindex, bone); bone.parent = bonesPerIndex[parentindex]; bone.localRotation = Quaternion.identity; bone.localPosition = vertexNoTransform[vertexindex]; bones.Add(bone); //create pose Matrix4x4 bindPose = new Matrix4x4(); bindPose = bone.worldToLocalMatrix * transform.localToWorldMatrix; bindPoses.Add(bindPose); //apply bone transformation Vector3 position = vertices[vertexindex]; for (int u = 0; u < numpoints; u++) { vertices[startindex] += position; bonesPerVertex.Add(startindex, bones.Count - 1); startindex++; } if ((modelFlags & 8) == 8) { i += 0x18; } else { i += 0x10; } } } else { //if no bones add dummy values for (int u = 0; u < vertices.Count; u++) { bonesPerVertex.Add(u, 0); } } //compute line size Bounds bounds = new Bounds(); foreach (Vector3 vector in vertices) { bounds.Encapsulate(vector); } float linesize = bounds.size.magnitude / 250.0f; float noisesize = 0.8f / bounds.size.magnitude; //primitives count = allbytes.ReadShort(i + 0); i += 2; //load palette Color32[] paletteColors = PaletteTexture[paletteIndex].GetPixels32(); List <BoneWeight> boneWeights = new List <BoneWeight>(); allVertices = new List <Vector3>(); uv = new List <Vector2>(); uvDepth = new List <Vector2>(); List <Color32> colors = new List <Color32>(); List <int>[] indices = new List <int> [5]; for (int n = 0; n < indices.Length; n++) { indices[n] = new List <int>(); } gradientPolygonList = new List <List <int> >(); gradientPolygonType = new List <int>(); for (int n = 0; n < count; n++) { int primitiveType = allbytes[i + 0]; i++; switch (primitiveType) { //line case 0: { i++; int colorIndex = allbytes[i + 0]; i += 2; Color32 color = paletteColors[colorIndex]; int pointIndexA = allbytes.ReadShort(i + 0) / 6; int pointIndexB = allbytes.ReadShort(i + 2) / 6; Vector3 directionVector = vertices[pointIndexA] - vertices[pointIndexB]; Vector3 middle = (vertices[pointIndexA] + vertices[pointIndexB]) / 2.0f; Quaternion rotation = Quaternion.LookRotation(directionVector); uv.AddRange(CubeMesh.uv); uvDepth.AddRange(CubeMesh.vertices.Select(x => Vector2.zero)); indices[0].AddRange(CubeMesh.triangles.Select(x => x + allVertices.Count)); allVertices.AddRange(CubeMesh.vertices.Select(x => rotation * (Vector3.Scale(x, new Vector3(linesize, linesize, directionVector.magnitude))) + middle)); colors.AddRange(CubeMesh.vertices.Select(x => color)); boneWeights.AddRange(CubeMesh.vertices.Select(x => new BoneWeight() { boneIndex0 = bonesPerVertex[x.z > 0 ? pointIndexA : pointIndexB], weight0 = 1 })); i += 4; break; } //polygon case 1: { int numPoints = allbytes[i + 0]; int polyType = allbytes[i + 1]; int colorIndex = allbytes[i + 2]; i += 3; Color32 color = GetPaletteColor(paletteColors, colorIndex, polyType); List <int> triangleList = indices[GetTriangleListIndex(polyType)]; //add vertices List <int> polyVertices = new List <int>(); int verticesCount = allVertices.Count; for (int m = 0; m < numPoints; m++) { int pointIndex = allbytes.ReadShort(i + 0) / 6; i += 2; colors.Add(color); polyVertices.Add(allVertices.Count); allVertices.Add(vertices[pointIndex]); boneWeights.Add(new BoneWeight() { boneIndex0 = bonesPerVertex[pointIndex], weight0 = 1 }); } gradientPolygonType.Add(polyType); gradientPolygonList.Add(polyVertices); if (polyType == 1 && NoiseMaterial.BoolValue) { Vector3 forward, left; ComputeUV(polyVertices, out forward, out left); foreach (int pointIndex in polyVertices) { Vector3 poly = allVertices[pointIndex]; uv.Add(new Vector2( Vector3.Dot(poly, left) * noisesize, Vector3.Dot(poly, forward) * noisesize )); } } else { uv.AddRange(polyVertices.Select(x => Vector2.zero)); } uvDepth.AddRange(polyVertices.Select(x => Vector2.zero)); //triangulate int v0 = 0; int v1 = 1; int v2 = numPoints - 1; bool swap = true; while (v1 < v2) { triangleList.Add(verticesCount + v0); triangleList.Add(verticesCount + v1); triangleList.Add(verticesCount + v2); if (swap) { v0 = v1; v1++; } else { v0 = v2; v2--; } swap = !swap; } break; } //sphere case 3: { int polyType = allbytes[i]; i++; int colorIndex = allbytes[i]; Color32 color = GetPaletteColor(paletteColors, colorIndex, polyType); List <int> triangleList = indices[GetTriangleListIndex(polyType)]; i += 2; int size = allbytes.ReadShort(i + 0); i += 2; int pointSphereIndex = allbytes.ReadShort(i + 0) / 6; i += 2; Vector3 position = vertices[pointSphereIndex]; float scale = size / 500.0f; float uvScale = noisesize * size / 200.0f; if ((polyType == 3 || polyType == 4 || polyType == 5 || polyType == 6) && GradientMaterial.BoolValue) { gradientPolygonType.Add(polyType); gradientPolygonList.Add(Enumerable.Range(allVertices.Count, SphereMesh.vertices.Length).ToList()); } uv.AddRange(SphereMesh.uv.Select(x => x * uvScale)); uvDepth.AddRange(SphereMesh.vertices.Select(x => Vector2.zero)); triangleList.AddRange(SphereMesh.triangles.Select(x => x + allVertices.Count)); allVertices.AddRange(SphereMesh.vertices.Select(x => x * scale + position)); colors.AddRange(SphereMesh.vertices.Select(x => color)); boneWeights.AddRange(SphereMesh.vertices.Select(x => new BoneWeight() { boneIndex0 = bonesPerVertex[pointSphereIndex], weight0 = 1 })); break; } case 2: //1x1 pixel case 6: //2x2 square case 7: //NxN square, size depends projected z-value { i++; int colorIndex = allbytes[i]; i += 2; int cubeIndex = allbytes.ReadShort(i + 0) / 6; i += 2; Color32 color = paletteColors[colorIndex]; Vector3 position = vertices[cubeIndex]; float pointsize; if (primitiveType == 2) { pointsize = linesize; } else { pointsize = linesize * 2.5f; } uv.AddRange(CubeMesh.uv); uvDepth.AddRange(CubeMesh.vertices.Select(x => Vector2.zero)); indices[0].AddRange(CubeMesh.triangles.Select(x => x + allVertices.Count)); allVertices.AddRange(CubeMesh.vertices.Select(x => x * pointsize + position)); colors.AddRange(CubeMesh.vertices.Select(x => color)); boneWeights.AddRange(CubeMesh.vertices.Select(x => new BoneWeight() { boneIndex0 = bonesPerVertex[cubeIndex], weight0 = 1 })); break; } case 4: case 5: //should be ignored break; default: throw new UnityException("unknown primitive " + primitiveType.ToString() + " at " + i.ToString()); } } // Create the mesh Mesh msh = new Mesh(); msh.vertices = allVertices.ToArray(); msh.colors32 = colors.ToArray(); //separate transparent/opaque triangles msh.subMeshCount = 5; msh.SetTriangles(indices[0], 0); msh.SetTriangles(indices[1], 1); msh.SetTriangles(indices[2], 2); msh.SetTriangles(indices[3], 3); msh.SetTriangles(indices[4], 4); msh.SetUVs(0, uv); msh.SetUVs(1, uvDepth); msh.RecalculateNormals(); msh.RecalculateBounds(); //apply bones if (bones.Count > 0) { msh.boneWeights = boneWeights.ToArray(); msh.bindposes = bindPoses.ToArray(); GetComponent <SkinnedMeshRenderer>().bones = bones.ToArray(); initialBonesPosition = bones.Select(x => x.localPosition).ToList(); } filter.localBounds = msh.bounds; filter.sharedMesh = msh; }
void GridCellEnter(object sender, CellEventArgs e) { string text = varParser.GetText(e.Var.Type, e.Var.Index); toolTip.Show(string.Format("#{0}\n{1}", e.Var.Index, text), e.Rectangle); }
void LoadBody(string filename, bool resetcamera = true) { string varName = varParser.GetText("BODYS", modelIndex); LeftTextBody = Path.GetFileName(Path.GetDirectoryName(filename)) + " " + modelIndex + "/" + (modelFiles.Count - 1) + " <color=#00c864>" + varName + "</color>"; RefreshLeftText(); //camera if (resetcamera) { autoRotate = true; cameraPosition = Vector2.zero; } //clear model SkinnedMeshRenderer filter = this.gameObject.GetComponent <SkinnedMeshRenderer>(); filter.sharedMesh = null; //delete all bones foreach (Transform child in transform) { GameObject.Destroy(child.gameObject); } //load data byte[] allbytes = File.ReadAllBytes(filename); int i = 0; //header int flags = Utils.ReadShort(allbytes, i + 0); i += 0xE; i += Utils.ReadShort(allbytes, i + 0) + 2; //vertexes int count = Utils.ReadShort(allbytes, i + 0); i += 2; List <Vector3> vertices = new List <Vector3>(); for (int j = 0; j < count; j++) { Vector3 position = new Vector3(Utils.ReadShort(allbytes, i + 0), -Utils.ReadShort(allbytes, i + 2), Utils.ReadShort(allbytes, i + 4)); vertices.Add(position / 1000.0f); i += 6; } //check if model has bones bones = new List <Transform>(); List <Matrix4x4> bindPoses = new List <Matrix4x4>(); Dictionary <int, int> bonesPerVertex = new Dictionary <int, int>(); List <Vector3> vertexNoTransform = vertices.ToList(); if ((flags & 2) == 2) { //bones count = Utils.ReadShort(allbytes, i + 0); i += 2; i += count * 2; Dictionary <int, Transform> bonesPerIndex = new Dictionary <int, Transform>(); bonesPerIndex.Add(255, transform); for (int n = 0; n < count; n++) { int startindex = Utils.ReadShort(allbytes, i + 0) / 6; int numpoints = Utils.ReadShort(allbytes, i + 2); int vertexindex = Utils.ReadShort(allbytes, i + 4) / 6; int parentindex = allbytes[i + 6]; int boneindex = allbytes[i + 7]; //create bone Transform bone = new GameObject("BONE").transform; bonesPerIndex.Add(boneindex, bone); bone.parent = bonesPerIndex[parentindex]; bone.localRotation = Quaternion.identity; bone.localPosition = vertexNoTransform[vertexindex]; bones.Add(bone); //create pose Matrix4x4 bindPose = new Matrix4x4(); bindPose = bone.worldToLocalMatrix * transform.localToWorldMatrix; bindPoses.Add(bindPose); //apply bone transformation Vector3 position = vertices[vertexindex]; for (int u = 0; u < numpoints; u++) { vertices[startindex] += position; bonesPerVertex.Add(startindex, bones.Count - 1); startindex++; } i += 0x10; } } else { //if no bones add dummy values for (int u = 0; u < vertices.Count; u++) { bonesPerVertex.Add(u, 0); } } //compute line size Bounds bounds = new Bounds(); foreach (Vector3 vector in vertices) { bounds.Encapsulate(vector); } float linesize = bounds.size.magnitude / 250.0f; float noisesize = 0.8f / bounds.size.magnitude; //primitives count = Utils.ReadShort(allbytes, i + 0); i += 2; //load palette Color32[] paletteColors = PaletteTexture[PaletteIndex].GetPixels32(); List <BoneWeight> boneWeights = new List <BoneWeight>(); List <Vector3> allVertices = new List <Vector3>(); List <Color32> colors = new List <Color32>(); List <int> indices = new List <int>(); List <Vector2> uv = new List <Vector2>(); for (int n = 0; n < count; n++) { int primitiveType = allbytes[i + 0]; i++; switch (primitiveType) { //line case 0: { i++; int colorIndex = allbytes[i + 0]; i += 2; Color32 color = paletteColors[colorIndex]; int pointIndexA = Utils.ReadShort(allbytes, i + 0) / 6; int pointIndexB = Utils.ReadShort(allbytes, i + 2) / 6; Vector3 directionVector = vertices[pointIndexA] - vertices[pointIndexB]; Vector3 middle = (vertices[pointIndexA] + vertices[pointIndexB]) / 2.0f; Quaternion rotation = Quaternion.LookRotation(directionVector); uv.AddRange(CubeMesh.uv); indices.AddRange(CubeMesh.triangles.Select(x => x + allVertices.Count)); allVertices.AddRange(CubeMesh.vertices.Select(x => rotation * (Vector3.Scale(x, new Vector3(linesize, linesize, directionVector.magnitude))) + middle)); colors.AddRange(CubeMesh.vertices.Select(x => color)); boneWeights.AddRange(CubeMesh.vertices.Select(x => new BoneWeight() { boneIndex0 = bonesPerVertex[x.z > 0 ? pointIndexA : pointIndexB], weight0 = 1 })); i += 4; break; } //polygon case 1: { int numPoints = allbytes[i + 0]; int polyType = allbytes[i + 1]; int colorIndex = allbytes[i + 2]; i += 3; Color32 color = GetPaletteColor(paletteColors, colorIndex, polyType); //add vertices List <Vector3> polyVertices = new List <Vector3>(); int verticesCount = allVertices.Count; for (int m = 0; m < numPoints; m++) { int pointIndex = Utils.ReadShort(allbytes, i + 0) / 6; i += 2; colors.Add(color); allVertices.Add(vertices[pointIndex]); polyVertices.Add(vertices[pointIndex]); boneWeights.Add(new BoneWeight() { boneIndex0 = bonesPerVertex[pointIndex], weight0 = 1 }); } if (polyType == 1 && NoiseMaterial.BoolValue) { Vector3 forward, left; ComputeUV(polyVertices, out forward, out left); foreach (Vector3 poly in polyVertices) { uv.Add(new Vector2( Vector3.Dot(poly, left) * noisesize, Vector3.Dot(poly, forward) * noisesize )); } } else { uv.AddRange(polyVertices.Select(x => Vector2.zero)); } //triangulate int v0 = 0; int v1 = 1; int v2 = numPoints - 1; bool swap = true; while (v1 < v2) { indices.Add(verticesCount + v0); indices.Add(verticesCount + v1); indices.Add(verticesCount + v2); if (swap) { v0 = v1; v1++; } else { v0 = v2; v2--; } swap = !swap; } break; } //sphere case 3: { int polyType = allbytes[i]; i++; int colorIndex = allbytes[i]; Color32 color = GetPaletteColor(paletteColors, colorIndex, polyType); i += 2; int size = Utils.ReadShort(allbytes, i + 0); i += 2; int pointSphereIndex = Utils.ReadShort(allbytes, i + 0) / 6; i += 2; Vector3 position = vertices[pointSphereIndex]; float scale = size / 500.0f; float uvScale = noisesize * size / 200.0f; uv.AddRange(SphereMesh.uv.Select(x => x * uvScale)); indices.AddRange(SphereMesh.triangles.Select(x => x + allVertices.Count)); allVertices.AddRange(SphereMesh.vertices.Select(x => x * scale + position)); colors.AddRange(SphereMesh.vertices.Select(x => color)); boneWeights.AddRange(SphereMesh.vertices.Select(x => new BoneWeight() { boneIndex0 = bonesPerVertex[pointSphereIndex], weight0 = 1 })); break; } case 2: //1x1 pixel case 6: //square case 7: { i++; int colorIndex = allbytes[i]; i += 2; int cubeIndex = Utils.ReadShort(allbytes, i + 0) / 6; i += 2; Color32 color = paletteColors[colorIndex]; Vector3 position = vertices[cubeIndex]; float pointsize; if (primitiveType == 2) { pointsize = linesize; } else { pointsize = linesize * 2.5f; } uv.AddRange(CubeMesh.uv); indices.AddRange(CubeMesh.triangles.Select(x => x + allVertices.Count)); allVertices.AddRange(CubeMesh.vertices.Select(x => x * pointsize + position)); colors.AddRange(CubeMesh.vertices.Select(x => color)); boneWeights.AddRange(CubeMesh.vertices.Select(x => new BoneWeight() { boneIndex0 = bonesPerVertex[cubeIndex], weight0 = 1 })); break; } default: throw new UnityException("unknown primitive " + primitiveType.ToString() + " at " + i.ToString()); } } // Create the mesh Mesh msh = new Mesh(); msh.vertices = allVertices.ToArray(); msh.colors32 = colors.ToArray(); //separate transparent/opaque triangles List <int> opaque = new List <int>(); List <int> noise = new List <int>(); List <int> transparent = new List <int>(); List <int> gradient = new List <int>(); for (int t = 0; t < indices.Count; t += 3) { List <int> trianglesList; float alpha = colors[indices[t]].a; if (alpha == 255) { trianglesList = opaque; } else if (alpha == 254) { trianglesList = noise; } else if (alpha == 253) { trianglesList = gradient; } else { trianglesList = transparent; } trianglesList.Add(indices[t + 0]); trianglesList.Add(indices[t + 1]); trianglesList.Add(indices[t + 2]); } msh.subMeshCount = 4; msh.SetTriangles(opaque, 0); msh.SetTriangles(transparent, 1); msh.SetTriangles(noise, 2); msh.SetTriangles(gradient, 3); msh.SetUVs(0, uv); msh.RecalculateNormals(); msh.RecalculateBounds(); //apply bones if (bones.Count > 0) { msh.boneWeights = boneWeights.ToArray(); msh.bindposes = bindPoses.ToArray(); GetComponent <SkinnedMeshRenderer>().bones = bones.ToArray(); initialBonesPosition = bones.Select(x => x.localPosition).ToList(); } filter.localBounds = msh.bounds; filter.sharedMesh = msh; }