1
0
mirror of https://github.com/xiaopeng12138/MaiDXR.git synced 2024-12-03 14:57:16 +01:00
MaiDXR/Assets/LIV/Scripts/SDKUtils.cs
2022-08-19 23:02:51 +02:00

343 lines
13 KiB
C#

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace LIV.SDK.Unity
{
public static class SDKUtils
{
public static void CreateClipPlane(Mesh mesh, int resX, int resY, bool useQuads, float skirtLength)
{
int vertexCount = (resX + 1) * (resY + 1);
int triangleCount = useQuads ? (resX * resY * 4) : (resX * resY * 2 * 3);
Vector3[] v = new Vector3[vertexCount];
Vector2[] uv = new Vector2[vertexCount];
int[] t = new int[triangleCount];
float hWidth = 0.5f;
float hHeight = 0.5f;
int resX1 = resX + 1;
int resY1 = resY + 1;
for (int y = 0; y < resY1; y++)
{
for (int x = 0; x < resX1; x++)
{
int vi = y * resX1 + x;
float uvx = (float)x / (float)resX;
float uvy = (float)y / (float)resY;
float skirtX = (x == 0 || x == resX) ? skirtLength : 1f;
float skirtY = (y == 0 || y == resY) ? skirtLength : 1f;
v[vi] = new Vector2((-hWidth + uvx) * skirtX, (-hHeight + uvy) * skirtY);
uv[vi] = new Vector2(Mathf.InverseLerp(1, resX - 1, x), Mathf.InverseLerp(1, resY - 1, y));
}
}
mesh.Clear();
mesh.vertices = v;
mesh.uv = uv;
mesh.bounds = new Bounds(Vector3.zero, Vector3.one * float.MaxValue);
{
int faces = resX * resY;
int vi = 0;
int ti = 0;
if (useQuads)
{
for (int i = 0; i < faces; i++)
{
vi = (i / resX) * resX1 + (i % resX);
t[ti++] = vi + 1;
t[ti++] = vi;
t[ti++] = vi + 1 + resX;
t[ti++] = vi + 2 + resX;
}
mesh.SetIndices(t, MeshTopology.Quads, 0);
}
else
{
for (int i = 0; i < faces; i++)
{
vi = (i / resX) * resX1 + (i % resX);
t[ti++] = vi + 2 + resX;
t[ti++] = vi + 1;
t[ti++] = vi;
t[ti++] = vi + 1 + resX;
t[ti++] = vi + 2 + resX;
t[ti++] = vi;
}
mesh.SetIndices(t, MeshTopology.Triangles, 0);
}
}
}
public static RenderTextureReadWrite GetReadWriteFromColorSpace(TEXTURE_COLOR_SPACE colorSpace)
{
switch (colorSpace)
{
case TEXTURE_COLOR_SPACE.LINEAR:
return RenderTextureReadWrite.Linear;
case TEXTURE_COLOR_SPACE.SRGB:
return RenderTextureReadWrite.sRGB;
default:
return RenderTextureReadWrite.Default;
}
}
public static TEXTURE_COLOR_SPACE GetDefaultColorSpace {
get {
switch (QualitySettings.activeColorSpace)
{
case UnityEngine.ColorSpace.Gamma:
return TEXTURE_COLOR_SPACE.SRGB;
case UnityEngine.ColorSpace.Linear:
return TEXTURE_COLOR_SPACE.LINEAR;
}
return TEXTURE_COLOR_SPACE.UNDEFINED;
}
}
public static TEXTURE_COLOR_SPACE GetColorSpace(RenderTexture renderTexture)
{
if (renderTexture == null) return TEXTURE_COLOR_SPACE.UNDEFINED;
if (renderTexture.sRGB) return TEXTURE_COLOR_SPACE.SRGB;
return TEXTURE_COLOR_SPACE.LINEAR;
}
public static RENDERING_PIPELINE GetRenderingPipeline(RenderingPath renderingPath)
{
switch (renderingPath)
{
case RenderingPath.DeferredLighting:
return RENDERING_PIPELINE.DEFERRED;
case RenderingPath.DeferredShading:
return RENDERING_PIPELINE.DEFERRED;
case RenderingPath.Forward:
return RENDERING_PIPELINE.FORWARD;
case RenderingPath.VertexLit:
return RENDERING_PIPELINE.VERTEX_LIT;
default:
return RENDERING_PIPELINE.UNDEFINED;
}
}
public static TEXTURE_DEVICE GetDevice()
{
switch (SystemInfo.graphicsDeviceType)
{
case UnityEngine.Rendering.GraphicsDeviceType.Direct3D11:
case UnityEngine.Rendering.GraphicsDeviceType.Direct3D12:
return TEXTURE_DEVICE.DIRECTX;
case UnityEngine.Rendering.GraphicsDeviceType.Vulkan:
return TEXTURE_DEVICE.VULKAN;
case UnityEngine.Rendering.GraphicsDeviceType.Metal:
return TEXTURE_DEVICE.METAL;
case UnityEngine.Rendering.GraphicsDeviceType.OpenGLCore:
return TEXTURE_DEVICE.OPENGL;
default:
return TEXTURE_DEVICE.UNDEFINED;
}
}
public static bool ContainsFlag(ulong flags, ulong flag)
{
return (flags & flag) != 0;
}
public static ulong SetFlag(ulong flags, ulong flag, bool enabled)
{
if (enabled)
{
return flags | flag;
}
else
{
return flags & (~flag);
}
}
public static void GetCameraPositionAndRotation(SDKPose pose, Matrix4x4 originLocalToWorldMatrix, out Vector3 position, out Quaternion rotation)
{
position = originLocalToWorldMatrix.MultiplyPoint(pose.localPosition);
rotation = RotateQuaternionByMatrix(originLocalToWorldMatrix, pose.localRotation);
}
public static void CleanCameraBehaviours(Camera camera, string[] excludeBehaviours)
{
// Remove all children from camera clone.
foreach (Transform child in camera.transform)
{
Object.Destroy(child.gameObject);
}
if (excludeBehaviours == null) return;
for (int i = 0; i < excludeBehaviours.Length; i++)
{
Object.Destroy(camera.GetComponent(excludeBehaviours[i]));
}
}
public static void SetCamera(Camera camera, Transform cameraTransform, SDKInputFrame inputFrame, Matrix4x4 originLocalToWorldMatrix, int layerMask)
{
Vector3 worldPosition = Vector3.zero;
Quaternion worldRotation = Quaternion.identity;
float verticalFieldOfView = inputFrame.pose.verticalFieldOfView;
float nearClipPlane = inputFrame.pose.nearClipPlane;
float farClipPlane = inputFrame.pose.farClipPlane;
Matrix4x4 projectionMatrix = inputFrame.pose.projectionMatrix;
GetCameraPositionAndRotation(inputFrame.pose, originLocalToWorldMatrix, out worldPosition, out worldRotation);
cameraTransform.position = worldPosition;
cameraTransform.rotation = worldRotation;
camera.fieldOfView = verticalFieldOfView;
camera.nearClipPlane = nearClipPlane;
camera.farClipPlane = farClipPlane;
camera.projectionMatrix = projectionMatrix;
camera.cullingMask = layerMask;
}
public static Quaternion RotateQuaternionByMatrix(Matrix4x4 matrix, Quaternion rotation)
{
return Quaternion.LookRotation(
matrix.MultiplyVector(Vector3.forward),
matrix.MultiplyVector(Vector3.up)
) * rotation;
}
public static SDKTrackedSpace GetTrackedSpace(Transform transform)
{
if (transform == null) return SDKTrackedSpace.empty;
return new SDKTrackedSpace
{
trackedSpaceWorldPosition = transform.position,
trackedSpaceWorldRotation = transform.rotation,
trackedSpaceLocalScale = transform.localScale,
trackedSpaceLocalToWorldMatrix = transform.localToWorldMatrix,
trackedSpaceWorldToLocalMatrix = transform.worldToLocalMatrix,
};
}
public static bool DestroyObject<T>(ref T reference) where T : UnityEngine.Object
{
if (reference == null) return false;
Object.Destroy(reference);
reference = default(T);
return true;
}
public static bool DisposeObject<T>(ref T reference) where T : System.IDisposable
{
if (reference == null) return false;
reference.Dispose();
reference = default(T);
return true;
}
public static bool CreateTexture(ref RenderTexture renderTexture, int width, int height, int depth, RenderTextureFormat format)
{
DestroyTexture(ref renderTexture);
if (width <= 0 || height <= 0)
{
Debug.LogError("LIV: Unable to create render texture. Texture dimension must be higher than zero.");
return false;
}
renderTexture = new RenderTexture(width, height, depth, format)
{
antiAliasing = 1,
wrapMode = TextureWrapMode.Clamp,
useMipMap = false,
anisoLevel = 0
};
if (!renderTexture.Create())
{
Debug.LogError("LIV: Unable to create render texture.");
return false;
}
return true;
}
public static void DestroyTexture(ref RenderTexture _renderTexture)
{
if (_renderTexture == null) return;
if (_renderTexture.IsCreated())
{
_renderTexture.Release();
}
_renderTexture = null;
}
public static void ApplyUserSpaceTransform(SDKRender render)
{
if (render.stageTransform == null) return;
render.stageTransform.localPosition = render.inputFrame.stageTransform.localPosition;
render.stageTransform.localRotation = render.inputFrame.stageTransform.localRotation;
render.stageTransform.localScale = render.inputFrame.stageTransform.localScale;
}
public static void CreateBridgeOutputFrame(SDKRender render)
{
RENDERING_PIPELINE renderingPipeline = RENDERING_PIPELINE.UNDEFINED;
#if LIV_UNIVERSAL_RENDER
renderingPipeline = RENDERING_PIPELINE.UNIVERSAL;
#else
if(render.cameraInstance != null)
{
renderingPipeline = SDKUtils.GetRenderingPipeline(render.cameraInstance.actualRenderingPath);
}
#endif
SDKBridge.CreateFrame(new SDKOutputFrame()
{
renderingPipeline = renderingPipeline,
trackedSpace = SDKUtils.GetTrackedSpace(render.stageTransform == null ? render.stage : render.stageTransform)
});
}
public static bool FeatureEnabled(FEATURES features, FEATURES feature)
{
return SDKUtils.ContainsFlag((ulong)features, (ulong)feature);
}
// Disable standard assets if required.
public static void DisableStandardAssets(Camera cameraInstance, ref MonoBehaviour[] behaviours, ref bool[] wasBehaviourEnabled)
{
behaviours = null;
wasBehaviourEnabled = null;
behaviours = cameraInstance.gameObject.GetComponents<MonoBehaviour>();
wasBehaviourEnabled = new bool[behaviours.Length];
for (var i = 0; i < behaviours.Length; i++)
{
var behaviour = behaviours[i];
// generates garbage
if (behaviour.enabled && behaviour.GetType().ToString().StartsWith("UnityStandardAssets."))
{
behaviour.enabled = false;
wasBehaviourEnabled[i] = true;
}
}
}
// Restore disabled behaviours.
public static void RestoreStandardAssets(ref MonoBehaviour[] behaviours, ref bool[] wasBehaviourEnabled)
{
if (behaviours != null)
for (var i = 0; i < behaviours.Length; i++)
if (wasBehaviourEnabled[i])
behaviours[i].enabled = true;
}
public static void ForceForwardRendering(Camera cameraInstance, Mesh clipPlaneMesh, Material forceForwardRenderingMaterial)
{
Matrix4x4 forceForwardRenderingMatrix = cameraInstance.transform.localToWorldMatrix * Matrix4x4.TRS(Vector3.forward * (cameraInstance.nearClipPlane + 0.1f), Quaternion.identity, Vector3.one);
Graphics.DrawMesh(clipPlaneMesh, forceForwardRenderingMatrix, forceForwardRenderingMaterial, 0, cameraInstance, 0, new MaterialPropertyBlock(), false, false, false);
}
}
}