Files
2025-05-29 22:31:40 +03:00

210 lines
7.8 KiB
C#

using System;
using HTraceWSGI.Scripts.Globals;
using HTraceWSGI.Scripts.PassHandlers;
using HTraceWSGI.Scripts.Pipeline;
using HTraceWSGI.Scripts.Structs;
using UnityEngine;
using UnityEngine.Rendering.HighDefinition;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace HTraceWSGI.Scripts.VoxelCameras
{
[ExecuteInEditMode]
internal class VoxelCamera : MonoBehaviour
{
public Camera Camera
{
get { return _camera; }
}
private Camera _camera;
private VoxelsHandler _voxelsHandler;
private bool _dirtyBounds = false;
private Vector3 _prevVoxelBounds;
private Vector3 _rememberPos;
public void Initialize(VoxelsHandler voxelsHandler)
{
_voxelsHandler = voxelsHandler;
CreateCamera();
ExecuteUpdate(null);
VoxelizationRuntimeData.OnReallocTextures += UpdateCameraFromUI;
_prevVoxelBounds = HResources.VoxelizationData.ExactData.Bounds;
}
public void ExecuteUpdate(Camera ctxCamera)
{
if (_dirtyBounds == true)
{
_dirtyBounds = false;
_prevVoxelBounds = HResources.VoxelizationData.ExactData.Bounds;
}
_camera.cullingMask = ~0; //voxelizationData.VoxelizationMask;
_camera.orthographic = true;
_camera.farClipPlane = .5f * HResources.VoxelizationData.ExactData.Bounds.z;
_camera.nearClipPlane = -.5f * HResources.VoxelizationData.ExactData.Bounds.z;
_camera.orthographicSize = .5f * _prevVoxelBounds.x;
_camera.aspect = (.5f * _prevVoxelBounds.x) / (.5f * _prevVoxelBounds.x);
if (true)
{
HResources.VoxelizationData.ExactData.PreviousVoxelCameraPosition = new Vector3(_camera.transform.position.x, _camera.transform.position.y, _camera.transform.position.z);
}
AttachedCameraTranslate(ctxCamera);
}
private void AttachedCameraTranslate(Camera ctxCamera)
{
bool attachToSceneCamera = ctxCamera != null && ctxCamera.cameraType == CameraType.SceneView && HResources.DebugData.AttachToSceneCamera == true;
if (HResources.VoxelizationData.AttachTo == null && attachToSceneCamera == false)
{
GroundLevelTranslate();
_camera.transform.position = _camera.transform.position.OptimizeForVoxelization(HResources.VoxelizationData.ExactData);
return;
}
Transform attachToTransform = HResources.VoxelizationData.AttachTo;
#if UNITY_EDITOR
if (attachToSceneCamera)
{
attachToTransform = SceneView.lastActiveSceneView.camera.transform;
}
#endif
_camera.transform.parent = attachToTransform;
_camera.transform.rotation = Quaternion.identity;
_camera.transform.eulerAngles += new Vector3(-90f, 0, 180f);
switch (HResources.VoxelizationData.VoxelizationUpdateMode)
{
case VoxelizationUpdateMode.Constant:
_camera.transform.localPosition = Vector3.zero;
CenterShiftTranslate(attachToTransform);
GroundLevelTranslate();
_camera.transform.position = _camera.transform.position.OptimizeForVoxelization(HResources.VoxelizationData.ExactData);
break;
case VoxelizationUpdateMode.Partial:
VoxelizationRuntimeData.OctantIndex = VoxelizationRuntimeData.OctantIndex.Next();
if (VoxelizationRuntimeData.FrameCount % HConstants.OCTANTS_FRAMES_LENGTH == 0) // || VoxelizationRuntimeData.FullVoxelization)
{
VoxelizationRuntimeData.OctantIndex = OctantIndex.OctantA;
_camera.transform.localPosition = Vector3.zero;
CenterShiftTranslate(attachToTransform);
GroundLevelTranslate();
_camera.transform.position = _camera.transform.position.OptimizeForVoxelization(HResources.VoxelizationData.ExactData);
VoxelizationRuntimeData.OffsetAxisIndex = CalculateOffsetPositionAndTargetAxis();
if (VoxelizationRuntimeData.CullingCamera != null && VoxelizationRuntimeData.VoxelOctantCamera != null && VoxelizationRuntimeData.FakeDirectionalCamera != null) //first frame exceprion
{
VoxelizationRuntimeData.VoxelOctantCamera.UpdateCamera();
VoxelizationRuntimeData.CullingCamera.UpdateCamera();
//VoxelizationRuntimeData.FakeDirectionalCamera.UpdateCamera(); we do it every frame in ExecuteUpdate()
}
}
else
{
_camera.transform.position = _rememberPos;
}
break;
}
if (VoxelizationRuntimeData.CullingCamera != null && VoxelizationRuntimeData.VoxelOctantCamera != null && VoxelizationRuntimeData.FakeDirectionalCamera != null) //first frame exceprion
{
// Debug.Log(VoxelizationRuntimeData.OctantIndex);
VoxelizationRuntimeData.VoxelOctantCamera.ExecuteUpdate();
VoxelizationRuntimeData.CullingCamera.ExecuteUpdate();
VoxelizationRuntimeData.FakeDirectionalCamera.ExecuteUpdate();
}
}
private OffsetAxisIndex CalculateOffsetPositionAndTargetAxis()
{
Vector3 offsetWorldPosition = _rememberPos;
_rememberPos = _camera.transform.position;
offsetWorldPosition = _rememberPos - offsetWorldPosition;
VoxelizationRuntimeData.OffsetWorldPosition = new OffsetWorldPosition(
VoxelizationRuntimeData.OffsetAxisIndex == OffsetAxisIndex.AxisXPos ? 0.0f : VoxelizationRuntimeData.OffsetWorldPosition.AxisXPos,
VoxelizationRuntimeData.OffsetAxisIndex == OffsetAxisIndex.AxisYPos ? 0.0f : VoxelizationRuntimeData.OffsetWorldPosition.AxisYPos,
VoxelizationRuntimeData.OffsetAxisIndex == OffsetAxisIndex.AxisZPos ? 0.0f : VoxelizationRuntimeData.OffsetWorldPosition.AxisZPos,
VoxelizationRuntimeData.OffsetAxisIndex == OffsetAxisIndex.AxisXNeg ? 0.0f : VoxelizationRuntimeData.OffsetWorldPosition.AxisXNeg,
VoxelizationRuntimeData.OffsetAxisIndex == OffsetAxisIndex.AxisYNeg ? 0.0f : VoxelizationRuntimeData.OffsetWorldPosition.AxisYNeg,
VoxelizationRuntimeData.OffsetAxisIndex == OffsetAxisIndex.AxisZNeg ? 0.0f : VoxelizationRuntimeData.OffsetWorldPosition.AxisZNeg
);
VoxelizationRuntimeData.OffsetWorldPosition += new OffsetWorldPosition(
offsetWorldPosition.x > Mathf.Epsilon ? offsetWorldPosition.x : 0f,
offsetWorldPosition.y > Mathf.Epsilon ? offsetWorldPosition.y : 0f,
offsetWorldPosition.z > Mathf.Epsilon ? offsetWorldPosition.z : 0f,
offsetWorldPosition.x < Mathf.Epsilon ? -offsetWorldPosition.x : 0f,
offsetWorldPosition.y < Mathf.Epsilon ? -offsetWorldPosition.y : 0f,
offsetWorldPosition.z < Mathf.Epsilon ? -offsetWorldPosition.z : 0f
);
return VoxelizationRuntimeData.OffsetWorldPosition.MaxAxisOffset();
}
private void CenterShiftTranslate(Transform attachToTransform)
{
if (attachToTransform.GetComponent<Camera>() && Mathf.Abs(HResources.VoxelizationData.CenterShift) > 0.01f)
{
var forward = attachToTransform.forward;
_camera.transform.position += new Vector3(forward.x, 0f, forward.z) * HResources.VoxelizationData.CenterShift;
}
}
private void GroundLevelTranslate()
{
float height = HResources.VoxelizationData.ExactData.Bounds.z;
if (HResources.VoxelizationData.GroundLevelEnable == true && (_camera.transform.position.y - height / 2) < HResources.VoxelizationData.GroundLevel)
{
_camera.transform.position = new Vector3(_camera.transform.position.x, HResources.VoxelizationData.GroundLevel + height / 2,
_camera.transform.position.z);
}
}
private void UpdateCameraFromUI()
{
_dirtyBounds = true;
}
private void CreateCamera()
{
if (_camera == null)
{
_camera = gameObject.AddComponent<Camera>();
_camera.aspect = 1f;
_camera.orthographic = true;
_camera.enabled = false;
_camera.hideFlags = HResources.DebugData.ShowBowels ? HideFlags.None : HideFlags.HideInHierarchy;
var HDCameraData = gameObject.AddComponent<HDAdditionalCameraData>();
}
}
private void Update()
{
if (_voxelsHandler == null || _voxelsHandler.PingVoxelsHandler(this))
{
DestroyImmediate(this.gameObject);
}
}
private void OnDestroy()
{
VoxelizationRuntimeData.OnReallocTextures -= UpdateCameraFromUI;
}
}
}