188 lines
5.8 KiB
C#
188 lines
5.8 KiB
C#
/*===============================================================================
|
|
Copyright (C) 2024 Immersal - Part of Hexagon. All Rights Reserved.
|
|
|
|
This file is part of the Immersal SDK.
|
|
|
|
The Immersal SDK cannot be copied, distributed, or made available to
|
|
third-parties for commercial purposes without written permission of Immersal Ltd.
|
|
|
|
Contact sales@immersal.com for licensing requests.
|
|
===============================================================================*/
|
|
|
|
using System;
|
|
using System.Runtime.InteropServices;
|
|
using System.Threading;
|
|
using UnityEngine;
|
|
|
|
namespace Immersal.XR
|
|
{
|
|
public interface ICameraData
|
|
{
|
|
IImageData GetImageData();
|
|
byte[] GetBytes();
|
|
CameraData Copy(IImageData imageData);
|
|
public void ReleaseReference();
|
|
public void CheckReferences();
|
|
int Width { get; }
|
|
int Height { get; }
|
|
int Channels { get; }
|
|
CameraDataFormat Format { get; }
|
|
Vector4 Intrinsics { get; }
|
|
Vector3 CameraPositionOnCapture { get; }
|
|
Quaternion CameraRotationOnCapture { get; }
|
|
double[] Distortion { get; }
|
|
Quaternion Orientation { get; }
|
|
}
|
|
|
|
public class CameraData : ICameraData
|
|
{
|
|
public int Width { get; set; }
|
|
public int Height { get; set; }
|
|
public int Channels { get; set; }
|
|
public CameraDataFormat Format { get; set; }
|
|
public Vector4 Intrinsics { get; set; } // x = principal point x, y = principal point y, z = focal length x, w = focal length y
|
|
public Vector3 CameraPositionOnCapture { get; set; }
|
|
public Quaternion CameraRotationOnCapture { get; set; }
|
|
public double[] Distortion { get; set; } // not yet used
|
|
public Quaternion Orientation { get; set; }
|
|
|
|
private readonly IImageData m_ImageData;
|
|
private int m_ReferenceCount;
|
|
private bool m_IsDisposed;
|
|
|
|
public CameraData(IImageData imageData)
|
|
{
|
|
m_ImageData = imageData;
|
|
m_ImageData.SetCameraDataReference(this);
|
|
}
|
|
|
|
public IImageData GetImageData()
|
|
{
|
|
if (m_IsDisposed) throw new ObjectDisposedException("Immersal.XR.CameraData");
|
|
Interlocked.Increment(ref m_ReferenceCount);
|
|
return m_ImageData;
|
|
}
|
|
|
|
public byte[] GetBytes()
|
|
{
|
|
if (m_IsDisposed) throw new ObjectDisposedException("Immersal.XR.CameraData");
|
|
return m_ImageData.ManagedBytes;
|
|
}
|
|
|
|
public void ReleaseReference()
|
|
{
|
|
Interlocked.Decrement(ref m_ReferenceCount);
|
|
CheckReferences();
|
|
}
|
|
|
|
public void CheckReferences()
|
|
{
|
|
if (m_ReferenceCount <= 0)
|
|
{
|
|
Dispose();
|
|
}
|
|
}
|
|
|
|
private void Dispose()
|
|
{
|
|
if (m_IsDisposed)
|
|
{
|
|
ImmersalLogger.LogWarning("Attempting to dispose already disposed CameraData");
|
|
return;
|
|
}
|
|
|
|
if (m_ImageData != null)
|
|
{
|
|
m_ImageData.DisposeData();
|
|
}
|
|
else
|
|
{
|
|
ImmersalLogger.LogWarning("Attempting to dispose null ImageData");
|
|
}
|
|
|
|
m_IsDisposed = true;
|
|
}
|
|
|
|
public CameraData Copy(IImageData imageData)
|
|
{
|
|
CameraData data = new CameraData(imageData)
|
|
{
|
|
Width = this.Width,
|
|
Height = this.Height,
|
|
Intrinsics = this.Intrinsics,
|
|
Format = this.Format,
|
|
Channels = this.Channels,
|
|
CameraPositionOnCapture = this.CameraPositionOnCapture,
|
|
CameraRotationOnCapture = this.CameraRotationOnCapture,
|
|
Orientation = this.Orientation,
|
|
Distortion = this.Distortion
|
|
};
|
|
return data;
|
|
}
|
|
}
|
|
|
|
public interface IImageData : IDisposable
|
|
{
|
|
public IntPtr UnmanagedDataPointer { get; }
|
|
public byte[] ManagedBytes { get; }
|
|
|
|
void SetCameraDataReference(ICameraData cameraData);
|
|
void DisposeData();
|
|
}
|
|
|
|
public abstract class ImageData: IImageData
|
|
{
|
|
public abstract IntPtr UnmanagedDataPointer { get; }
|
|
public abstract byte[] ManagedBytes { get; }
|
|
|
|
public abstract void DisposeData();
|
|
|
|
private ICameraData m_CameraData;
|
|
private bool m_CameraDataReferenceSet = false;
|
|
|
|
public void Dispose()
|
|
{
|
|
if (m_CameraData == null)
|
|
{
|
|
ImmersalLogger.LogWarning("Disposing ImageData with no CameraData reference.");
|
|
DisposeData();
|
|
return;
|
|
}
|
|
m_CameraData.ReleaseReference();
|
|
}
|
|
|
|
public void SetCameraDataReference(ICameraData cameraData)
|
|
{
|
|
if (m_CameraDataReferenceSet)
|
|
{
|
|
ImmersalLogger.LogError("CameraData reference already set.");
|
|
return;
|
|
}
|
|
m_CameraData = cameraData;
|
|
m_CameraDataReferenceSet = true;
|
|
}
|
|
}
|
|
|
|
public sealed class SimpleImageData : ImageData
|
|
{
|
|
public override IntPtr UnmanagedDataPointer => m_UnmanagedDataPointer;
|
|
public override byte[] ManagedBytes { get; }
|
|
|
|
private IntPtr m_UnmanagedDataPointer;
|
|
private GCHandle m_managedDataHandle;
|
|
|
|
public SimpleImageData(byte[] bytes)
|
|
{
|
|
ManagedBytes = bytes;
|
|
m_managedDataHandle = GCHandle.Alloc(ManagedBytes, GCHandleType.Pinned);
|
|
m_UnmanagedDataPointer = m_managedDataHandle.AddrOfPinnedObject();
|
|
}
|
|
|
|
public override void DisposeData()
|
|
{
|
|
m_managedDataHandle.Free();
|
|
m_UnmanagedDataPointer = IntPtr.Zero;
|
|
}
|
|
}
|
|
|
|
} |