Beispiel #1
0
        public static void Extract(MODF.SMMapObjDef mapObjDef, string wmoInstanceName, bool isGlobalWmo, uint mapID, uint originalMapId, BinaryWriter writer, List <ADTOutputCache> dirfileCache)
        {
            // destructible wmo, do not dump. we can handle the vmap for these
            // in dynamic tree (gameobject vmaps)
            if (mapObjDef.Flags.HasAnyFlag(MODFFlags.Destroyable))
            {
                return;
            }

            if (!File.Exists(Program.BuildingsDirectory + wmoInstanceName))
            {
                Console.WriteLine($"WMOInstance.WMOInstance: couldn't open {wmoInstanceName}");
                return;
            }

            //-----------add_in _dir_file----------------
            using BinaryReader binaryReader = new(File.Open(Program.BuildingsDirectory + wmoInstanceName, FileMode.Open, FileAccess.Read, FileShare.Read));
            binaryReader.BaseStream.Seek(8, SeekOrigin.Begin); // get the correct no of vertices
            int nVertices = binaryReader.ReadInt32();

            if (nVertices == 0)
            {
                return;
            }

            Vector3        position = fixCoords(mapObjDef.Position);
            AxisAlignedBox bounds   = new(fixCoords(mapObjDef.Bounds.Lo), fixCoords(mapObjDef.Bounds.Hi));

            if (isGlobalWmo)
            {
                position += new Vector3(533.33333f * 32, 533.33333f * 32, 0.0f);
                bounds   += new Vector3(533.33333f * 32, 533.33333f * 32, 0.0f);
            }

            float scale = 1.0f;

            if (mapObjDef.Flags.HasAnyFlag(MODFFlags.UnkHasScale))
            {
                scale = mapObjDef.Scale / 1024.0f;
            }
            uint uniqueId = VmapFile.GenerateUniqueObjectId(mapObjDef.UniqueId, 0);
            uint flags    = ModelFlags.HasBound;

            if (mapID != originalMapId)
            {
                flags |= ModelFlags.ParentSpawn;
            }

            if (uniqueId == 198660)
            {
            }

            //write mapID, Flags, ID, Pos, Rot, Scale, Bound_lo, Bound_hi, name
            writer.Write(mapID);
            writer.Write(flags);
            writer.Write(mapObjDef.NameSet);
            writer.Write(uniqueId);
            writer.WriteVector3(position);
            writer.WriteVector3(mapObjDef.Rotation);
            writer.Write(scale);
            writer.WriteVector3(bounds.Lo);
            writer.WriteVector3(bounds.Hi);
            writer.Write(wmoInstanceName.GetByteCount());
            writer.WriteString(wmoInstanceName);

            if (dirfileCache != null)
            {
                ADTOutputCache cacheModelData = new();
                cacheModelData.Flags = flags & ~ModelFlags.ParentSpawn;

                MemoryStream stream    = new();
                BinaryWriter cacheData = new(stream);
                cacheData.Write(mapObjDef.NameSet);
                cacheData.Write(uniqueId);
                cacheData.WriteVector3(position);
                cacheData.WriteVector3(mapObjDef.Rotation);
                cacheData.Write(scale);
                cacheData.WriteVector3(bounds.Lo);
                cacheData.WriteVector3(bounds.Hi);
                cacheData.Write(wmoInstanceName.GetByteCount());
                cacheData.WriteString(wmoInstanceName);

                cacheModelData.Data = stream.ToArray();
                dirfileCache.Add(cacheModelData);
            }
        }
