Geometry & Space Utilities
WorldToLocalUV
WorldToLocalUVpublic Vector2 WorldToLocalUV(Vector3 worldPos)
{
Vector3 local = transform.InverseTransformPoint(worldPos) - meshOffset;
GetProjectionBasis(out Vector3 r, out Vector3 up, out _);
float u = Vector3.Dot(local, r) / Mathf.Max(kEpsilon, raycastGridExtent.x) + 0.5f;
float v = Vector3.Dot(local, up) / Mathf.Max(kEpsilon, raycastGridExtent.y) + 0.5f;
return new Vector2(u, v);
}Purpose: Convert a world-space point to decal UV (0..1).
Parameters: worldPos
Returns: Vector2 (UV) — (0.5, 0.5) is decal center.
Notes: Uses current projection basis and grid extent.
IsPointInsideMask
IsPointInsideMaskpublic bool IsPointInsideMask(Vector3 worldPos)
{
Vector3 local = transform.InverseTransformPoint(worldPos);
Vector3 c = center;
return
Mathf.Abs(local.x - c.x) <= size.x * 0.5f &&
Mathf.Abs(local.y - c.y) <= size.y * 0.5f &&
Mathf.Abs(local.z - c.z) <= maxDistance * 0.5f;
}Purpose: Test if a world point lies inside the projection box.
Parameters: worldPos
Returns: bool
GetProjectionBasis
GetProjectionBasispublic void GetProjectionBasis(out Vector3 right, out Vector3 up, out Vector3 fwd)
{
fwd = GetProjectionVector(transform).normalized;
if (fwd.sqrMagnitude < kEpsilon) fwd = -transform.up;
up = Mathf.Abs(Vector3.Dot(fwd, transform.up)) < 0.999f ? transform.up : transform.right;
right = Vector3.Cross(up, fwd).normalized;
up = Vector3.Cross(fwd, right).normalized;
right = transform.InverseTransformDirection(right);
up = transform.InverseTransformDirection(up);
fwd = transform.InverseTransformDirection(fwd);
}Purpose: Compute local right/up/forward basis for the current projection.
Parameters: out right, out up, out fwd
Returns: void
Notes: Ensures a stable orthonormal basis even for near-parallel cases.
ProjectPointOntoSurface
ProjectPointOntoSurfacepublic Vector3 ProjectPointOntoSurface(Vector3 worldPos)
{
Vector3 dir = GetProjectionVector(transform).normalized;
if (Physics.Raycast(worldPos - dir * 0.01f, dir,
out var hit, maxDistance, wrapMask))
return hit.point + hit.normal * surfaceOffset;
return worldPos;
}Purpose: Project a point along the projection vector onto the nearest valid surface.
Parameters: worldPos
Returns: Snapped world position.
Notes: Offsets along the hit normal by surfaceOffset to avoid z-fighting.
Last updated