Exemple #1
0
        /// <summary>
        /// Loads the data into the mesh buffers, overwriting existing content.
        /// </summary>
        /// <param name="data">The data to load.</param>
        /// <returns>True if the load was successful.</returns>
        public bool Load(PolyMeshDetailData data)
        {
            if (IsDisposed ||
                data == null ||
                data.meshes == null ||
                data.tris == null ||
                data.verts == null ||
                data.meshCount < 0 || data.meshCount > mMaxMeshes ||
                data.triCount < 0 || data.triCount > mMaxTris ||
                data.vertCount < 0 || data.vertCount > mMaxVerts ||
                data.meshes.Length < data.meshCount * 4 ||
                data.tris.Length < data.triCount * 4 ||
                data.verts.Length < data.vertCount)
            {
                return(false);
            }

            mMeshCount = data.meshCount;
            mTriCount  = data.triCount;
            mVertCount = data.vertCount;

            UtilEx.Copy(data.meshes, 0, mMeshes, mMeshCount * 4);
            Marshal.Copy(data.tris, 0, mTris, mTriCount * 4);
            float[] fverts = Vector3Util.Flatten(data.verts, mVertCount);
            Marshal.Copy(fverts, 0, mVerts, mVertCount * 3);

            return(true);
        }
Exemple #2
0
        private void FillData(PolyMeshDetailData buffer)
        {
            buffer.vertCount = mVertCount;
            buffer.triCount  = mTriCount;
            buffer.meshCount = mMeshCount;

            float[] fverts = new float[mVertCount * 3];
            Marshal.Copy(mVerts, fverts, 0, mVertCount * 3);
            buffer.verts = Vector3Util.GetVectors(fverts, 0, buffer.verts, 0, mVertCount);
            Marshal.Copy(mTris, buffer.tris, 0, mTriCount * 4);
            UtilEx.Copy(mMeshes, buffer.meshes, mMeshCount * 4);
        }
Exemple #3
0
        /// <summary>
        /// Gets the data from the mesh buffers.
        /// </summary>
        /// <remarks>
        /// <para>
        /// This method is useful for extracting mesh data so it can be inspected or altered and
        /// reloaded.
        /// </para>
        /// </remarks>
        /// <param name="includeBuffer">
        /// If true, includes the unused buffer space.  Otherwise only the used buffer data is
        /// returned.
        /// </param>
        /// <returns>The data from the mesh buffers.</returns>
        public PolyMeshDetailData GetData(bool includeBuffer)
        {
            if (IsDisposed)
            {
                return(null);
            }

            PolyMeshDetailData result = new PolyMeshDetailData(
                (includeBuffer ? mMaxVerts : mVertCount)
                , (includeBuffer ? mMaxTris : mTriCount)
                , (includeBuffer ? mMaxMeshes : mMeshCount));

            FillData(result);

            return(result);
        }