Beispiel #2
0
        public static void ExtractSet(WMODoodadData doodadData, MODF.SMMapObjDef wmo, bool isGlobalWmo, uint mapID, uint originalMapId, BinaryWriter writer, List <ADTOutputCache> dirfileCache)
        {
            if (doodadData == null)
            {
                return;
            }

            if (wmo.DoodadSet >= doodadData.Sets.Count)
            {
                return;
            }

            Vector3 wmoPosition = new(wmo.Position.Z, wmo.Position.X, wmo.Position.Y);
            Matrix3 wmoRotation = Matrix3.fromEulerAnglesZYX(MathFunctions.toRadians(wmo.Rotation.Y), MathFunctions.toRadians(wmo.Rotation.X), MathFunctions.toRadians(wmo.Rotation.Z));

            if (isGlobalWmo)
            {
                wmoPosition += new Vector3(533.33333f * 32, 533.33333f * 32, 0.0f);
            }

            ushort doodadId      = 0;
            MODS   doodadSetData = doodadData.Sets[wmo.DoodadSet];

            if (doodadData.Paths == null)
            {
                return;
            }

            using BinaryReader reader = new(new MemoryStream(doodadData.Paths));
            foreach (ushort doodadIndex in doodadData.References)
            {
                if (doodadIndex < doodadSetData.StartIndex ||
                    doodadIndex >= doodadSetData.StartIndex + doodadSetData.Count)
                {
                    continue;
                }

                MODD doodad = doodadData.Spawns[doodadIndex];

                reader.BaseStream.Position = doodad.NameIndex;
                string ModelInstName = reader.ReadCString().GetPlainName();

                if (ModelInstName.Length > 3)
                {
                    string extension = ModelInstName.Substring(ModelInstName.Length - 4);
                    if (extension == ".mdx" || extension == ".mdl")
                    {
                        ModelInstName  = ModelInstName.Remove(ModelInstName.Length - 2, 2);
                        ModelInstName += "2";
                    }
                }

                if (!File.Exists(Program.BuildingsDirectory + ModelInstName))
                {
                    continue;
                }

                using (BinaryReader binaryReader = new(File.Open(Program.BuildingsDirectory + ModelInstName, FileMode.Open, FileAccess.Read, FileShare.Read)))
                {
                    binaryReader.BaseStream.Seek(8, SeekOrigin.Begin); // get the correct no of vertices
                    int nVertices = binaryReader.ReadInt32();
                    if (nVertices == 0)
                    {
                        continue;
                    }
                }
                ++doodadId;

                Vector3 position = wmoPosition + (wmoRotation * new Vector3(doodad.Position.X, doodad.Position.Y, doodad.Position.Z));

                Vector3 rotation;
                (new Quaternion(doodad.Rotation.X, doodad.Rotation.Y, doodad.Rotation.Z, doodad.Rotation.W).ToRotationMatrix() * wmoRotation).toEulerAnglesXYZ(out rotation.Z, out rotation.X, out rotation.Y);

                rotation.Z = MathFunctions.toDegrees(rotation.Z);
                rotation.X = MathFunctions.toDegrees(rotation.X);
                rotation.Y = MathFunctions.toDegrees(rotation.Y);

                ushort nameSet  = 0;    // not used for models
                uint   uniqueId = VmapFile.GenerateUniqueObjectId(wmo.UniqueId, doodadId);
                uint   flags    = ModelFlags.M2;
                if (mapID != originalMapId)
                {
                    flags |= ModelFlags.ParentSpawn;
                }

                //write mapID, Flags, NameSet, UniqueId, Pos, Rot, Scale, name
                writer.Write(mapID);
                writer.Write(flags);
                writer.Write(nameSet);
                writer.Write(uniqueId);
                writer.WriteVector3(position);
                writer.WriteVector3(rotation);
                writer.Write(doodad.Scale);
                writer.Write(ModelInstName.GetByteCount());
                writer.WriteString(ModelInstName);

                if (dirfileCache != null)
                {
                    ADTOutputCache cacheModelData = new();
                    cacheModelData.Flags = flags & ~ModelFlags.ParentSpawn;

                    MemoryStream stream    = new();
                    BinaryWriter cacheData = new(stream);
                    cacheData.Write(nameSet);
                    cacheData.Write(uniqueId);
                    cacheData.WriteVector3(position);
                    cacheData.WriteVector3(rotation);
                    cacheData.Write(doodad.Scale);
                    cacheData.Write(ModelInstName.GetByteCount());
                    cacheData.WriteString(ModelInstName);

                    cacheModelData.Data = stream.ToArray();
                    dirfileCache.Add(cacheModelData);
                }
            }
        }