96 lines
3.2 KiB
C#
96 lines
3.2 KiB
C#
|
|
// Perfect Culling (C) 2021 Patrick König
|
|||
|
|
//
|
|||
|
|
|
|||
|
|
using System;
|
|||
|
|
|
|||
|
|
#if UNITY_EDITOR
|
|||
|
|
using UnityEditor;
|
|||
|
|
#endif
|
|||
|
|
|
|||
|
|
using UnityEngine;
|
|||
|
|
using UnityEngine.Rendering;
|
|||
|
|
|
|||
|
|
namespace Koenigz.PerfectCulling
|
|||
|
|
{
|
|||
|
|
public class PerfectCullingExcludeVolume : MonoBehaviour, CustomHandle.IResizableByHandle
|
|||
|
|
{
|
|||
|
|
static readonly Bounds UniformBounds = new Bounds(Vector3.zero, Vector3.one);
|
|||
|
|
|
|||
|
|
[SerializeField] public Vector3 volumeSize = Vector3.one;
|
|||
|
|
[SerializeField] public PerfectCullingBakingBehaviour[] restrictToBehaviours = System.Array.Empty<PerfectCullingBakingBehaviour>();
|
|||
|
|
|
|||
|
|
public Bounds volumeExcludeBounds
|
|||
|
|
{
|
|||
|
|
get => new Bounds(transform.position, volumeSize);
|
|||
|
|
|
|||
|
|
set
|
|||
|
|
{
|
|||
|
|
// TODO: Causes annoying offset, gonna need to solve this in a different way.
|
|||
|
|
transform.position = value.center;
|
|||
|
|
|
|||
|
|
volumeSize = new Vector3(
|
|||
|
|
Mathf.Max(1, (value.size.x)),
|
|||
|
|
Mathf.Max(1, (value.size.y)),
|
|||
|
|
Mathf.Max(1, (value.size.z)));
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public bool IsPositionActive(PerfectCullingBakingBehaviour bakingBehaviour, Vector3 pos)
|
|||
|
|
{
|
|||
|
|
if (restrictToBehaviours.Length > 0)
|
|||
|
|
{
|
|||
|
|
if (System.Array.IndexOf(restrictToBehaviours, bakingBehaviour) < 0)
|
|||
|
|
{
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#if true
|
|||
|
|
// This should be much faster
|
|||
|
|
Transform tf = transform;
|
|||
|
|
|
|||
|
|
Vector3 localPos = Quaternion.Inverse(tf.rotation) * (tf.position - pos);
|
|||
|
|
|
|||
|
|
Vector3 scale = volumeExcludeBounds.extents;
|
|||
|
|
|
|||
|
|
localPos.x *= 1F / scale.x;
|
|||
|
|
localPos.y *= 1F / scale.y;
|
|||
|
|
localPos.z *= 1F / scale.z;
|
|||
|
|
|
|||
|
|
return localPos.x <= 1.0f && localPos.x >= -1.0f
|
|||
|
|
&& localPos.y <= 1.0f && localPos.y >= -1.0f
|
|||
|
|
&& localPos.z <= 1.0f && localPos.z >= -1.0f;
|
|||
|
|
#else
|
|||
|
|
Matrix4x4 matrix4X4 = Matrix4x4.TRS(transform.position, transform.rotation, volumeExcludeBounds.size).inverse;
|
|||
|
|
|
|||
|
|
return UniformBounds.Contains(matrix4X4.MultiplyPoint3x4(pos));
|
|||
|
|
#endif
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public Vector3 HandleSized
|
|||
|
|
{
|
|||
|
|
get => volumeExcludeBounds.size;
|
|||
|
|
set => volumeExcludeBounds = new Bounds(transform.position, value);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#if UNITY_EDITOR
|
|||
|
|
private void OnDrawGizmosSelected()
|
|||
|
|
{
|
|||
|
|
Matrix4x4 trs = Matrix4x4.TRS(transform.position, transform.rotation, Vector3.one);
|
|||
|
|
|
|||
|
|
Handles.color = new Color(1, 0, 0, 1.0f);
|
|||
|
|
Handles.zTest = CompareFunction.LessEqual;
|
|||
|
|
Handles.lighting = false;
|
|||
|
|
|
|||
|
|
Handles.matrix = trs;
|
|||
|
|
Handles.DrawWireCube(Vector3.zero, volumeSize);
|
|||
|
|
|
|||
|
|
// CubeHandleCap doesn't allow to specify non-uniform scale so we need to mess with the matrix
|
|||
|
|
Handles.matrix = trs * Matrix4x4.Scale(volumeSize);
|
|||
|
|
|
|||
|
|
Handles.color = new Color(1, 0, 0, PerfectCullingConstants.VolumeInsideAlpha);
|
|||
|
|
Handles.CubeHandleCap(-1, Vector3.zero, Quaternion.identity, 1.0f, EventType.Repaint);
|
|||
|
|
}
|
|||
|
|
#endif
|
|||
|
|
}
|
|||
|
|
}
|