예제 #1
0
        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;
                }
            }
        }
예제 #2
0
        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();
        }