public static int Deserialise(BinaryReader reader, GameObject parent) { GameObject go = new GameObject("Mesh Group"); go.isStatic = true; MeshGroup group = go.AddComponent<MeshGroup>(); go.transform.SetParent(parent.transform); int NextOffset = reader.ReadInt32(); reader.SkipInt32(48); reader.SkipInt32(); // Length reader.SkipInt32(0); group.TextureGroup = reader.ReadInt32(); group.TextureIndex = reader.ReadInt32(); group.Unknown1 = reader.ReadInt32(); reader.SkipInt32(0); reader.SkipBytes(16, 0); int next; do { next = SubMeshGroup.Deserialise(reader, go); } while (next != 0); return NextOffset; }
public int MeshFlags; // 60 is normal, 124 is decal public static int Deserialise(BinaryReader reader, GameObject parent) { GameObject go = new GameObject("Mesh Part"); MeshPart part = go.AddComponent<MeshPart>(); part.transform.SetParent(parent.transform); long offset = reader.BaseStream.Position; int NextOffset = reader.ReadInt32(); reader.SkipInt32(64); reader.SkipInt32();//Length reader.SkipInt32(0); int VertexCount = reader.ReadInt32(); part.ObjectType = reader.ReadInt32(); //1 = static, 2 = can be or not there, 3 = can move int val = reader.ReadInt32(); part.OcclusionGroup = "0x" + val.ToString("X") + " 0b" + Convert.ToString(val, 2); part.MeshFlags = reader.ReadInt32(); reader.SkipBytes(32, 0); go.isStatic = part.ObjectType != 3; Matrix4x4 matrix = part.GetComponentInParent<Scene>().GetSH3ToUnityMatrix(); List<Vector3> _verts = new List<Vector3>(); List<Vector3> _norms = new List<Vector3>(); List<Vector2> _uvs = new List<Vector2>(); List<Color32> _colors = new List<Color32>(); for (int i = 0; i != VertexCount; i++) { Vector3 temp = reader.ReadVector3(); temp.y = -temp.y; _verts.Add(matrix.MultiplyPoint(temp)); temp = reader.ReadVector3(); temp.x = -temp.x; temp.z = -temp.z; _norms.Add(temp); _uvs.Add(reader.ReadVector2()); _colors.Add(reader.ReadBGRA()); } Mesh mesh = MeshUtils.MakeStripped(_verts, _norms, _uvs, _colors); mesh.name = "mesh_" + offset; go.AddComponent<MeshFilter>().sharedMesh = mesh; go.AddComponent<MeshRenderer>().shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off; return NextOffset; }
public static Skybox Deserialise(BinaryReader reader, GameObject parent) { GameObject go = new GameObject("Skybox"); Skybox sky = go.AddComponent<Skybox>(); go.transform.SetParent(parent.transform); sky.NextSkyboxOffset = reader.ReadInt32(); sky.HeaderLength = reader.ReadInt32(); sky.SkyboxLength = reader.ReadInt32(); sky.Unknown1 = reader.ReadInt32(); sky.Unknown2 = reader.ReadInt32(); sky.Unknown3 = reader.ReadInt32(); sky.Unknown4 = reader.ReadInt32(); sky.Unknown5 = reader.ReadInt32(); sky.Matrix = reader.ReadMatrix4x4(); List<Vector3> _verts = new List<Vector3>(); for (int i = 0; i != 8; i++) { _verts.Add(reader.ReadVector3()); reader.SkipInt32(); } sky.Vertices = _verts.ToArray(); return sky; }
public float Unknown4; //1 public static int Deserialise(BinaryReader reader, GameObject parent) { GameObject go = new GameObject("SubSubMesh Group"); go.isStatic = true; SubSubMeshGroup group = go.AddComponent<SubSubMeshGroup>(); go.transform.SetParent(parent.transform); int NextOffset = reader.ReadInt32(); reader.SkipInt32(48); reader.SkipInt32(); //Length reader.SkipInt32(0); group.Illumination = reader.ReadInt32(); reader.SkipInt32(0); reader.SkipInt32(0); reader.SkipInt32(0); group.Unknown1 = reader.ReadSingle(); group.Unknown2 = reader.ReadSingle(); group.Unknown3 = reader.ReadSingle(); group.Unknown4 = reader.ReadSingle(); int next; do { next = MeshPart.Deserialise(reader, go); } while (next != 0); return NextOffset; }
public static MapShadows ReadShadowCasters(string path) { string assetPath = path.Replace(".kg2", ".asset"); GameObject subGO = Scene.BeginEditingPrefab(path, "Shadows"); try { MapShadows casters = subGO.AddComponent<MapShadows>(); BinaryReader reader = new BinaryReader(new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read)); if (reader.BaseStream.Length != 0) { //Master header reader.SkipInt32(); short casterCount = reader.ReadInt16(); reader.SkipBytes(10, 0); Matrix4x4 transMat = casters.GetComponentInParent<Scene>().GetSH3ToUnityMatrix(); //Reading casters for (int i = 0; i != casterCount; i++) { //Caster header reader.SkipInt32(0); /*short index = */reader.ReadInt16(); short shapeCounts = reader.ReadInt16(); reader.SkipBytes(16, 0); /*Vector3 mainPivot = */reader.ReadShortVector3(); /*short casterGroup = */reader.ReadInt16(); Matrix4x4 mainMatrix = reader.ReadMatrix4x4(); Vector3 debugPosition = Matrix4x4Utils.ExtractTranslationFromMatrix(ref mainMatrix); debugPosition.y = -debugPosition.y; Vector3 currentNormal = Vector3.zero; //reading shapes for (int j = 0; j != shapeCounts; j++) { short countOfPoints = reader.ReadInt16(); short UnknownS1 = reader.ReadInt16(); /*short UnknownS2 = */reader.ReadInt16(); reader.SkipInt16(countOfPoints); /*Vector3 pivot = */reader.ReadShortVector3(); short shapeGroup = reader.ReadInt16(); List<Vector3> _verts = new List<Vector3>(); List<Vector3> _norms = new List<Vector3>(); for (int k = 0; k != countOfPoints; ) { Vector3 v = reader.ReadShortVector3(); short flag = reader.ReadInt16(); if (flag == 0) { currentNormal = Vector3.Normalize(v); } else { _verts.Add(transMat.MultiplyPoint(v + debugPosition)); _norms.Add(currentNormal); k++; } } Mesh mesh = null; if (UnknownS1 == 6) { mesh = MeshUtils.MakeStripped(_verts, _norms, null, null, true); } else if (UnknownS1 == 5) { mesh = MeshUtils.MakeStrippedInverted(_verts, _norms); } else { mesh = MeshUtils.MakeSquare(_verts, _norms, null, null, true); } mesh.name = "shadowMesh_" + shapeGroup; GameObject go = new GameObject("Shadow mesh"); go.transform.SetParent(subGO.transform); go.AddComponent<MeshFilter>().sharedMesh = mesh; MeshRenderer mr = go.AddComponent<MeshRenderer>(); mr.sharedMaterial = MaterialRolodex.defaultDiffuse; mr.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.ShadowsOnly; if (reader.BaseStream.Position % 16 != 0) { reader.SkipBytes(8, 0); } } } } reader.Close(); foreach (MeshFilter mf in subGO.GetComponentsInChildren<MeshFilter>()) { AssetDatabase.AddObjectToAsset(mf.sharedMesh, assetPath); } Scene.FinishEditingPrefab(path, subGO); return casters; } catch (Exception e) { Debug.LogException(e); } return null; }
public static Texture2D[] ReadDDS(string baseName, BinaryReader reader) { reader.SkipInt32(2); int texturesSize = reader.ReadInt32(); reader.SkipInt32(0); reader.SkipInt32(0); reader.SkipInt32(0x19990901); //magic reader.SkipInt32(0); reader.SkipInt32(0); reader.SkipInt32(1); List<Texture2D> textures = new List<Texture2D>(); int i = 0; while (reader.BaseStream.Position < texturesSize) { short textureID = reader.ReadInt16(); reader.SkipInt16(0); short width = reader.ReadInt16(); short height = reader.ReadInt16(); reader.SkipInt16(512); reader.SkipInt16(512); int subgroupsCount = reader.ReadInt32(); //1 more? reader.SkipInt16(); reader.SkipInt16(); reader.SkipBytes(12); //Skips 0 0 0 int texLength = 0; for (int j = 0; j != subgroupsCount; j++) { //Subgroup thingie /*short subgroupID = */ reader.SkipInt16(); reader.SkipInt16(); reader.SkipInt16(0); reader.SkipInt16(0); reader.SkipInt16(512); reader.SkipInt16(512); reader.SkipInt16(256); reader.SkipInt16(0); texLength = reader.ReadInt32(); /*int texAndHeaderLength = */ reader.SkipInt32(); reader.SkipInt32(0); reader.SkipUInt32(0x99000000); } Texture2D text = new Texture2D(width, height, TextureFormat.DXT1, false); text.LoadRawTextureData(reader.ReadBytes(texLength)); text.Apply(); text.alphaIsTransparency = true; text.name = baseName + textureID.ToString("0000"); textures.Add(text); i++; } reader.SkipBytes(0x10); return textures.ToArray(); }
public static MapCollisions ReadCollisions(string path) { string assetPath = path.Replace(".cld", ".asset"); GameObject subGO = Scene.BeginEditingPrefab(path, "Collisions"); try { MapCollisions cols = subGO.AddComponent<MapCollisions>(); BinaryReader reader = new BinaryReader(new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read)); Vector2 origin = reader.ReadVector2(); reader.SkipInt32(160); reader.SkipInt32(880); reader.SkipInt32(160); reader.SkipInt32(80); /*int vertexCount = */reader.ReadInt32(); reader.SkipInt32(0); List<int> offsets = new List<int>(); for (int i = 0; i != 85; i++) { offsets.Add(reader.ReadInt32()); } /*int offset; while ((offset = reader.ReadInt32()) != 0 && offset != -1) { offsets.Add(offset); }*/ Matrix4x4 transMat = cols.GetComponentInParent<Scene>().GetSH3ToUnityMatrix(); foreach (int off in offsets) { reader.BaseStream.Position = off - 4; int peek = reader.ReadInt32(); if (peek == 0) { while (true) { peek = reader.PeekInt32(); if (peek != 0) { cols.panes.Add(new CollisionPane(reader, transMat)); } else { break; } } } } int[] groups = cols.panes.Select(x => x.group).Distinct().ToArray(); foreach (int group in groups) { List<MeshCombineUtility.MeshInstance> meshes = new List<MeshCombineUtility.MeshInstance>(); GameObject colGO = new GameObject("Collision " + group); colGO.isStatic = true; foreach (CollisionPane pane in cols.panes.Where(x => x.group == group)) { if (pane.type == 257) { MeshCombineUtility.MeshInstance inst = new MeshCombineUtility.MeshInstance(); inst.mesh = MeshUtils.MakeSquareInverted(pane.vectors.ToList()); inst.subMeshIndex = 0; inst.transform = Matrix4x4.identity; meshes.Add(inst); } else if (pane.type == 1) { MeshCombineUtility.MeshInstance inst = new MeshCombineUtility.MeshInstance(); inst.mesh = MeshUtils.MakeStrippedInverted(pane.vectors.ToList()); inst.subMeshIndex = 0; inst.transform = Matrix4x4.identity; meshes.Add(inst); } else if (pane.type == 769) { CapsuleCollider cc = colGO.AddComponent<CapsuleCollider>(); cc.center = pane.vectors[0] + (pane.offset * 0.5f); cc.radius = pane.radius; cc.height = pane.offset.y; cc.direction = 1; } } Mesh mesh = MeshCombineUtility.Combine(meshes.ToArray(), false); mesh.RecalculateNormals(); mesh.name = "collisionMesh_" + group; MeshCollider mc = colGO.AddComponent<MeshCollider>(); mc.sharedMesh = mesh; colGO.transform.SetParent(subGO.transform); } reader.Close(); foreach (MeshCollider mc in subGO.GetComponentsInChildren<MeshCollider>()) { AssetDatabase.AddObjectToAsset(mc.sharedMesh, assetPath); } Scene.FinishEditingPrefab(path, subGO); return cols; } catch (Exception e) { Debug.LogException(e); } return null; }
public CollisionPane(BinaryReader reader, Matrix4x4 transMat) { type = reader.ReadInt32(); int vectorsToRead = reader.ReadInt32(); //Not neccessarely group = reader.ReadInt32(); //More like group reader.SkipInt32(0); if (type == 769) { Vector3 vertex = reader.ReadVector3YInverted(); vectors = new Vector3[] { transMat.MultiplyPoint(vertex) }; reader.SkipSingle(1.0f); offset = transMat.MultiplyPoint(reader.ReadVector3YInverted()); radius = reader.ReadSingle() * Scene.GLOBAL_SCALE; } else if (type == 257 || type == 1) { List<Vector3> v3s = new List<Vector3>(); for (int i = 0; i != vectorsToRead; i++) { if (type == 1 && i != 0 && i % 3 == 0) { reader.SkipBytes(16); continue; } Vector3 vertex = reader.ReadVector3YInverted(); v3s.Add(transMat.MultiplyPoint(vertex)); reader.SkipSingle(1.0f); } vectors = v3s.ToArray(); offset = Vector3.zero; radius = 0.0f; } else { Debug.LogWarning("UNHANDLED COLLIDER TYPE " + type + " FIX IT"); } }
static void ReadSH2Map(BinaryReader reader, Map scene, string path) { GameObject subGO = scene.gameObject; string assetPath = path.Replace(".map", ".asset"); int fileID = reader.ReadInt32(); int fileSize = reader.ReadInt32(); int Unknown1 = reader.ReadInt32(); reader.SkipInt32(0); //Textures Texture[] textures = TextureUtils.ReadDDS(Path.GetFileName(path).Replace(".map", "_tex"), reader); //Meshes reader.SkipInt32(1); reader.SkipInt32(); //Length from magic to bottom reader.SkipInt32(0); reader.SkipInt32(0); long magicPosition = reader.BaseStream.Position; reader.SkipInt32(0x20010730); //Magic number? reader.SkipInt32(1); int materialsOffset = reader.ReadInt32() + (int)magicPosition; int meshCount = reader.ReadInt32(); reader.SkipInt32(0); reader.SkipInt32(); // Length of elements from 0^ reader.SkipInt32(20); reader.SkipInt32(0); reader.SkipInt32(0); reader.SkipInt32(1); reader.SkipInt32(8); long v1offset = reader.BaseStream.Position; reader.ReadVector3YInverted(); //V1 reader.SkipInt32(0); reader.ReadVector3YInverted(); //V2 reader.SkipInt32(0); int headerLength = reader.ReadInt32(); //From v1 to vertexLength int indicesOffset = reader.ReadInt32() + (int)v1offset; int indicesLength = reader.ReadInt32(); int Unknown = reader.ReadInt32(); reader.SkipInt32(meshCount); List<MeshGroupSH2> groups = new List<MeshGroupSH2>(); for (int i = 0; i != meshCount; i++) { groups.Add(MeshGroupSH2.Initialise(reader, subGO)); } int vertexLength = reader.ReadInt32(); reader.SkipInt32(1); reader.SkipInt32(0); int elementLength = reader.ReadInt32(); reader.SkipInt32(vertexLength); int vertexElementsCount = vertexLength / elementLength; List<Vector3> verts = new List<Vector3>(); List<Vector3> norms = new List<Vector3>(); List<Color32> colors = new List<Color32>(); List<Vector2> uvs = new List<Vector2>(); for (int i = 0; i != vertexElementsCount; i++) { verts.Add(reader.ReadVector3YInverted() * Scene.GLOBAL_SCALE); norms.Add(reader.ReadVector3YInverted()); if (elementLength == 36) { colors.Add(reader.ReadBGRA()); } uvs.Add(reader.ReadVector2()); } reader.BaseStream.Position = indicesOffset; List<short[]> indices = new List<short[]>(groups.Count); //stupid for (int i = 0; i != groups.Count; i++) { indices.Add(null); } for(int i = 0; i != groups.Count; i++) { MeshGroupSH2 group = groups[i]; indices[group.MainID] = new short[group.indexCount]; for (int j = 0; j != group.indexCount ; j++) { indices[group.MainID][j] = reader.ReadInt16(); } Debug.Log("End of i = " + reader.BaseStream.Position.ToString("X")); } reader.BaseStream.Position = materialsOffset; //Mesh renderer MaterialRolodex rolodex = MaterialRolodex.GetOrCreateAt(assetPath); rolodex.AddTextures(textures); MeshRenderer mr = subGO.AddComponent<MeshRenderer>(); Material[] mats = new Material[groups.Count]; for (int i = 0; i != groups.Count; i++) { reader.SkipInt16(); MaterialRolodex.TexMatsPair tmp = rolodex.GetWithSH2ID(reader.ReadInt16()); mats[i] = tmp.GetOrCreateDiffuse(); reader.SkipBytes(12); } mr.sharedMaterials = mats; reader.Close(); //Mesh filter subGO.AddComponent<MeshFilter>().sharedMesh = MeshUtils.MakeIndexedStrip(verts, indices, norms, uvs, colors); foreach (MeshFilter mf in subGO.GetComponentsInChildren<MeshFilter>()) { AssetDatabase.AddObjectToAsset(mf.sharedMesh, assetPath); } }
static void ReadSH3Map(BinaryReader reader, Map scene, string path) { GameObject subGO = scene.gameObject; string assetPath = path.Replace(".map", ".asset"); reader.SkipInt32(-1); reader.SkipInt32(0); reader.SkipInt32(0); reader.SkipInt32(80); //Main header size int TextureGroupOffset = reader.ReadInt32(); reader.SkipInt32(0); reader.SkipInt32(80); //Alt main header size reader.SkipInt32(); //Total main header size scene.Unknown1 = reader.ReadInt32(); reader.SkipInt32(); //Scene star header offset reader.SkipInt32(0); reader.SkipInt32(0); reader.SkipInt32(); //TextureGroupOffset2 /*int transformOffset = */ reader.ReadInt32(); scene.Unknown2 = reader.ReadInt32(); reader.SkipInt32(0); scene.TotalTextures = reader.ReadInt16(); scene.LocalTextureBaseIndex = reader.ReadInt16(); scene.LocalTextureCount = reader.ReadInt16(); scene.LocalTextureBaseIndexModifier = reader.ReadInt16(); reader.SkipInt32(0); reader.SkipInt32(0); //Read textures long goBack = reader.BaseStream.Position; reader.BaseStream.Position = TextureGroupOffset; Texture2D[] textures = TextureUtils.ReadTex32(Path.GetFileName(path).Replace(".map", "_tex"), reader); reader.BaseStream.Position = goBack; //Read Skyboxes Skybox sky = null; do { sky = Skybox.Deserialise(reader, subGO); } while (sky.NextSkyboxOffset != 0); //Read meshgroups int next; do { next = MeshGroup.Deserialise(reader, subGO); } while (next != 0); //reader.BaseStream.Position = transformOffset; //Matrix4x4 mat4x4 = reader.ReadMatrix4x4(); Matrix4x4Utils.SetTransformFromSH3Matrix(subGO.transform, ref subGO.GetComponentInChildren<Skybox>().Matrix); reader.Close(); //Asset bookkeeping MaterialRolodex rolodex = MaterialRolodex.GetOrCreateAt(assetPath); rolodex.AddTextures(textures); int baseIndex = 0; MeshGroup[] groups = subGO.GetComponentsInChildren<MeshGroup>(); foreach (MeshGroup group in groups) { MaterialRolodex goodRolodex = null; if (group.TextureGroup == 3) { goodRolodex = rolodex; baseIndex = scene.LocalTextureBaseIndex + scene.LocalTextureBaseIndexModifier; } else if (group.TextureGroup == 2) { string trpath; if (path.Contains("cc/cc")) { trpath = path.Substring(0, path.IndexOf(".map") - 2) + "01TR.tex"; } else { trpath = path.Replace(".map", "TR.tex"); } goodRolodex = MaterialRolodex.GetOrCreateAt(trpath); } else if (group.TextureGroup == 1) { string name = Path.GetFileName(path); goodRolodex = MaterialRolodex.GetOrCreateAt(path.Replace(name, name.Substring(0, 2) + "GB.tex")); } else { Debug.LogWarning("Unknown texture group " + group.TextureGroup + " on " + group.gameObject); } if (goodRolodex == null) { Debug.LogWarning("Couldn't find rolodex for group " + group.TextureGroup + " on " + path); continue; } MaterialRolodex.TexMatsPair tmp = goodRolodex.GetWithSH3Index(group.TextureIndex, baseIndex); foreach (SubMeshGroup subMeshGroup in group.GetComponentsInChildren<SubMeshGroup>()) { foreach (SubSubMeshGroup subSubMeshGroup in subMeshGroup.GetComponentsInChildren<SubSubMeshGroup>()) { foreach (MeshRenderer renderer in subSubMeshGroup.GetComponentsInChildren<MeshRenderer>()) { if (subMeshGroup.IsTransparent == 1) { renderer.sharedMaterial = tmp.GetOrCreateTransparent(); } else if (subMeshGroup.IsTransparent == 3) { renderer.sharedMaterial = tmp.GetOrCreateCutout(); } else if (subSubMeshGroup.Illumination == 8) { renderer.sharedMaterial = tmp.GetOrCreateSelfIllum(); } else { renderer.sharedMaterial = tmp.GetOrCreateDiffuse(); } } } } } foreach (MeshFilter mf in subGO.GetComponentsInChildren<MeshFilter>()) { AssetDatabase.AddObjectToAsset(mf.sharedMesh, assetPath); } }
public static Camera TryMakeCamera(BinaryReader reader, Matrix4x4 transMat) { Vector2 zoneA = reader.ReadVector2(); reader.SkipBytes(8); Vector2 zoneB = reader.ReadVector2(); Vector2 zoneHeights = reader.ReadVector2(); Vector2 constraintA = reader.ReadVector2(); reader.SkipBytes(8); Vector2 constraintB = reader.ReadVector2(); Vector2 constraintHeights = reader.ReadVector2(); reader.SkipInt32(0); int type = reader.ReadInt32(); reader.SkipInt32(0); int Unknown1 = reader.ReadInt32(); Vector4 Unknown2 = reader.ReadVector4(); Vector2 Unknown3 = reader.ReadVector2(); reader.SkipInt32(0); int Unknown4 = reader.ReadInt32(); Vector2 Unknown5 = reader.ReadVector2(); Vector2 Unknown6 = reader.ReadVector2(); if (type != 1) { Camera cam = new Camera(); Vector3 activeMin = new Vector3(zoneA.x, -zoneHeights.x, zoneA.y); Vector3 activeMax = new Vector3(zoneB.x, -zoneHeights.y, zoneB.y); cam.activeArea = new Bounds(); cam.activeArea.SetMinMax(transMat.MultiplyPoint(activeMin), transMat.MultiplyPoint(activeMax)); Vector3 constraintMin = new Vector3(constraintA.x, -constraintHeights.x, constraintA.y); Vector3 constraintMax = new Vector3(constraintB.x, -constraintHeights.y, constraintB.y); cam.constraintsArea = new Bounds(); cam.constraintsArea.SetMinMax(transMat.MultiplyPoint(constraintMin), transMat.MultiplyPoint(constraintMax)); cam.type = type; cam.Unknown1 = Unknown1; cam.Unknown2 = Unknown2; cam.Unknown3 = Unknown3; cam.Unknown4 = Unknown4; cam.Unknown5 = Unknown5; cam.Unknown6 = Unknown6; return cam; } return null; }