Exemple #1
0
        /**************************************************************************/
        public bool loadVMap(uint mapID, uint tileX, uint tileY, MeshData meshData)
        {
            bool result = vmapManager.LoadSingleMap(mapID, "vmaps", tileX, tileY);
            bool retval = false;

            do
            {
                if (!result)
                {
                    break;
                }

                Dictionary <uint, StaticMapTree> instanceTrees;
                vmapManager.GetInstanceMapTree(out instanceTrees);

                if (instanceTrees[mapID] == null)
                {
                    break;
                }

                ModelInstance[] models = null;
                uint            count;
                instanceTrees[mapID].GetModelInstances(out models, out count);

                if (models == null)
                {
                    break;
                }

                for (uint i = 0; i < count; ++i)
                {
                    ModelInstance instance = models[i];
                    if (instance == null)
                    {
                        continue;
                    }

                    // model instances exist in tree even though there are instances of that model in this tile
                    WorldModel worldModel = instance.GetWorldModel();
                    if (worldModel == null)
                    {
                        continue;
                    }

                    // now we have a model to add to the meshdata
                    retval = true;

                    List <GroupModel> groupModels;
                    worldModel.getGroupModels(out groupModels);

                    // all M2s need to have triangle indices reversed
                    bool isM2 = (instance.flags & ModelFlags.M2) != 0;

                    // transform data
                    float   scale    = instance.iScale;
                    Matrix3 rotation = Matrix3.fromEulerAnglesXYZ(MathF.PI * instance.iRot.Z / -180.0f, MathF.PI * instance.iRot.X / -180.0f, MathF.PI * instance.iRot.Y / -180.0f);
                    Vector3 position = instance.iPos;
                    position.X -= 32 * SharedConst.GRID_SIZE;
                    position.Y -= 32 * SharedConst.GRID_SIZE;

                    foreach (var it in groupModels)
                    {
                        List <Vector3>      tempVertices;
                        List <Vector3>      transformedVertices = new List <Vector3>();
                        List <MeshTriangle> tempTriangles;
                        WmoLiquid           liquid = null;

                        it.GetMeshData(out tempVertices, out tempTriangles, out liquid);

                        // first handle collision mesh
                        transform(tempVertices.ToArray(), transformedVertices, scale, rotation, position);

                        int offset = meshData.solidVerts.Count / 3;

                        copyVertices(transformedVertices.ToArray(), meshData.solidVerts);
                        copyIndices(tempTriangles, meshData.solidTris, offset, isM2);

                        // now handle liquid data
                        if (liquid != null && liquid.iFlags != null)
                        {
                            List <Vector3> liqVerts = new List <Vector3>();
                            List <uint>    liqTris = new List <uint>();
                            uint           tilesX, tilesY, vertsX, vertsY;
                            Vector3        corner;
                            liquid.GetPosInfo(out tilesX, out tilesY, out corner);
                            vertsX = tilesX + 1;
                            vertsY = tilesY + 1;
                            byte[]  flags = liquid.iFlags;
                            float[] data  = liquid.iHeight;
                            NavArea type  = NavArea.Empty;

                            // convert liquid type to NavTerrain
                            var  liquidTypeRecord = liquidTypeStorage.LookupByKey(liquid.GetLiquidType());
                            uint liquidFlags      = (uint)(liquidTypeRecord != null ? (1 << liquidTypeRecord.SoundBank) : 0);
                            if ((liquidFlags & (uint)(LiquidTypeMask.Water | LiquidTypeMask.Ocean)) != 0)
                            {
                                type = NavArea.Water;
                            }
                            else if ((liquidFlags & (uint)(LiquidTypeMask.Magma | LiquidTypeMask.Slime)) != 0)
                            {
                                type = NavArea.MagmaSlime;
                            }

                            // indexing is weird...
                            // after a lot of trial and error, this is what works:
                            // vertex = y*vertsX+x
                            // tile   = x*tilesY+y
                            // flag   = y*tilesY+x

                            Vector3 vert;
                            for (uint x = 0; x < vertsX; ++x)
                            {
                                for (uint y = 0; y < vertsY; ++y)
                                {
                                    vert    = new Vector3(corner.X + x * SharedConst.GRID_PART_SIZE, corner.Y + y * SharedConst.GRID_PART_SIZE, data[y * vertsX + x]);
                                    vert    = vert * rotation * scale + position;
                                    vert.X *= -1.0f;
                                    vert.Y *= -1.0f;
                                    liqVerts.Add(vert);
                                }
                            }

                            uint idx1, idx2, idx3, idx4;
                            uint square;
                            for (uint x = 0; x < tilesX; ++x)
                            {
                                for (uint y = 0; y < tilesY; ++y)
                                {
                                    if ((flags[x + y * tilesX] & 0x0f) != 0x0f)
                                    {
                                        square = x * tilesY + y;
                                        idx1   = square + x;
                                        idx2   = square + 1 + x;
                                        idx3   = square + tilesY + 1 + 1 + x;
                                        idx4   = square + tilesY + 1 + x;

                                        // top triangle
                                        liqTris.Add(idx3);
                                        liqTris.Add(idx2);
                                        liqTris.Add(idx1);
                                        // bottom triangle
                                        liqTris.Add(idx4);
                                        liqTris.Add(idx3);
                                        liqTris.Add(idx1);
                                    }
                                }
                            }

                            int liqOffset = meshData.liquidVerts.Count / 3;
                            for (int x = 0; x < liqVerts.Count; ++x)
                            {
                                meshData.liquidVerts.Add(liqVerts[x].Y);
                                meshData.liquidVerts.Add(liqVerts[x].Z);
                                meshData.liquidVerts.Add(liqVerts[x].X);
                            }

                            for (int x = 0; x < liqTris.Count / 3; ++x)
                            {
                                meshData.liquidTris.Add((int)(liqTris[x * 3 + 1] + liqOffset));
                                meshData.liquidTris.Add((int)(liqTris[x * 3 + 2] + liqOffset));
                                meshData.liquidTris.Add((int)(liqTris[x * 3] + liqOffset));
                                meshData.liquidType.Add((byte)type);
                            }
                        }
                    }
                }
            }while (false);

            vmapManager.UnloadSingleMap(mapID, tileX, tileY);

            return(retval);
        }
