Ejemplo n.º 1
0
        public WMOContainer(Renderer.Structs.WorldModel wmo, string fileName) : base(fileName)
        {
            WorldModel        = wmo;
            EnabledGroups     = new bool[wmo.groupBatches.Length];
            EnabledDoodadSets = new bool[wmo.doodadSets.Length];

            // Is there no way to initialize an array of true bools?
            for (int i = 0; i < EnabledGroups.Length; i++)
            {
                EnabledGroups[i] = true;
            }

            for (int i = 0; i < EnabledDoodadSets.Length; i++)
            {
                EnabledDoodadSets[i] = true;
            }
        }
Ejemplo n.º 2
0
        public static Renderer.Structs.WorldModel LoadWMO(string filename, CacheStorage cache, int shaderProgram)
        {
            if (cache.worldModelBatches.ContainsKey(filename))
            {
                return(cache.worldModelBatches[filename]);
            }

            WoWFormatLib.Structs.WMO.WMO wmo = new WoWFormatLib.Structs.WMO.WMO();

            if (cache.worldModels.ContainsKey(filename))
            {
                wmo = cache.worldModels[filename];
            }
            else
            {
                //Load WMO from file
                if (WoWFormatLib.Utils.CASC.cascHandler.FileExists(filename))
                {
                    var wmoreader = new WMOReader();
                    wmoreader.LoadWMO(filename, false);
                    cache.worldModels.Add(filename, wmoreader.wmofile);
                    wmo = wmoreader.wmofile;
                }
                else
                {
                    throw new Exception("WMO " + filename + " does not exist!");
                }
            }

            if (wmo.group.Count() == 0)
            {
                throw new Exception("Broken WMO! Report to developer (mail [email protected]) with this filename: " + filename);
            }

            var wmobatch = new Renderer.Structs.WorldModel()
            {
                groupBatches = new Renderer.Structs.WorldModelGroupBatches[wmo.group.Count()]
            };

            string[] groupNames = new string[wmo.group.Count()];

            for (int g = 0; g < wmo.group.Count(); g++)
            {
                if (wmo.group[g].mogp.vertices == null)
                {
                    continue;
                }

                wmobatch.groupBatches[g].vao          = GL.GenVertexArray();
                wmobatch.groupBatches[g].vertexBuffer = GL.GenBuffer();
                wmobatch.groupBatches[g].indiceBuffer = GL.GenBuffer();

                GL.BindVertexArray(wmobatch.groupBatches[g].vao);

                GL.BindBuffer(BufferTarget.ArrayBuffer, wmobatch.groupBatches[g].vertexBuffer);

                Renderer.Structs.M2Vertex[] wmovertices = new Renderer.Structs.M2Vertex[wmo.group[g].mogp.vertices.Count()];

                for (int i = 0; i < wmo.groupNames.Count(); i++)
                {
                    if (wmo.group[g].mogp.nameOffset == wmo.groupNames[i].offset)
                    {
                        groupNames[g] = wmo.groupNames[i].name.Replace(" ", "_");
                    }
                }

                if (groupNames[g] == "antiportal")
                {
                    continue;
                }

                for (int i = 0; i < wmo.group[g].mogp.vertices.Count(); i++)
                {
                    wmovertices[i].Position = new Vector3(wmo.group[g].mogp.vertices[i].vector.X, wmo.group[g].mogp.vertices[i].vector.Y, wmo.group[g].mogp.vertices[i].vector.Z);
                    wmovertices[i].Normal   = new Vector3(wmo.group[g].mogp.normals[i].normal.X, wmo.group[g].mogp.normals[i].normal.Y, wmo.group[g].mogp.normals[i].normal.Z);
                    if (wmo.group[g].mogp.textureCoords[0] == null)
                    {
                        wmovertices[i].TexCoord = new Vector2(0.0f, 0.0f);
                    }
                    else
                    {
                        wmovertices[i].TexCoord = new Vector2(wmo.group[g].mogp.textureCoords[0][i].X, wmo.group[g].mogp.textureCoords[0][i].Y);
                    }
                }

                //Push to buffer
                GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(wmovertices.Length * 8 * sizeof(float)), wmovertices, BufferUsageHint.StaticDraw);

                //Set pointers in buffer
                //var normalAttrib = GL.GetAttribLocation(shaderProgram, "normal");
                //GL.EnableVertexAttribArray(normalAttrib);
                //GL.VertexAttribPointer(normalAttrib, 3, VertexAttribPointerType.Float, false, sizeof(float) * 8, sizeof(float) * 0);

                var texCoordAttrib = GL.GetAttribLocation(shaderProgram, "texCoord");
                GL.EnableVertexAttribArray(texCoordAttrib);
                GL.VertexAttribPointer(texCoordAttrib, 2, VertexAttribPointerType.Float, false, sizeof(float) * 8, sizeof(float) * 3);

                var posAttrib = GL.GetAttribLocation(shaderProgram, "position");
                GL.EnableVertexAttribArray(posAttrib);
                GL.VertexAttribPointer(posAttrib, 3, VertexAttribPointerType.Float, false, sizeof(float) * 8, sizeof(float) * 5);

                //Switch to Index buffer
                GL.BindBuffer(BufferTarget.ElementArrayBuffer, wmobatch.groupBatches[g].indiceBuffer);

                List <uint> wmoindicelist = new List <uint>();
                for (int i = 0; i < wmo.group[g].mogp.indices.Count(); i++)
                {
                    wmoindicelist.Add(wmo.group[g].mogp.indices[i].indice);
                }

                wmobatch.groupBatches[g].indices = wmoindicelist.ToArray();

                GL.BufferData(BufferTarget.ElementArrayBuffer, (IntPtr)(wmobatch.groupBatches[g].indices.Length * sizeof(uint)), wmobatch.groupBatches[g].indices, BufferUsageHint.StaticDraw);
            }

            GL.Enable(EnableCap.Texture2D);

            wmobatch.mats = new Renderer.Structs.Material[wmo.materials.Count()];
            for (int i = 0; i < wmo.materials.Count(); i++)
            {
                wmobatch.mats[i].texture1 = wmo.materials[i].texture1;
                wmobatch.mats[i].texture2 = wmo.materials[i].texture2;
                wmobatch.mats[i].texture3 = wmo.materials[i].texture3;

                for (int ti = 0; ti < wmo.textures.Count(); ti++)
                {
                    if (wmo.textures[ti].startOffset == wmo.materials[i].texture1)
                    {
                        wmobatch.mats[i].textureID1 = BLPLoader.LoadTexture(wmo.textures[ti].filename, cache);
                    }

                    if (wmo.textures[ti].startOffset == wmo.materials[i].texture2)
                    {
                        wmobatch.mats[i].textureID2 = BLPLoader.LoadTexture(wmo.textures[ti].filename, cache);
                    }

                    if (wmo.textures[ti].startOffset == wmo.materials[i].texture3)
                    {
                        wmobatch.mats[i].textureID3 = BLPLoader.LoadTexture(wmo.textures[ti].filename, cache);
                    }
                }
            }

            wmobatch.doodads = new Renderer.Structs.WMODoodad[wmo.doodadDefinitions.Count()];

            for (int i = 0; i < wmo.doodadDefinitions.Count(); i++)
            {
                for (int j = 0; j < wmo.doodadNames.Count(); j++)
                {
                    if (wmo.doodadDefinitions[i].offset == wmo.doodadNames[j].startOffset)
                    {
                        wmobatch.doodads[i].filename = wmo.doodadNames[j].filename;
                        //M2Loader.LoadM2(wmobatch.doodads[i].filename, cache);
                    }
                }
                wmobatch.doodads[i].flags    = wmo.doodadDefinitions[i].flags;
                wmobatch.doodads[i].position = new Vector3(wmo.doodadDefinitions[i].position.X, wmo.doodadDefinitions[i].position.Y, wmo.doodadDefinitions[i].position.Z);
                wmobatch.doodads[i].rotation = new Quaternion(wmo.doodadDefinitions[i].rotation.X, wmo.doodadDefinitions[i].rotation.Y, wmo.doodadDefinitions[i].rotation.Z, wmo.doodadDefinitions[i].rotation.W);
                wmobatch.doodads[i].scale    = wmo.doodadDefinitions[i].scale;
                wmobatch.doodads[i].color    = new Vector4(wmo.doodadDefinitions[i].color[0], wmo.doodadDefinitions[i].color[1], wmo.doodadDefinitions[i].color[2], wmo.doodadDefinitions[i].color[3]);
            }

            int numRenderbatches = 0;

            //Get total amount of render batches
            for (int i = 0; i < wmo.group.Count(); i++)
            {
                if (wmo.group[i].mogp.renderBatches == null)
                {
                    continue;
                }
                numRenderbatches = numRenderbatches + wmo.group[i].mogp.renderBatches.Count();
            }

            wmobatch.wmoRenderBatch = new Renderer.Structs.RenderBatch[numRenderbatches];

            int rb = 0;

            for (int g = 0; g < wmo.group.Count(); g++)
            {
                var group = wmo.group[g];
                if (group.mogp.renderBatches == null)
                {
                    continue;
                }
                for (int i = 0; i < group.mogp.renderBatches.Count(); i++)
                {
                    wmobatch.wmoRenderBatch[rb].firstFace = group.mogp.renderBatches[i].firstFace;
                    wmobatch.wmoRenderBatch[rb].numFaces  = group.mogp.renderBatches[i].numFaces;
                    uint matID = 0;

                    if (group.mogp.renderBatches[i].flags == 2)
                    {
                        matID = (uint)group.mogp.renderBatches[i].possibleBox2_3;
                    }
                    else
                    {
                        matID = group.mogp.renderBatches[i].materialID;
                    }

                    wmobatch.wmoRenderBatch[rb].materialID = new uint[3];
                    for (int ti = 0; ti < wmobatch.mats.Count(); ti++)
                    {
                        if (wmo.materials[matID].texture1 == wmobatch.mats[ti].texture1)
                        {
                            wmobatch.wmoRenderBatch[rb].materialID[0] = (uint)wmobatch.mats[ti].textureID1;
                        }

                        if (wmo.materials[matID].texture2 == wmobatch.mats[ti].texture2)
                        {
                            wmobatch.wmoRenderBatch[rb].materialID[1] = (uint)wmobatch.mats[ti].textureID2;
                        }

                        if (wmo.materials[matID].texture3 == wmobatch.mats[ti].texture3)
                        {
                            wmobatch.wmoRenderBatch[rb].materialID[2] = (uint)wmobatch.mats[ti].textureID3;
                        }
                    }

                    wmobatch.wmoRenderBatch[rb].blendType = wmo.materials[matID].blendMode;
                    wmobatch.wmoRenderBatch[rb].groupID   = (uint)g;
                    rb++;
                }
            }
            cache.worldModelBatches.Add(filename, wmobatch);

            return(wmobatch);
        }
