UP-Viagg-io/LocalPackages/depthkit.core/Runtime/Utils/Metadata.cs

327 lines
13 KiB
C#

/************************************************************************************
Depthkit Unity SDK License v1
Copyright 2016-2024 Simile Inc dba Scatter. All Rights reserved.
Licensed under the the Simile Inc dba Scatter ("Scatter")
Software Development Kit License Agreement (the "License");
you may not use this SDK except in compliance with the License,
which is provided at the time of installation or download,
or which otherwise accompanies this software in either electronic or hard copy form.
You may obtain a copy of the License at http://www.depthkit.tv/license-agreement-v1
Unless required by applicable law or agreed to in writing,
the SDK distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and limitations under the License.
************************************************************************************/
using UnityEngine;
using System.Linq;
using System.Runtime.InteropServices;
namespace Depthkit
{
[System.Serializable]
public class Metadata
{
public static readonly int MaxPerspectives = 10;
[System.Serializable]
public class MetadataVersion
{
public int _versionMajor;
public int _versionMinor;
public string format;
}
//Used for reading the older single perspective JSON format.
[System.Serializable]
public class MetadataSinglePerspective
{
public int _versionMajor;
public int _versionMinor;
public string format;
public int numAngles;
public Vector2 depthImageSize;
public Vector2 depthPrincipalPoint;
public Vector2 depthFocalLength;
public float farClip;
public float nearClip;
public int textureWidth;
public int textureHeight;
public Matrix4x4 extrinsics;
public Vector3 boundsCenter;
public Vector3 boundsSize;
public Vector4 crop;
public float clipEpsilon;
}
[System.Serializable]
public class Perspective
{
public Vector2 depthImageSize;
public Vector2 depthPrincipalPoint;
public Vector2 depthFocalLength;
public float farClip;
public float nearClip;
public Matrix4x4 extrinsics;
public Matrix4x4 extrinsicsInv;
public Vector4 crop;
public float clipEpsilon;
public Vector3 cameraNormal;
public Vector3 cameraCenter;
}
[StructLayout(LayoutKind.Sequential)]
public struct StructuredPerspectiveData
{
public const int size = sizeof(float) * 2 +
sizeof(float) * 2 +
sizeof(float) * 2 +
sizeof(float) +
sizeof(float) +
sizeof(float) * 16 +
sizeof(float) * 16 +
sizeof(float) * 4 +
sizeof(float) +
sizeof(float) * 3 +
sizeof(float) * 3 +
sizeof(float);
public Vector2 depthImageSize;
public Vector2 depthPrincipalPoint;
public Vector2 depthFocalLength;
public float farClip;
public float nearClip;
public Matrix4x4 extrinsics;
public Matrix4x4 extrinsicsInverse;
public Vector4 crop;
public float clipEpsilon;
public Vector3 cameraPosition;
public Vector3 cameraNormal;
public float padding;
public StructuredPerspectiveData(Vector2 dImageSize, Vector2 dPrincipalPoint, Vector2 dFocalLength, float fClip, float nClip, Matrix4x4 ex, Vector4 c, float cEpsilon, Vector3 camPos, Vector3 camNorm)
{
depthImageSize = dImageSize;
depthPrincipalPoint = dPrincipalPoint;
depthFocalLength = dFocalLength;
farClip = fClip;
nearClip = nClip;
extrinsics = ex;
extrinsicsInverse = ex.inverse;
crop = c;
clipEpsilon = cEpsilon;
cameraPosition = camPos;
cameraNormal = camNorm;
padding = 0;
}
}
// This allows other classes to reference the default values while keeping a single source of truth.
public class DefaultReconstructionSettingsDefaults
{
public static readonly float depthBiasAdjustment = 0.008f;
public static readonly float edgeMaskBlurAmount = 0.01f;
public static readonly float edgeMaskSobelMultiplier = 50.0f;
public static readonly float surfaceNormalColorBlendPower = 1.0f;
public static readonly float viewDependentColorBlendPower = 1.0f;
}
[System.Serializable]
public class DefaultReconstructionSettings
{
// New properties in v0.5 metadata
// Defaults for older versions set here
public float depthBiasAdjustment = DefaultReconstructionSettingsDefaults.depthBiasAdjustment;
public float edgeMaskBlurAmount = DefaultReconstructionSettingsDefaults.edgeMaskBlurAmount;
public float edgeMaskSobelMultiplier = DefaultReconstructionSettingsDefaults.edgeMaskSobelMultiplier;
public float surfaceNormalColorBlendPower = DefaultReconstructionSettingsDefaults.surfaceNormalColorBlendPower;
public float viewDependentColorBlendPower = DefaultReconstructionSettingsDefaults.viewDependentColorBlendPower;
}
public readonly static uint MAX_PERSPECTIVES = 12;
private const float eps = 0.00000001f;
public int _versionMajor;
public int _versionMinor;
public string format;
public int textureWidth;
public int textureHeight;
public Vector3 boundsCenter;
public Vector3 boundsSize;
public Perspective[] perspectives;
public int perspectivesCount;
public int numRows;
public int numColumns;
public int numAngles;
public DefaultReconstructionSettings defaultReconstructionSettings;
public bool Valid()
{
return _versionMinor != 0 && perspectives != null;
}
// Depth and color resolution for each perspective
public Vector2Int perspectiveCPPResolution
{
get
{
if (textureHeight == 0 && textureWidth == 0) return new Vector2Int(0, 0);
return new Vector2Int
{
x = Mathf.Max(textureWidth / Mathf.Max(numColumns, 1), 1),
y = Mathf.Max(textureHeight / Mathf.Max(numRows, 1), 1),
};
}
}
public Vector2Int perspectiveResolution
{
get
{
Vector2Int res = perspectiveCPPResolution;
res.y /= 2;
return res;
}
}
public Vector2Int paddedTextureDimensions
{
get
{
return new Vector2Int(
Util.NextMultipleOfX(perspectiveResolution.x, 8),
Util.NextMultipleOfX(perspectiveResolution.y, 8)
);
}
}
static Depthkit.Metadata FromSinglePerspective(MetadataSinglePerspective md)
{
return new Depthkit.Metadata
{
_versionMajor = 0,
_versionMinor = 4,
format = md.format,
boundsCenter = md.boundsCenter,
boundsSize = md.boundsSize,
textureWidth = md.textureWidth,
textureHeight = md.textureHeight,
perspectives = new Perspective[] {
new Perspective {
depthImageSize = md.depthImageSize,
depthPrincipalPoint = md.depthPrincipalPoint,
depthFocalLength = md.depthFocalLength,
farClip = md.farClip,
nearClip = md.nearClip,
extrinsics = md.extrinsics,
crop = md.crop,
clipEpsilon = md.clipEpsilon
}
}
};
}
public static Depthkit.Metadata CreateFromJSON(string jsonString)
{
Depthkit.Metadata metadata;
MetadataVersion mdVersion = JsonUtility.FromJson<MetadataVersion>(jsonString);
// Read and upgrade old single perspective format.
if (mdVersion._versionMajor == 0 && mdVersion._versionMinor < 3)
{
MetadataSinglePerspective md = JsonUtility.FromJson<MetadataSinglePerspective>(jsonString);
//for version 1.0 (from Depthkit Visualize) fill in defaults for missing parameters
if (mdVersion.format == "perpixel" && mdVersion._versionMinor == 1)
{
//set final image dimensions
md.textureWidth = (int)(md.depthImageSize.x);
md.textureHeight = (int)(md.depthImageSize.y) * 2;
//calculate bounds
md.boundsCenter = new Vector3(0f, 0f, (md.farClip - md.nearClip) / 2.0f + md.nearClip);
md.boundsSize = new Vector3(md.depthImageSize.x * md.farClip / md.depthFocalLength.x,
md.depthImageSize.y * md.farClip / md.depthFocalLength.y,
md.farClip - md.nearClip);
md.numAngles = 1;
// check if we have a zero'd crop (is this possible?), if so default to full window
if (md.crop.x <= eps && md.crop.y <= eps && md.crop.z <= eps && md.crop.w <= eps)
{
md.crop = new Vector4(0.0f, 0.0f, 1.0f, 1.0f);
}
md.extrinsics = Matrix4x4.identity;
}
if (md.clipEpsilon < eps)
{
md.clipEpsilon = 0.005f; // default depth clipping epsilon, set for older versions of metadata
}
metadata = Depthkit.Metadata.FromSinglePerspective(md);
metadata.numRows = 1;
metadata.numColumns = 1;
}
else
{
// Read multiperspective format.
metadata = JsonUtility.FromJson<Depthkit.Metadata>(jsonString);
metadata.boundsCenter.z *= -1;
metadata.boundsCenter.y *= -1;
if (mdVersion._versionMinor <= 3)
{
metadata.numRows = 1;
metadata.numColumns = metadata.numAngles;
}
}
// Convert from Depthkit to Unity coordinate space
for (int i = 0; i < metadata.perspectives.Length; ++i)
{
Matrix4x4 mirror = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, new Vector3(1.0f, -1.0f, -1.0f));
metadata.perspectives[i].extrinsics = mirror * metadata.perspectives[i].extrinsics * mirror;
metadata.perspectives[i].extrinsicsInv = metadata.perspectives[i].extrinsics.inverse;
metadata.perspectives[i].cameraCenter = (metadata.perspectives[i].extrinsics * new Vector4(0.0f, 0.0f, 0.0f, 1.0f));
metadata.perspectives[i].cameraNormal = (metadata.perspectives[i].extrinsics * new Vector4(0.0f, 0.0f, 1.0f, 0.0f)).normalized;
}
metadata.perspectivesCount = metadata.perspectives.Length;
return metadata;
}
public static StructuredPerspectiveData[] FillPersistentMetadataFromPerspectives(Perspective[] perspectives)
{
StructuredPerspectiveData[] filledData = new StructuredPerspectiveData[perspectives.Length];
for (int i = 0; i < perspectives.Length; i++)
{
filledData[i] = new StructuredPerspectiveData(perspectives[i].depthImageSize,
perspectives[i].depthPrincipalPoint,
perspectives[i].depthFocalLength,
perspectives[i].farClip,
perspectives[i].nearClip,
perspectives[i].extrinsics,
perspectives[i].crop,
perspectives[i].clipEpsilon,
perspectives[i].cameraCenter,
perspectives[i].cameraNormal);
}
return filledData;
}
}
}