Exemple #2
0
        public bool Read(BinaryReader reader)
        {
            mogpflags  = reader.ReadUInt32();
            GroupWMOID = reader.ReadUInt32();

            Vector3 vec1 = reader.Read <Vector3>();
            Vector3 vec2 = reader.Read <Vector3>();

            bounds = new AxisAlignedBox(vec1, vec2);

            liquidflags = reader.ReadUInt32();

            string blockId = reader.ReadStringFromChars(4);

            if (blockId != "GRP ")
            {
                Console.WriteLine($"Error: {blockId} != GRP ");
                return(false);
            }
            int  blocksize = reader.ReadInt32();
            uint branches  = reader.ReadUInt32();

            for (uint b = 0; b < branches; ++b)
            {
                // indexes for each branch (not used yet)
                uint indexes = reader.ReadUInt32();
            }

            // ---- indexes
            blockId = reader.ReadStringFromChars(4);
            if (blockId != "INDX")
            {
                Console.WriteLine($"Error: {blockId} != INDX");
                return(false);
            }
            blocksize = reader.ReadInt32();
            uint nindexes = reader.ReadUInt32();

            if (nindexes > 0)
            {
                ushort[] indexarray = new ushort[nindexes];
                for (var i = 0; i < nindexes; ++i)
                {
                    indexarray[i] = reader.ReadUInt16();
                }

                for (uint i = 0; i < nindexes; i += 3)
                {
                    triangles.Add(new MeshTriangle(indexarray[i], indexarray[i + 1], indexarray[i + 2]));
                }
            }

            // ---- vectors
            blockId = reader.ReadStringFromChars(4);
            if (blockId != "VERT")
            {
                Console.WriteLine($"Error: {blockId} != VERT");
                return(false);
            }
            blocksize = reader.ReadInt32();

            uint nvectors = reader.ReadUInt32();

            if (nvectors > 0)
            {
                float[] vectorarray = new float[nvectors * 3];
                for (var i = 0; i < nvectors * 3; ++i)
                {
                    vectorarray[i] = reader.ReadSingle();
                }

                vertexArray = new List <Vector3>();
                for (uint i = 0; i < nvectors; ++i)
                {
                    vertexArray.Add(new Vector3(vectorarray[3 * i], vectorarray[3 * i + 1], vectorarray[3 * i + 2]));
                }
            }

            // ----- liquid
            liquid = null;
            if (Convert.ToBoolean(liquidflags & 3))
            {
                blockId = reader.ReadStringFromChars(4);
                if (blockId != "LIQU")
                {
                    Console.WriteLine($"Error: {blockId} != LIQU");
                    return(false);
                }
                blocksize = reader.ReadInt32();
                uint liquidType = reader.ReadUInt32();
                if (Convert.ToBoolean(liquidflags & 1))
                {
                    WMOLiquidHeader hlq = reader.Read <WMOLiquidHeader>();
                    liquid = new WmoLiquid((uint)hlq.xtiles, (uint)hlq.ytiles, new Vector3(hlq.pos_x, hlq.pos_y, hlq.pos_z), liquidType);
                    int size = hlq.xverts * hlq.yverts;
                    liquid.iHeight = new float[size];
                    for (var i = 0; i < size; ++i)
                    {
                        liquid.iHeight[i] = reader.ReadSingle();
                    }

                    size          = hlq.xtiles * hlq.ytiles;
                    liquid.iFlags = new byte[size];
                    for (var i = 0; i < size; ++i)
                    {
                        liquid.iFlags[i] = reader.ReadByte();
                    }
                }
                else
                {
                    liquid            = new WmoLiquid(0, 0, Vector3.Zero, liquidType);
                    liquid.iHeight[0] = bounds.Hi.Z;
                }
            }

            return(true);
        }