generate box colliders for water mesh

This commit is contained in:
in0finite 2022-02-27 00:44:14 +01:00
parent 6185f7089f
commit 706d2b6d9d
3 changed files with 35 additions and 30 deletions

View file

@ -9,7 +9,7 @@ GameObject:
serializedVersion: 6
m_Component:
- component: {fileID: 7995634715881356742}
- component: {fileID: 8546980230320474744}
- component: {fileID: 4513590737340015457}
m_Layer: 4
m_Name: WaterCollision
m_TagString: Untagged
@ -31,8 +31,8 @@ Transform:
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!64 &8546980230320474744
MeshCollider:
--- !u!65 &4513590737340015457
BoxCollider:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
@ -41,7 +41,6 @@ MeshCollider:
m_Material: {fileID: 0}
m_IsTrigger: 1
m_Enabled: 1
serializedVersion: 4
m_Convex: 1
m_CookingOptions: 30
m_Mesh: {fileID: 0}
serializedVersion: 2
m_Size: {x: 1, y: 1, z: 1}
m_Center: {x: 0, y: 0, z: 0}

View file

@ -13,6 +13,7 @@ namespace SanAndreasUnity.Behaviours.World
[SerializeField] private GameObject m_waterCollisionPrefab;
[SerializeField] private bool m_createCollisionObjects = false;
[SerializeField] private float m_collisionHeight = 20f;
[HideInInspector] [SerializeField] private List<Transform> m_renderingObjects = new List<Transform>();
[HideInInspector] [SerializeField] private List<Transform> m_collisionObjects = new List<Transform>();
@ -167,42 +168,37 @@ namespace SanAndreasUnity.Behaviours.World
int i = 0;
foreach (var face in faces)
{
Vector3[] vertices = new Vector3[face.Vertices.Length];
Vector3[] normals = new Vector3[face.Vertices.Length];
int numIndices = (face.Vertices.Length - 2) * 3;
int[] indices = new int[numIndices];
int verticesIndex = 0;
int indicesIndex = 0;
ProcessFace(face, vertices, normals, ref verticesIndex, indices, ref indicesIndex);
Vector3 center = Vector3.zero;
vertices.ForEach(v => center += v / vertices.Length);
for (int v = 0; v < vertices.Length; v++)
vertices[v] = vertices[v] - center;
face.Vertices.ForEach(v => center += v.Position / face.Vertices.Length);
var mesh = new Mesh();
// create box collider based on vertices
Vector3 min = Vector3.positiveInfinity;
Vector3 max = Vector3.negativeInfinity;
for (int v = 0; v < face.Vertices.Length; v++)
{
min = MathUtils.MinComponents(min, face.Vertices[v].Position);
max = MathUtils.MaxComponents(max, face.Vertices[v].Position);
}
mesh.vertices = vertices;
mesh.normals = normals;
mesh.SetIndices(indices, MeshTopology.Triangles, 0);
mesh.name = $"Water collision mesh {i}";
Vector3 size = max - min;
size.y = m_collisionHeight;
GameObject go = availableObjects.Count > 0
? availableObjects.Dequeue().gameObject
: Instantiate(m_waterCollisionPrefab, this.transform);
go.name = mesh.name;
go.name = $"Water collision {i}";
go.transform.localPosition = center;
go.transform.localPosition = center.WithY(center.y - size.y * 0.5f);
go.transform.localRotation = Quaternion.identity;
var meshCollider = go.GetComponentOrThrow<MeshCollider>();
var boxCollider = go.GetComponentOrThrow<BoxCollider>();
boxCollider.size = size;
/*var meshCollider = go.GetComponentOrThrow<MeshCollider>();
if (meshCollider.sharedMesh != null && !EditorUtilityEx.IsAsset(meshCollider.sharedMesh))
F.DestroyEvenInEditMode(meshCollider.sharedMesh);
meshCollider.sharedMesh = mesh;
meshCollider.sharedMesh = mesh;*/
m_collisionObjects.Add(go.transform);

View file

@ -17,5 +17,15 @@ namespace SanAndreasUnity.Utilities
Vector3 projection = v + t * (w - v); // Projection falls on the segment
return Vector3.Distance(p, projection);
}
public static Vector3 MinComponents(Vector3 a, Vector3 b)
{
return new Vector3(Mathf.Min(a.x, b.x), Mathf.Min(a.y, b.y), Mathf.Min(a.z, b.z));
}
public static Vector3 MaxComponents(Vector3 a, Vector3 b)
{
return new Vector3(Mathf.Max(a.x, b.x), Mathf.Max(a.y, b.y), Mathf.Max(a.z, b.z));
}
}
}