Как соединить юбку с куском сетки ландшафта LOD, чтобы обеспечить совпадение швов?C#

Место общения программистов C#
Ответить Пред. темаСлед. тема
Anonymous
 Как соединить юбку с куском сетки ландшафта LOD, чтобы обеспечить совпадение швов?

Сообщение Anonymous »

Я экспортирую свой ландшафт Unity в сетку. Поскольку ландшафт большой, я также разделил его на несколько фрагментов.
Более того, я также генерирую уровни детализации фрагментов. Я включаю LOD определенного фрагмента в игре в зависимости от расстояния игрока до этого фрагмента.
Проблема в том, что у меня возникают пробелы, когда два фрагмента с разными уровнями LOD пытаются соединиться. Поэтому мне по сути нужно, чтобы каждая сетка фрагментов ниже LOD_0 имела границу, равную плотности сетки LOD_0.
Изображение
Я начал писать новый код генерации сетки, и вот что у меня есть на данный момент:

Код: Выделить всё

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

public class MeshStitchGeneration : MonoBehaviour
{
private 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] private Mesh lod0Mesh     = null;
[SerializeField] private Mesh lowerLODMesh = null;
[SerializeField] private Material material = null;

[Button("Generate")]
private void Generate()
{
var newObj = new GameObject("Generated");

newObj.transform.SetParent(gameObject.transform);

newObj.transform.SetLocalPositionAndRotation(Vector3.zero, Quaternion.identity);

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

renderer.sharedMaterial = material;

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

filter.sharedMesh = newStitchedMesh;
}

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

return BorderData.Null;
}

var bound = lod0Mesh.bounds;

if (bound.size.x != bound.size.z)
{
Debug.LogError("Requires a square mesh!");

return BorderData.Null;
}

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

var gridSize = Mathf.RoundToInt(Mathf.Sqrt(vertices.Length));
var vertexIncrement = bound.size.x / (gridSize - 1);

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

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

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

if (vertex.x < ox + bound.size.x - vertexIncrement
&& vertex.z < oz + bound.size.z - vertexIncrement
&& vertex.x > ox + vertexIncrement * 2
&& vertex.z > oz + vertexIncrement * 2)
{
continue;
}

vertexIndexMapping[i] = data.borderVertices.Length;
data.borderVertices.Add(vertex);
}
for (int i = 0; i < triangles.Length;  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) data.borderTriangles.Add(vertexIndexMapping[v1]);
if (isV2OnBorder) data.borderTriangles.Add(vertexIndexMapping[v2]);
if (isV3OnBorder) data.borderTriangles.Add(vertexIndexMapping[v3]);
}
}
return data;
}
private 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 List(lowerVertices.Length + borderData.borderVertices.Length);
var combinedTriangles = new List(lowerTriangles.Length + borderData.borderTriangles.Length);

combinedVertices.AddRange(lowerVertices);

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

int lowerVertexCount = lowerVertices.Length;

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

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

return newMesh;
}
}
Приведенный выше код в настоящее время предназначен только для тестирования, поэтому я прошу прощения, если он не лучшего качества. Сейчас я получаю границу из сетки фрагментов LOD_0. Эта часть работает отлично. Теперь мне нужно объединить эти данные границы с сеткой фрагмента нижнего уровня детализации.
В настоящее время то, что я сделал внутри функции «AppendBorderDataToMesh», просто создает новую сетку, которая содержит сетку границы и кусковая сетка. Итак, всего две сетки в одной.
Как это можно увидеть на этом изображении: Изображение
Но это не то, что мне нужно. Я хочу создать новые треугольники, которые соединят граничную сетку с кусковой сеткой, по существу образуя четырехугольники между вершинами границы и ближайшими краевыми вершинами кусковой сетки.
Итак, что-то вроде этого Я думаю: Изображение
Это довольно сложно, и я не знаю, как это сделать.
Может кто-нибудь мне помочь? Был бы очень признателен

Подробнее здесь: https://stackoverflow.com/questions/790 ... s-at-seams
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • Регенерация LOD ландшафта в Unreal Engine 5
    Anonymous » » в форуме C++
    0 Ответы
    16 Просмотры
    Последнее сообщение Anonymous
  • Алгоритм LOD на основе сетки (стиль Nanite)
    Гость » » в форуме C++
    0 Ответы
    7 Просмотры
    Последнее сообщение Гость
  • Ошибка матча по каратэ: совпадение не удалось: EQUALS $ | совпадение не удалось: EQUALS
    Anonymous » » в форуме JAVA
    0 Ответы
    45 Просмотры
    Последнее сообщение Anonymous
  • Как реализовать границы слов с помощью strpos(), чтобы обеспечить совпадение всего слова/числа?
    Anonymous » » в форуме Php
    0 Ответы
    36 Просмотры
    Последнее сообщение Anonymous
  • Приоритет сетки: порядок или столбец сетки/строка сетки
    Anonymous » » в форуме CSS
    0 Ответы
    153 Просмотры
    Последнее сообщение Anonymous

Вернуться в «C#»