Beispiel #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);
        }