unity – Methods to merge two meshes collectively?


I’m exporting my Unity terrain to a mesh. As a result of the terrain is large, I additionally cut up it into a number of chunks.
Furthermore, I additionally generate chunk LODs. I allow a sure chunk LOD in-game based mostly on the participant’s distance to that chunk.

The difficulty is that I get gaps when two chunks which can be in numerous LOD ranges attempt to join. So I primarily want for each decrease than LOD_0 chunk mesh to have a border that’s the density of the LOD_0 mesh.

https://i.imgur.com/AcWxzMU.png

I’ve began writing the brand new mesh technology code, and that is what I’ve to this point:

utilizing System;
utilizing System.Collections.Generic;
utilizing Sirenix.OdinInspector;
utilizing Unity.Collections;
utilizing UnityEngine;

public class MeshStitchGeneration : MonoBehaviour
{
    non-public struct BorderData : IDisposable
    {
        public NativeList borderVertices;
        public NativeList     borderTriangles;

        public static BorderData Null => default;

        public BorderData(Allocator allocator)
        {
            borderVertices = new(allocator);
            borderTriangles = new(allocator);
        }

        public void Dispose()
        {
            borderVertices.Dispose();
            borderTriangles.Dispose();
        }
    }

    [SerializeField] non-public Mesh lod0Mesh     = null;
    [SerializeField] non-public Mesh lowerLODMesh = null;
    [SerializeField] non-public Materials materials = null;

    [Button("Generate")]
    non-public void Generate()
    {
        var newObj = new GameObject("Generated");
        
        newObj.rework.SetParent(gameObject.rework);

        newObj.rework.SetLocalPositionAndRotation(Vector3.zero, Quaternion.id);

        var filter = newObj.AddComponent();
        var renderer = newObj.AddComponent();

        renderer.sharedMaterial = materials;

        utilizing var borderMeshData = GetBorderMeshData();
        var newStitchedMesh = AppendBorderDataToMesh(in borderMeshData);

        filter.sharedMesh = newStitchedMesh;
    }

    non-public BorderData GetBorderMeshData()
    {
        if (lod0Mesh == null)
        {
            Debug.LogError("No lod0Mesh assigned!");

            return BorderData.Null;
        }

        var sure = lod0Mesh.bounds;

        if (sure.dimension.x != sure.dimension.z)
        {
            Debug.LogError("Requires a sq. mesh!");

            return BorderData.Null;
        }

        var vertices = lod0Mesh.vertices.AsSpan();
        var triangles = lod0Mesh.triangles.AsSpan();

        var gridSize = Mathf.RoundToInt(Mathf.Sqrt(vertices.Size));
        var vertexIncrement = sure.dimension.x / (gridSize - 1);

        var information = new BorderData(Allocator.Persistent);
        var vertexIndexMapping = new Dictionary();

        for (int i = 0; i < vertices.Size; i++)
        {
            Vector3 vertex = vertices[i];

            var ox = sure.min.x;
            var oz = sure.min.z;

            if (vertex.x < ox + sure.dimension.x - vertexIncrement
                && vertex.z < oz + sure.dimension.z - vertexIncrement
                && vertex.x > ox + vertexIncrement * 2
                && vertex.z > oz + vertexIncrement * 2)
            {
                proceed;
            }

            vertexIndexMapping[i] = information.borderVertices.Size;
            information.borderVertices.Add(vertex);
        }
        for (int i = 0; i < triangles.Size; i += 3)
        {
            int v1 = triangles[i];
            int v2 = triangles[i + 1];
            int v3 = triangles[i + 2];

            bool isV1OnBorder = vertexIndexMapping.ContainsKey(v1);
            bool isV2OnBorder = vertexIndexMapping.ContainsKey(v2);
            bool isV3OnBorder = vertexIndexMapping.ContainsKey(v3);

            if (isV1OnBorder || isV2OnBorder || isV3OnBorder)
            {
                if (isV1OnBorder) information.borderTriangles.Add(vertexIndexMapping[v1]);
                if (isV2OnBorder) information.borderTriangles.Add(vertexIndexMapping[v2]);
                if (isV3OnBorder) information.borderTriangles.Add(vertexIndexMapping[v3]);
            }
        }
        return information;
    }
    non-public Mesh AppendBorderDataToMesh(in BorderData borderData)
    {
        if (lowerLODMesh == null)
        {
            Debug.LogError("No lowerLODMesh assigned!");
            return null;
        }
        var newMesh = new Mesh();

        var lowerVertices = lowerLODMesh.vertices;
        var lowerTriangles = lowerLODMesh.triangles;

        var combinedVertices  = new Record(lowerVertices.Size + borderData.borderVertices.Size);
        var combinedTriangles = new Record(lowerTriangles.Size + borderData.borderTriangles.Size);

        combinedVertices.AddRange(lowerVertices);

        foreach (var borderVertex in borderData.borderVertices)
        {
            combinedVertices.Add(borderVertex);
        }
        combinedTriangles.AddRange(lowerTriangles);

        int lowerVertexCount = lowerVertices.Size;

        foreach (var triangleIndex in borderData.borderTriangles)
        {
            combinedTriangles.Add(lowerVertexCount + triangleIndex);
        }
        newMesh.vertices  = combinedVertices.ToArray();
        newMesh.triangles = combinedTriangles.ToArray();

        newMesh.RecalculateNormals(); newMesh.RecalculateBounds();

        return newMesh;
    }
}

The above code is at present only for testing so I apologize if it isn’t the most effective in high quality. What I’m doing proper now could be getting a border from the LOD_0 chunk mesh. That half is working nice. Now I must merge that border information with the decrease LOD chunk mesh.

Presently what I’ve accomplished contained in the “AppendBorderDataToMesh” operate simply merely creates a brand new mesh that incorporates the border mesh and the chunk mesh. So simply two meshes in a single.

So like it may be seen on this picture: https://i.imgur.com/Nkii36k.png

However that isn’t what I would like. I wish to create new triangles that join the border mesh to the chunk mesh by primarily forming quads between the vertices of the border and the closest edge vertices of the chunk mesh.

So one thing like this I suppose: https://i.imgur.com/gs9ko1y.png

That is fairly advanced and I’m not positive find out how to do it.

Can somebody please assist me? Would actually respect it

Related Articles

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Latest Articles