mirror of
https://github.com/nothke/quality-control.git
synced 2025-08-31 15:43:44 +00:00
Added interaction, hand, rigidbody dragging, picking up hammer
This commit is contained in:
113
Assets/Plugins/Interaction/Runtime/Utils/BoundsUtils.cs
Normal file
113
Assets/Plugins/Interaction/Runtime/Utils/BoundsUtils.cs
Normal file
@@ -0,0 +1,113 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Nothke.Utils
|
||||
{
|
||||
public static class BoundsUtils
|
||||
{
|
||||
// static list for caching, never deallocates
|
||||
static List<Collider> colliderCache = new List<Collider>();
|
||||
|
||||
public static Bounds GetObjectSpaceColliderBounds(GameObject go, bool includeInactive = false)
|
||||
{
|
||||
Transform t = go.transform;
|
||||
var rootW2L = t.worldToLocalMatrix;
|
||||
|
||||
go.GetComponentsInChildren(includeInactive, colliderCache);
|
||||
|
||||
if (colliderCache.Count == 0)
|
||||
{
|
||||
Debug.LogError("Attempting to get bounds of the object but it has no colliders");
|
||||
return default;
|
||||
}
|
||||
|
||||
Bounds goBounds = GetBoundsInRootSpace(colliderCache[0]);
|
||||
|
||||
for (int i = 1; i < colliderCache.Count; i++)
|
||||
{
|
||||
Bounds b = GetBoundsInRootSpace(colliderCache[i]);
|
||||
goBounds.Encapsulate(b);
|
||||
}
|
||||
|
||||
return goBounds;
|
||||
|
||||
Bounds GetBoundsInRootSpace(Collider col)
|
||||
{
|
||||
Bounds b = col.GetLocalBounds();
|
||||
Matrix4x4 l2w = col.transform.localToWorldMatrix;
|
||||
Matrix4x4 local = rootW2L * l2w;
|
||||
return TransformBounds(local, b);
|
||||
}
|
||||
}
|
||||
|
||||
public static Bounds GetLocalBounds(this Collider collider)
|
||||
{
|
||||
if (collider is BoxCollider)
|
||||
{
|
||||
BoxCollider box = (BoxCollider)collider;
|
||||
return new Bounds(box.center, box.size);
|
||||
}
|
||||
else if (collider is SphereCollider)
|
||||
{
|
||||
var center = ((SphereCollider)collider).center;
|
||||
var radius = ((SphereCollider)collider).radius;
|
||||
Vector3 size = new Vector3(radius * 2, radius * 2, radius * 2);
|
||||
return new Bounds(center, size);
|
||||
}
|
||||
else if (collider is CapsuleCollider)
|
||||
{
|
||||
var capsule = (CapsuleCollider)collider;
|
||||
var r = capsule.radius;
|
||||
var h = capsule.height;
|
||||
|
||||
Vector3 size;
|
||||
switch (capsule.direction)
|
||||
{
|
||||
case 0: size = new Vector3(h, r * 2, r * 2); break;
|
||||
case 1: size = new Vector3(r * 2, h, r * 2); break;
|
||||
case 2: size = new Vector3(r * 2, r * 2, h); break;
|
||||
default: size = default; break;
|
||||
}
|
||||
|
||||
return new Bounds(capsule.center, size);
|
||||
}
|
||||
else if (collider is MeshCollider)
|
||||
{
|
||||
return ((MeshCollider)collider).sharedMesh.bounds;
|
||||
}
|
||||
|
||||
Debug.LogError("Attempting to get bounds of an unknown collider type");
|
||||
return new Bounds();
|
||||
}
|
||||
|
||||
public static Bounds TransformBounds(in Matrix4x4 mat, in Bounds bounds)
|
||||
{
|
||||
// Find 8 corners of the bounds
|
||||
Vector3 p0 = bounds.min;
|
||||
Vector3 p1 = bounds.max;
|
||||
Vector3 p2 = new Vector3(p0.x, p0.y, p1.z);
|
||||
Vector3 p3 = new Vector3(p0.x, p1.y, p0.z);
|
||||
Vector3 p4 = new Vector3(p1.x, p0.y, p0.z);
|
||||
Vector3 p5 = new Vector3(p0.x, p1.y, p1.z);
|
||||
Vector3 p6 = new Vector3(p1.x, p0.y, p1.z);
|
||||
Vector3 p7 = new Vector3(p1.x, p1.y, p0.z);
|
||||
|
||||
Bounds b = new Bounds(mat * p0, Vector3.zero);
|
||||
b.Encapsulate(mat * p1);
|
||||
b.Encapsulate(mat * p2);
|
||||
b.Encapsulate(mat * p3);
|
||||
b.Encapsulate(mat * p4);
|
||||
b.Encapsulate(mat * p5);
|
||||
b.Encapsulate(mat * p6);
|
||||
b.Encapsulate(mat * p7);
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
public static void DrawBoundsGizmos(in Bounds bounds)
|
||||
{
|
||||
Gizmos.DrawWireCube(bounds.center, bounds.size);
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user