Ejemplo n.º 3
0
        public static Renderer.Structs.WorldModel LoadWMO(string fileName, int shaderProgram)
        {
            if (!Listfile.TryGetFileDataID(fileName, out uint fileDataID))
            {
                CASCLib.Logger.WriteLine("Could not get filedataid for " + fileName);
            }

            if (!WoWFormatLib.Utils.CASC.FileExists(fileDataID))
            {
                throw new Exception("WMO " + fileName + " does not exist!");
            }

            WMO wmo = new WMOReader().LoadWMO(fileDataID, 0, fileName);

            if (wmo.group.Count() == 0)
            {
                CASCLib.Logger.WriteLine("WMO has no groups: ", fileName);
                throw new Exception("Broken WMO! Report to developer (mail [email protected]) with this filename: " + fileName);
            }

            var wmoBatch = new Renderer.Structs.WorldModel()
            {
                groupBatches = new Renderer.Structs.WorldModelGroupBatches[wmo.group.Count()]
            };

            for (var g = 0; g < wmo.group.Count(); g++)
            {
                if (wmo.group[g].mogp.vertices == null)
                {
                    continue;
                }

                wmoBatch.groupBatches[g].vao          = GL.GenVertexArray();
                wmoBatch.groupBatches[g].vertexBuffer = GL.GenBuffer();
                wmoBatch.groupBatches[g].indiceBuffer = GL.GenBuffer();

                GL.BindVertexArray(wmoBatch.groupBatches[g].vao);
                GL.BindBuffer(BufferTarget.ArrayBuffer, wmoBatch.groupBatches[g].vertexBuffer);

                var wmovertices = new Renderer.Structs.M2Vertex[wmo.group[g].mogp.vertices.Count()];

                string groupName = null;
                for (var i = 0; i < wmo.groupNames.Count(); i++)
                {
                    if (wmo.group[g].mogp.nameOffset == wmo.groupNames[i].offset)
                    {
                        groupName = wmo.groupNames[i].name.Replace(" ", "_");
                    }
                }

                if (groupName == "antiportal")
                {
                    continue;
                }

                wmoBatch.groupBatches[g].groupName = groupName;

                for (var i = 0; i < wmo.group[g].mogp.vertices.Count(); i++)
                {
                    wmovertices[i].Position = new Vector3(wmo.group[g].mogp.vertices[i].vector.X, wmo.group[g].mogp.vertices[i].vector.Y, wmo.group[g].mogp.vertices[i].vector.Z);
                    wmovertices[i].Normal   = new Vector3(wmo.group[g].mogp.normals[i].normal.X, wmo.group[g].mogp.normals[i].normal.Y, wmo.group[g].mogp.normals[i].normal.Z);
                    if (wmo.group[g].mogp.textureCoords[0] == null)
                    {
                        wmovertices[i].TexCoord = new Vector2(0.0f, 0.0f);
                    }
                    else
                    {
                        wmovertices[i].TexCoord = new Vector2(wmo.group[g].mogp.textureCoords[0][i].X, wmo.group[g].mogp.textureCoords[0][i].Y);
                    }
                }

                //Push to buffer
                GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(wmovertices.Length * 8 * sizeof(float)), wmovertices, BufferUsageHint.StaticDraw);

                //Set pointers in buffer
                //var normalAttrib = GL.GetAttribLocation(shaderProgram, "normal");
                //GL.EnableVertexAttribArray(normalAttrib);
                //GL.VertexAttribPointer(normalAttrib, 3, VertexAttribPointerType.Float, false, sizeof(float) * 8, sizeof(float) * 0);

                var texCoordAttrib = GL.GetAttribLocation(shaderProgram, "texCoord");
                GL.EnableVertexAttribArray(texCoordAttrib);
                GL.VertexAttribPointer(texCoordAttrib, 2, VertexAttribPointerType.Float, false, sizeof(float) * 8, sizeof(float) * 3);

                var posAttrib = GL.GetAttribLocation(shaderProgram, "position");
                GL.EnableVertexAttribArray(posAttrib);
                GL.VertexAttribPointer(posAttrib, 3, VertexAttribPointerType.Float, false, sizeof(float) * 8, sizeof(float) * 5);

                //Switch to Index buffer
                GL.BindBuffer(BufferTarget.ElementArrayBuffer, wmoBatch.groupBatches[g].indiceBuffer);

                var wmoindicelist = new List <uint>();
                for (var i = 0; i < wmo.group[g].mogp.indices.Count(); i++)
                {
                    wmoindicelist.Add(wmo.group[g].mogp.indices[i].indice);
                }

                wmoBatch.groupBatches[g].indices = wmoindicelist.ToArray();

                GL.BufferData(BufferTarget.ElementArrayBuffer, (IntPtr)(wmoBatch.groupBatches[g].indices.Length * sizeof(uint)), wmoBatch.groupBatches[g].indices, BufferUsageHint.StaticDraw);
            }

            GL.Enable(EnableCap.Texture2D);

            wmoBatch.mats = new Renderer.Structs.Material[wmo.materials.Count()];
            for (var i = 0; i < wmo.materials.Count(); i++)
            {
                wmoBatch.mats[i].texture1 = wmo.materials[i].texture1;
                wmoBatch.mats[i].texture2 = wmo.materials[i].texture2;
                wmoBatch.mats[i].texture3 = wmo.materials[i].texture3;

                if (wmo.textures == null)
                {
                    if (WoWFormatLib.Utils.CASC.FileExists(wmo.materials[i].texture1))
                    {
                        wmoBatch.mats[i].textureID1 = BLPLoader.LoadTexture(wmo.materials[i].texture1);
                    }

                    if (WoWFormatLib.Utils.CASC.FileExists(wmo.materials[i].texture2))
                    {
                        wmoBatch.mats[i].textureID2 = BLPLoader.LoadTexture(wmo.materials[i].texture2);
                    }

                    if (WoWFormatLib.Utils.CASC.FileExists(wmo.materials[i].texture3))
                    {
                        wmoBatch.mats[i].textureID3 = BLPLoader.LoadTexture(wmo.materials[i].texture3);
                    }
                }
                else
                {
                    for (var ti = 0; ti < wmo.textures.Count(); ti++)
                    {
                        if (wmo.textures[ti].startOffset == wmo.materials[i].texture1)
                        {
                            wmoBatch.mats[i].textureID1 = BLPLoader.LoadTexture(wmo.textures[ti].filename);
                        }

                        if (wmo.textures[ti].startOffset == wmo.materials[i].texture2)
                        {
                            wmoBatch.mats[i].textureID2 = BLPLoader.LoadTexture(wmo.textures[ti].filename);
                        }

                        if (wmo.textures[ti].startOffset == wmo.materials[i].texture3)
                        {
                            wmoBatch.mats[i].textureID3 = BLPLoader.LoadTexture(wmo.textures[ti].filename);
                        }
                    }
                }
            }

            // Store all of the doodad set names for the WMO.
            wmoBatch.doodadSets = new string[wmo.doodadSets.Length];
            for (uint i = 0; i < wmo.doodadSets.Length; i++)
            {
                wmoBatch.doodadSets[i] = wmo.doodadSets[i].setName;
            }

            wmoBatch.doodads = new Renderer.Structs.WMODoodad[wmo.doodadDefinitions.Count()];
            for (var i = 0; i < wmo.doodadDefinitions.Count(); i++)
            {
                if (wmo.doodadNames != null)
                {
                    for (var j = 0; j < wmo.doodadNames.Count(); j++)
                    {
                        if (wmo.doodadDefinitions[i].offset == wmo.doodadNames[j].startOffset)
                        {
                            wmoBatch.doodads[i].filename = wmo.doodadNames[j].filename;
                        }
                    }
                }
                else
                {
                    wmoBatch.doodads[i].filedataid = wmo.doodadDefinitions[i].offset;
                }

                wmoBatch.doodads[i].flags     = wmo.doodadDefinitions[i].flags;
                wmoBatch.doodads[i].position  = new Vector3(wmo.doodadDefinitions[i].position.X, wmo.doodadDefinitions[i].position.Y, wmo.doodadDefinitions[i].position.Z);
                wmoBatch.doodads[i].rotation  = new Quaternion(wmo.doodadDefinitions[i].rotation.X, wmo.doodadDefinitions[i].rotation.Y, wmo.doodadDefinitions[i].rotation.Z, wmo.doodadDefinitions[i].rotation.W);
                wmoBatch.doodads[i].scale     = wmo.doodadDefinitions[i].scale;
                wmoBatch.doodads[i].color     = new Vector4(wmo.doodadDefinitions[i].color[0], wmo.doodadDefinitions[i].color[1], wmo.doodadDefinitions[i].color[2], wmo.doodadDefinitions[i].color[3]);
                wmoBatch.doodads[i].doodadSet = 0; // Default to 0.

                // Search all the doodadSets to see which one this doodad falls into.
                for (uint j = 0; j < wmo.doodadSets.Length; j++)
                {
                    var doodadSet = wmo.doodadSets[j];
                    if (i >= doodadSet.firstInstanceIndex && i < doodadSet.firstInstanceIndex + doodadSet.numDoodads)
                    {
                        wmoBatch.doodads[i].doodadSet = j;
                        break; // Assumingly, a doodad cannot be in more than one doodadSet.
                    }
                }
            }

            var numRenderbatches = 0;

            //Get total amount of render batches
            for (var i = 0; i < wmo.group.Count(); i++)
            {
                if (wmo.group[i].mogp.renderBatches == null)
                {
                    continue;
                }
                numRenderbatches = numRenderbatches + wmo.group[i].mogp.renderBatches.Count();
            }

            wmoBatch.wmoRenderBatch = new Renderer.Structs.RenderBatch[numRenderbatches];

            var rb = 0;

            for (var g = 0; g < wmo.group.Count(); g++)
            {
                var group = wmo.group[g];
                if (group.mogp.renderBatches == null)
                {
                    continue;
                }
                for (var i = 0; i < group.mogp.renderBatches.Count(); i++)
                {
                    wmoBatch.wmoRenderBatch[rb].firstFace = group.mogp.renderBatches[i].firstFace;
                    wmoBatch.wmoRenderBatch[rb].numFaces  = group.mogp.renderBatches[i].numFaces;
                    uint matID = 0;

                    if (group.mogp.renderBatches[i].flags == 2)
                    {
                        matID = (uint)group.mogp.renderBatches[i].possibleBox2_3;
                    }
                    else
                    {
                        matID = group.mogp.renderBatches[i].materialID;
                    }

                    wmoBatch.wmoRenderBatch[rb].materialID = new uint[3];
                    for (var ti = 0; ti < wmoBatch.mats.Count(); ti++)
                    {
                        if (wmo.materials[matID].texture1 == wmoBatch.mats[ti].texture1)
                        {
                            wmoBatch.wmoRenderBatch[rb].materialID[0] = (uint)wmoBatch.mats[ti].textureID1;
                        }

                        if (wmo.materials[matID].texture2 == wmoBatch.mats[ti].texture2)
                        {
                            wmoBatch.wmoRenderBatch[rb].materialID[1] = (uint)wmoBatch.mats[ti].textureID2;
                        }

                        if (wmo.materials[matID].texture3 == wmoBatch.mats[ti].texture3)
                        {
                            wmoBatch.wmoRenderBatch[rb].materialID[2] = (uint)wmoBatch.mats[ti].textureID3;
                        }
                    }

                    wmoBatch.wmoRenderBatch[rb].blendType = wmo.materials[matID].blendMode;
                    wmoBatch.wmoRenderBatch[rb].groupID   = (uint)g;
                    rb++;
                }
            }

            return(wmoBatch);
        }