public void Load(byte[] currentBank, int offset, Level level, Area area) { int cursor = offset; while (true) { byte command = currentBank[cursor + 1]; cursor += 2; if (command < 0x40 || command >= 0x65) { bool extraInformation = hasExtraInformation(command); int numTriangles = cvt.int16(currentBank, cursor); cursor += 2; CollisionPatch currentPatch = new CollisionPatch("Patch " + offset.ToString("X")); currentPatch.type = command; patches.Add(currentPatch); for (int i = 0; i < numTriangles; i++) { CollisionTriangle t; currentPatch.triangles.Add(t = new CollisionTriangle(cvt.int16(currentBank, cursor), cvt.int16(currentBank, cursor + 2), cvt.int16(currentBank, cursor + 4))); cursor += 6; if (extraInformation) { t.extraInformation = cvt.int16(currentBank, cursor); cursor += 2; } } continue; } if (command == 0x40) { allVertices = new Vector3[cvt.int16(currentBank, cursor)]; cursor += 2; for (int i = 0; i < allVertices.Length; i++) { allVertices[i] = new Vector3(-cvt.int16(currentBank, cursor), cvt.int16(currentBank, cursor + 2), cvt.int16(currentBank, cursor + 4)); cursor += 6; } continue; } if (command == 0x43) //Special objects { int numObjects = cvt.int16(currentBank, cursor); cursor += 2; for (int i = 0; i < numObjects; i++) { int objectPreset = currentBank[cursor + 1]; int currentPreset = 0; while (objectPresets0x43[currentPreset] != objectPreset) { currentPreset += 8; } Vector3 position = new Vector3(-cvt.int16(currentBank, cursor + 2), cvt.int16(currentBank, cursor + 4), cvt.int16(currentBank, cursor + 6)); cursor += 8; float yRot = 0; int behaviour = cvt.int32(objectPresets0x43, currentPreset + 4); int mID = objectPresets0x43[currentPreset + 3]; int bParams = 0; switch (objectPresets0x43[currentPreset + 1]) { case 0: break; case 1: yRot = (short)(currentBank[cursor + 1] << 0x8); cursor += 2; break; case 2: yRot = cvt.int16(currentBank, cursor); bParams = cvt.int16(currentBank, cursor + 2); cursor += 4; break; case 3: yRot = cvt.int16(currentBank, cursor); bParams = cvt.int16(currentBank, cursor + 2); cursor += 4; break; case 4: bParams = cvt.int16(currentBank, cursor); cursor += 2; break; } yRot = ((float)yRot / ushort.MaxValue) * 360; if (level != null && area != null) { Object newObject = new Object(position, new Vector3(0, yRot, 0), behaviour, mID, 0x1F, bParams); area.AddObject(newObject, Area.ObjectStorageType.Special); } } continue; } if (command == 0x44) //water box { int numObjects = cvt.int16(currentBank, cursor); cursor += 2; for (int i = 0; i < numObjects; i++) { //Water boxes not yet implemented //WaterBox asfas = new WaterBox(cvt.int16(currentBank, cursor + 2), cvt.int16(currentBank, cursor + 4), cvt.int16(currentBank, cursor + 6), cvt.int16(currentBank, cursor + 8), cvt.int16(currentBank, cursor + 10)); //asfas.ID = cvt.int16(currentBank, cursor); cursor += 12; } } if (command == 0x41) { continue; } if (command == 0x42) { break; } } }
public void Import(string fileName, PatchMode mode) { Clear(); string[] fileNameSplit = fileName.Split(new char[] { '/', '\\' }); string fileRelativePath = fileName.Remove(fileName.Length - (fileNameSplit[fileNameSplit.Length - 1].Length), fileNameSplit[fileNameSplit.Length - 1].Length); int minIndex = allVertices.Length; List <Vector3> positions = new List <Vector3>(); CollisionPatch currentPatch = new CollisionPatch("<Undefined>"); StreamReader rd = new StreamReader(fileName); while (!rd.EndOfStream) { string line = rd.ReadLine(); string[] split = line.Split(' '); if (split[0] == "mtllib") //Material Library { string currentDir = Environment.CurrentDirectory; Environment.CurrentDirectory = System.IO.Path.GetDirectoryName(System.IO.Path.GetFullPath(fileName)); CreateMaterialLibrary(line.Remove(0, split[0].Length).Trim()); Environment.CurrentDirectory = currentDir; } else if (split[0] == "o") //Object { if (mode == PatchMode.ByObject) { if (currentPatch.triangles.Count > 0) { patches.Add(currentPatch); } currentPatch = new CollisionPatch(split[1]); } } else if (split[0] == "v") //Vertex Position { Vector3 v = cvt.ParseVector3(split, 1); v.X *= -1; positions.Add(v * Settings.importScale); } else if (split[0] == "usemtl") //Material usage declaration { if (mode == PatchMode.ByMaterial) { if (currentPatch.triangles.Count > 0) { foreach (CollisionPatch patch in patches) { if (patch.name == currentPatch.name) { goto skipMakePatch; } } patches.Add(currentPatch); skipMakePatch :; } foreach (CollisionPatch patch in patches) { if (patch.name == split[1]) { currentPatch = patch; goto skipNewPatch; } } currentPatch = new CollisionPatch(split[1]); if (!materials.TryGetValue(split[1], out currentPatch.materialImage)) { currentPatch.materialImage = failImage; } skipNewPatch :; } } else if (split[0] == "f") // Face { short i0 = 0, ix = 0; for (int i = 1; i < split.Length; i++) { short index = 0; string[] vertexIndices = split[i].Split('/'); short.TryParse(vertexIndices[0], out index); index -= 1; if (i == 1) { i0 = index; } if (i >= 3) { CollisionTriangle t; currentPatch.triangles.Add(t = new CollisionTriangle((short)(i0 + minIndex), (short)(ix + minIndex), (short)(index + minIndex))); } ix = index; } } } rd.BaseStream.Close(); Array.Resize(ref allVertices, allVertices.Length + positions.Count); Array.Copy(positions.ToArray(), 0, allVertices, allVertices.Length - positions.Count, positions.Count); if (currentPatch.triangles.Count > 0) { if (mode == PatchMode.ByObject) { goto makePatch; } foreach (CollisionPatch patch in patches) { if (patch.name == currentPatch.name) { goto skipMakePatch; } } makePatch: patches.Add(currentPatch); skipMakePatch :; } Optimize(); }