Как изменить 3D-сетку, чтобы она повторяла рельеф местности, сохраняя при этом толщину?C#

Место общения программистов C#
Ответить
Anonymous
 Как изменить 3D-сетку, чтобы она повторяла рельеф местности, сохраняя при этом толщину?

Сообщение Anonymous »

Для проекта Unity мне нужно создать скрипт, который изменяет сетку 3D-объекта во время выполнения так, чтобы она повторяла форму ландшафта под ним.
В настоящее время я добился такого результата (до/после):
До
После
Модель правильно повторяет кривую земли, но толщина вообще не сохраняется. Модель становится очень тонкой, и все детали теряются.
до
после
Я создал диаграмму, показывающую, что происходит по сравнению с . что должно произойти:
график
Вот текущий код:
public LayerMask groundLayer;
public float maxRaycastDistance = 100f;
public float deformationStrength = 1.0f;
private MeshFilter meshFilter;
private Mesh originalMeshe;
private Mesh workingMeshe;
private Vector3[] originalVertice;
private Vector3[] deformedVertice;
public float height = 3f;

private void InitializeMeshe()
{
meshFilter = GetComponent();
var meshRenderers = GetComponent();

height = meshRenderers.bounds.size.y;

originalMeshe = meshFilter.sharedMesh;
workingMeshe = Instantiate(originalMeshe);
originalVertice = workingMeshe.vertices;
deformedVertice = new Vector3[originalVertice.Length];

meshFilter.mesh = workingMeshe;
}

public void DeformMeshe()
{
Vector3[] deformedVerts = new Vector3[originalVertice.Length];

for (int j = 0; j < originalVertice.Length; j++)
{
Vector3 worldPos = meshFilter.transform.TransformPoint(originalVertice[j]);
Vector3 closestPoint = worldPos;
Vector3? groundHeight = GetGroundHeight(worldPos);

if (groundHeight == null)
{
deformedVerts[j] = originalVertice[j];
continue;
}

float closestDistance = Vector3.Distance(worldPos, groundHeight.Value);
if (closestDistance < maxRaycastDistance) closestPoint = groundHeight.Value;

Vector3 targetPosition = Vector3.Lerp(worldPos, closestPoint, deformationStrength);
targetPosition.y += height;

deformedVerts[j] = meshFilter.transform.InverseTransformPoint(targetPosition);
}

workingMeshe.vertices = deformedVerts;
workingMeshe.RecalculateNormals();
workingMeshe.RecalculateBounds();
}

public Vector3? GetGroundHeight(Vector3 worldPos)
{
if (Physics.Raycast(worldPos, Vector3.down, out RaycastHit hitDown, maxRaycastDistance, groundLayer))
return hitDown.point;

if (Physics.Raycast(worldPos, Vector3.up, out RaycastHit hitUp, maxRaycastDistance, groundLayer))
return hitUp.point;

return null;
}

Как я могу исправить свой код для достижения своей цели?
  • Первоначальный метод включает в себя передачу лучей лучей в сторону земли, чтобы определите его высоту и соответствующим образом отрегулируйте положение вершин по оси Y.
  • Я пытался использовать нормали, чтобы поддерживать постоянное расстояние между точками.
Vector3 normalWorld = meshFilter.transform.TransformDirection(vertexNormals[j]);
float originalDistance = Vector3.Dot(originalVertice[j], vertexNormals[j]);
Vector3 adjustedPosition = closestPoint + normalWorld * originalDistance;

Vector3 targetPosition = Vector3.Lerp(worldPos, adjustedPosition, deformationStrength);

Результат с нормалями
  • Все еще используя нормали, я попытался переместить точки вдоль самолет. Результат идентичен попытке 2.
Vector3 displacement = closestPoint - worldPos;
Vector3 displacementOnPlane = displacement - Vector3.Dot(displacement, worldNormal) * worldNormal;
Vector3 targetPosition = worldPos + displacementOnPlane * deformationStrength;
targetPosition += worldNormal * height;


Подробнее здесь: https://stackoverflow.com/questions/792 ... -thickness
Ответить

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

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

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

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

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