Exemple #4
0
        /// <summary>
        /// Loads the data from the mesh buffers into the data object.
        /// </summary>
        /// <remarks>
        /// <para>
        /// If the buffer argument is null, a new buffer will be returned. If the buffer is too
        /// small it will be resized.
        /// </para>
        /// <para>
        /// Only the used portions of the mesh buffers are copied.
        /// </para>
        /// </remarks>
        /// <param name="buffer">A buffer to load the data into.</param>
        /// <returns>A reference to the mesh data.</returns>
        public PolyMeshDetailData GetData(PolyMeshDetailData buffer)
        {
            if (IsDisposed)
            {
                return(null);
            }
            if (buffer == null)
            {
                return(GetData(true));
            }

            if (!buffer.CanFit(mVertCount, mTriCount, mMeshCount))
            {
                buffer.Reset(mMaxVerts, mMaxTris, mMaxMeshes);
            }

            FillData(buffer);

            return(buffer);
        }
        private void FillData(PolyMeshDetailData buffer)
        {
            buffer.vertCount = mVertCount;
            buffer.triCount = mTriCount;
            buffer.meshCount = mMeshCount;

            float[] fverts = new float[mVertCount * 3];
            Marshal.Copy(mVerts, fverts, 0, mVertCount * 3);
            buffer.verts = Vector3Util.GetVectors(fverts, 0, buffer.verts, 0, mVertCount);
            Marshal.Copy(mTris, buffer.tris, 0, mTriCount * 4);
            UtilEx.Copy(mMeshes, buffer.meshes, mMeshCount * 4);
        }
        /// <summary>
        /// Loads the data into the mesh buffers, overwriting existing content.
        /// </summary>
        /// <param name="data">The data to load.</param>
        /// <returns>True if the load was successful.</returns>
        public bool Load(PolyMeshDetailData data)
        {
            if (IsDisposed
                || data == null
                || data.meshes == null
                || data.tris == null
                || data.verts == null
                || data.meshCount < 0 || data.meshCount > mMaxMeshes
                || data.triCount < 0 || data.triCount > mMaxTris
                || data.vertCount < 0 || data.vertCount > mMaxVerts
                || data.meshes.Length < data.meshCount * 4
                || data.tris.Length < data.triCount * 4
                || data.verts.Length < data.vertCount)
            {
                return false;
            }

            mMeshCount = data.meshCount;
            mTriCount = data.triCount;
            mVertCount = data.vertCount;

            UtilEx.Copy(data.meshes, 0, mMeshes, mMeshCount * 4);
            Marshal.Copy(data.tris, 0, mTris, mTriCount * 4);
            float[] fverts = Vector3Util.Flatten(data.verts, mVertCount);
            Marshal.Copy(fverts, 0, mVerts, mVertCount * 3);

            return true;
        }
        /// <summary>
        /// Loads the data from the mesh buffers into the data object.
        /// </summary>
        /// <remarks>
        /// <para>
        /// If the buffer argument is null, a new buffer will be returned. If the buffer is too 
        /// small it will be resized.
        /// </para>
        /// <para>
        /// Only the used portions of the mesh buffers are copied.
        /// </para>
        /// </remarks>
        /// <param name="buffer">A buffer to load the data into.</param>
        /// <returns>A reference to the mesh data.</returns>
        public PolyMeshDetailData GetData(PolyMeshDetailData buffer)
        {
            if (IsDisposed)
                return null;
            if (buffer == null)
                return GetData(true);

            if (!buffer.CanFit(mVertCount, mTriCount, mMeshCount))
                buffer.Reset(mMaxVerts, mMaxTris, mMaxMeshes);

            FillData(buffer);

            return buffer;
        }
        /// <summary>
        /// Gets the data from the mesh buffers.
        /// </summary>
        /// <remarks>
        /// <para>
        /// This method is useful for extracting mesh data so it can be inspected or altered and 
        /// reloaded.
        /// </para>
        /// </remarks>
        /// <param name="includeBuffer">
        /// If true, includes the unused buffer space.  Otherwise only the used buffer data is 
        /// returned.
        /// </param>
        /// <returns>The data from the mesh buffers.</returns>
        public PolyMeshDetailData GetData(bool includeBuffer)
        {
            if (IsDisposed)
                return null;

            PolyMeshDetailData result = new PolyMeshDetailData(
                (includeBuffer ? mMaxVerts : mVertCount)
                , (includeBuffer ? mMaxTris : mTriCount)
                , (includeBuffer ? mMaxMeshes : mMeshCount));

            FillData(result);

            return result;
        }
        /// <summary>
        /// Draws a debug view of a <see cref="PolyMeshDetailData"/> object.
        /// </summary>
        /// <remarks>
        /// <para>
        /// Meant to be called during the MonoBehavior.OnRenderObject() method.
        /// </para>
        /// </remarks>
        /// <param name="detailData">The detail mesh to draw.</param>
        public static void Draw(PolyMeshDetailData detailData)
        {
            DebugDraw.SimpleMaterial.SetPass(0);

            GL.Begin(GL.TRIANGLES);
            for (int iMesh = 0; iMesh < detailData.meshCount; iMesh++)
            {
                GL.Color(ColorUtil.IntToColor(iMesh, 0.75f));

                int pMesh = iMesh * 4;
                int pVertBase = (int)detailData.meshes[pMesh + 0];
                int pTriBase = (int)detailData.meshes[pMesh + 2] * 4;
                int tCount = (int)detailData.meshes[pMesh + 3];

                for (int iTri = 0; iTri < tCount; iTri++)
                {
                    for (int iVert = 0; iVert < 3; iVert++)
                    {
                        int pVert = pVertBase
                            + (detailData.tris[pTriBase + (iTri * 4 + iVert)]);

                        GL.Vertex(detailData.verts[pVert]);
                    }
                }
            }
            GL.End();

            // Draw the triangle lines.

            GL.Begin(GL.LINES);
            Color portalColor = new Color(0, 0, 0, 0.25f);
            for (int iMesh = 0; iMesh < detailData.meshCount; iMesh++)
            {
                Color meshColor = ColorUtil.IntToColor(iMesh, 1.0f);

                int pMesh = iMesh * 4;
                int pVertBase = (int)detailData.meshes[pMesh + 0];
                int pTriBase = (int)detailData.meshes[pMesh + 2] * 4;
                int tCount = (int)detailData.meshes[pMesh + 3];

                for (int iTri = 0; iTri < tCount; iTri++)
                {
                    byte flags = detailData.tris[pTriBase + (iTri * 4 + 3)];
                    for (int iVert = 0, iPrevVert = 2
                        ; iVert < 3
                        ; iPrevVert = iVert++)
                    {
                        if (((flags >> (iPrevVert * 2)) & 0x3) == 0)
                            GL.Color(meshColor);
                        else
                            GL.Color(portalColor);

                        int pVert = pVertBase
                            + (detailData.tris[pTriBase + (iTri * 4 + iVert)]);
                        int pPrevVert = pVertBase
                            + (detailData.tris[pTriBase + (iTri * 4 + iPrevVert)]);

                        GL.Vertex(detailData.verts[pVert]);
                        GL.Vertex(detailData.verts[pPrevVert]);
                    }
                }
            }
            GL.End();
        }
        /// <summary>
        /// Creates a standard <see cref="NavmeshTileBuildData"/> object from the provided
        /// parameters.
        /// </summary>
        /// <remarks>
        /// <para>
        /// Errors will be logged to the build context.
        /// </para>
        /// </remarks>
        /// <param name="tx">The x-index of the tile.</param>
        /// <param name="tz">The z-index of the tile.</param>
        /// <param name="polyMesh">The polygon mesh data.</param>
        /// <param name="detailMesh">The detail mesh data. (Optional)</param>
        /// <param name="connections">The off-mesh connections. (Null allowed.)</param>
        /// <param name="bvTreeEnabled">True if bounding volumes should be generated.</param>
        /// <param name="context">The build context.</param>
        /// <returns>The tile build data, or null on error.</returns>
        public static NavmeshTileBuildData GetBuildData(BuildContext context
            , int tx, int tz
            , PolyMeshData polyMesh, PolyMeshDetailData detailMesh
            , ConnectionSet connections
            , bool bvTreeEnabled)
        {
            if (context == null)
                // Silent.
                return null;

            Vector3[] verts = null;
            float[] radii = null;
            byte[] dirs = null;
            byte[] areas = null;
            ushort[] flags = null;
            uint[] userIds = null;

            Vector3 bmin = polyMesh.boundsMin;
            Vector3 bmax = polyMesh.boundsMax;

            int connCount = (connections == null)
                ? 0
                : connections.GetConnections(bmin.x, bmin.z, bmax.x, bmax.z
                    , out verts, out radii, out dirs, out areas, out flags, out userIds);

            NavmeshTileBuildData result = new NavmeshTileBuildData(
                    polyMesh.vertCount
                    , polyMesh.polyCount
                    , polyMesh.maxVertsPerPoly
                    , (detailMesh == null ? 0 : detailMesh.vertCount)
                    , (detailMesh == null ? 0 : detailMesh.triCount)
                    , connCount);

            if (!result.LoadBase(tx, tz, 0, 0
                , polyMesh.boundsMin
                , polyMesh.boundsMax
                , polyMesh.xzCellSize
                , polyMesh.yCellSize
                , polyMesh.walkableHeight
                , polyMesh.walkableRadius
                , polyMesh.walkableStep
                , bvTreeEnabled))
            {
                context.LogError("Base data load failed. Bad configuration data or internal error."
                    , null);
                return null;
            }

            if (!result.LoadPolys(polyMesh.verts
                , polyMesh.vertCount
                , polyMesh.polys
                , polyMesh.flags
                , polyMesh.areas
                , polyMesh.polyCount))
            {
                context.LogError("Polygon load failed. Bad mesh data or internal error.", null);
                return null;
            }

            if (detailMesh != null)
            {
                if (!result.LoadDetail(detailMesh.verts
                    , detailMesh.vertCount
                    , detailMesh.tris
                    , detailMesh.triCount
                    , detailMesh.meshes
                    , detailMesh.meshCount))
                {
                    context.LogError("Detail load failed. Bad mesh data or internal error.", null);
                    return null;
                }
            }

            if (connCount > 0)
            {
                if (!result.LoadConns(verts, radii, dirs, areas, flags, userIds, connCount))
                {
                    context.LogError("Off-mesh connection load failed. Bad data or internal error."
                        , null);
                    return null;
                }
            }

            return result;
        }