Beispiel #1
0
        /// <summary>
        /// Builds a detail mesh from the provided polygon mesh.
        /// </summary>
        /// <param name="context">The context to use for the operation.</param>
        /// <param name="polyMesh">The source polygon mesh.</param>
        /// <param name="field">The compact heightfield used to build the polygon mesh.</param>
        /// <param name="detailSampleDistance">
        /// The sample distance to use when sampling the surface height of the polygon mesh.
        /// </param>
        /// <param name="detailMaxDeviation">
        /// The maximum the surface of the detail mesh should deviate from the heightfield data.
        /// </param>
        /// <returns>A new detail mesh, or null on error.</returns>
        public static PolyMeshDetail Build(BuildContext context
                                           , PolyMesh polyMesh, CompactHeightfield field
                                           , float detailSampleDistance, float detailMaxDeviation)
        {
            if (context == null || polyMesh == null || polyMesh.IsDisposed ||
                field == null || field.IsDisposed ||
                detailSampleDistance < 0 ||
                detailMaxDeviation < 0)
            {
                return(null);
            }

            PolyMeshDetail result = new PolyMeshDetail(AllocType.External);

            if (PolyMeshDetailEx.rcpdBuildPolyMeshDetail(context.root
                                                         , ref polyMesh.root
                                                         , field
                                                         , detailSampleDistance
                                                         , detailMaxDeviation
                                                         , result))
            {
                return(result);
            }

            return(null);
        }
Beispiel #2
0
        /// <summary>
        /// Gets a serialized version of the mesh that can be used to recreate it later.
        /// </summary>
        /// <param name="includeBuffer">
        /// True if serialized data should include the full buffer size.  Otherwise the buffers will
        /// be stripped and the smallest possible serialized data returned.
        /// </param>
        /// <returns>A serialized version of the mesh.</returns>
        public byte[] GetSerializedData(bool includeBuffer)
        {
            if (IsDisposed)
            {
                return(null);
            }

            // Design note:  This is implemented using interop calls
            // bacause it is so much easier and faster to serialize in C++
            // than in C#.

            IntPtr ptr      = IntPtr.Zero;
            int    dataSize = 0;

            if (!PolyMeshDetailEx.rcpdGetSerializedData(this
                                                        , includeBuffer
                                                        , ref ptr
                                                        , ref dataSize))
            {
                return(null);
            }

            byte[] result = UtilEx.ExtractArrayByte(ptr, dataSize);

            NMGenEx.nmgFreeSerializationData(ref ptr);

            return(result);
        }
Beispiel #3
0
        /// <summary>
        /// Frees all resources and marks the object as disposed.
        /// </summary>
        public void RequestDisposal()
        {
            if (!IsDisposed)
            {
                if (ResourceType == AllocType.Local)
                {
                    Marshal.FreeHGlobal(mMeshes);
                    Marshal.FreeHGlobal(mTris);
                    Marshal.FreeHGlobal(mVerts);
                }
                else if (ResourceType == AllocType.External)
                {
                    PolyMeshDetailEx.rcpdFreeMeshData(this);
                }

                mMeshes    = IntPtr.Zero;
                mTris      = IntPtr.Zero;
                mVerts     = IntPtr.Zero;
                mMeshCount = 0;
                mVertCount = 0;
                mTriCount  = 0;
                mMaxMeshes = 0;
                mMaxTris   = 0;
                mMaxVerts  = 0;
            }
        }
Beispiel #4
0
        private PolyMeshDetail(SerializationInfo info, StreamingContext context)
        {
            // Note: Version compatability is handled by the interop call.
            if (info.MemberCount != 1)
            {
                return;
            }

            byte[] rawData = (byte[])info.GetValue(DataKey, typeof(byte[]));
            PolyMeshDetailEx.rcpdBuildFromMeshData(rawData, rawData.Length, this);
        }
Beispiel #5
0
        /// <summary>
        /// Constructs a detail mesh from the data generated by the <see cref="GetSerializedData"/>
        /// method.
        /// </summary>
        /// <param name="serializedMesh">The source data.</param>
        /// <returns>The new detail mesh, or null on error.</returns>
        public static PolyMeshDetail Create(byte[] serializedMesh)
        {
            PolyMeshDetail result = new PolyMeshDetail(AllocType.External);

            if (PolyMeshDetailEx.rcpdBuildFromMeshData(serializedMesh
                                                       , serializedMesh.Length
                                                       , result))
            {
                return(result);
            }

            return(null);
        }
Beispiel #6
0
        /// <summary>
        /// Builds an aggregate triangle mesh from a detail mesh.
        /// </summary>
        /// <remarks>
        /// <para>
        /// All duplicate vertices are merged.
        /// </para>
        /// </remarks>
        /// <param name="source">The detail mesh to extract the triangle mesh from.</param>
        /// <param name="verts">The result vertices.</param>
        /// <param name="tris">
        /// The result triangles. [(vertAIndex, vertBIndex, vertCIndex) * triCount]
        /// </param>
        /// <returns>True if the operation completed successfully.</returns>
        public static bool ExtractTriMesh(PolyMeshDetail source
                                          , out Vector3[] verts
                                          , out int[] tris)
        {
            // TODO: EVAL: v0.5: Inefficient.

            verts = null;
            tris  = null;
            if (source == null || source.IsDisposed || source.TriCount == 0)
            {
                return(false);
            }

            // Assume no duplicate verts.
            Vector3[] tverts = new Vector3[source.VertCount];
            tris = new int[source.TriCount * 3];
            int vertCount = 0;
            int triCount  = 0;

            if (PolyMeshDetailEx.rcpdFlattenMesh(source
                                                 , tverts
                                                 , ref vertCount
                                                 , source.VertCount
                                                 , tris
                                                 , ref triCount
                                                 , source.TriCount))
            {
                verts = new Vector3[vertCount];
                for (int i = 0; i < vertCount; i++)
                {
                    verts[i] = tverts[i];
                }
                return(true);
            }

            tris = null;
            return(false);
        }