Skip to content

Commit

Permalink
Merge pull request #588 from ExtendRealityLtd/pointer-fixes
Browse files Browse the repository at this point in the history
Pointer fixes
  • Loading branch information
thestonefox authored May 6, 2023
2 parents 07b44ad + c1bd830 commit 646db80
Show file tree
Hide file tree
Showing 5 changed files with 266 additions and 13 deletions.
12 changes: 10 additions & 2 deletions Runtime/Cast/PointsCast.cs
Original file line number Diff line number Diff line change
Expand Up @@ -357,17 +357,25 @@ public virtual void Process()

protected virtual void OnEnable()
{
points.Clear();
ClearState();
OnAfterTargetHitChange();
}

protected virtual void OnDisable()
{
ClearState();
ClearDestinationPointOverride();
}

/// <summary>
/// Clears the pointer state.
/// </summary>
protected virtual void ClearState()
{
TargetHit = null;
trackedOriginForward = null;
IsTargetHitValid = false;
points.Clear();
ClearDestinationPointOverride();
}

/// <summary>
Expand Down
23 changes: 13 additions & 10 deletions Runtime/Tracking/CameraRig/BaseDeviceDetailsRecord.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public abstract class BaseDeviceDetailsRecord : DeviceDetailsRecord
/// <summary>
/// The last known is connected status.
/// </summary>
protected bool lastKnownIsConnected;
protected bool? lastKnownIsConnected;
/// <summary>
/// The last known tracking type.
/// </summary>
Expand All @@ -38,36 +38,39 @@ public abstract class BaseDeviceDetailsRecord : DeviceDetailsRecord
/// <inheritdoc/>
protected override bool HasBatteryChargeStatusChanged()
{
bool hasChanged = BatteryChargeStatus != lastKnownBatteryStatus;
BatteryStatus currentValue = BatteryChargeStatus;
bool hasChanged = !currentValue.Equals(lastKnownBatteryStatus);
if (hasChanged)
{
BatteryChargeStatusChanged?.Invoke(BatteryChargeStatus);
BatteryChargeStatusChanged?.Invoke(currentValue);
lastKnownBatteryStatus = currentValue;
}
lastKnownBatteryStatus = BatteryChargeStatus;
return hasChanged;
}

/// <inheritdoc/>
protected override bool HasIsConnectedChanged()
{
bool hasChanged = IsConnected != lastKnownIsConnected;
bool currentValue = IsConnected;
bool hasChanged = currentValue != lastKnownIsConnected;
if (hasChanged)
{
ConnectionStatusChanged?.Invoke(IsConnected);
ConnectionStatusChanged?.Invoke(currentValue);
lastKnownIsConnected = currentValue;
}
lastKnownIsConnected = IsConnected;
return hasChanged;
}

/// <inheritdoc/>
protected override bool HasTrackingTypeChanged()
{
bool hasChanged = TrackingType != lastKnownTrackingType;
SpatialTrackingType currentValue = TrackingType;
bool hasChanged = !currentValue.Equals(lastKnownTrackingType);
if (hasChanged)
{
TrackingTypeChanged?.Invoke(TrackingType);
TrackingTypeChanged?.Invoke(currentValue);
lastKnownTrackingType = currentValue;
}
lastKnownTrackingType = TrackingType;
return hasChanged;
}

Expand Down
22 changes: 21 additions & 1 deletion Runtime/Visual/PointsRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,23 @@ public GameObject End
end = value;
}
}
[Tooltip("The threshold the forward value can be within 0 to be able to be set.")]
[SerializeField]
private float forwardZeroThreshold = 0.000001f;
/// <summary>
/// The threshold the forward value can be within 0 to be able to be set.
/// </summary>
public float ForwardZeroThreshold
{
get
{
return forwardZeroThreshold;
}
set
{
forwardZeroThreshold = value;
}
}

/// <summary>
/// A collection of segment clones.
Expand Down Expand Up @@ -383,7 +400,10 @@ protected virtual void UpdateElement(IReadOnlyList<Vector3> points, int pointsIn
return;
}

renderElement.transform.forward = forward;
if (!forward.ApproxEquals(Vector3.zero, ForwardZeroThreshold))
{
renderElement.transform.forward = forward;
}

Vector3 scale = renderElement.transform.lossyScale;

Expand Down
211 changes: 211 additions & 0 deletions Tests/Editor/Tracking/CameraRig/BaseDeviceDetailsRecordTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
using Zinnia.Tracking.CameraRig;

namespace Test.Zinnia.Tracking.CameraRig
{
using NUnit.Framework;
using Test.Zinnia.Utility.Mock;
using UnityEngine;
using UnityEngine.XR;

public class BaseDeviceDetailsRecordTest
{
private GameObject containingObject;
private MockBaseDeviceDetailsRecord subject;

[SetUp]
public void SetUp()
{
containingObject = new GameObject("BaseDeviceDetailsRecordTest");
subject = containingObject.AddComponent<MockBaseDeviceDetailsRecord>();
}

[TearDown]
public void TearDown()
{
Object.DestroyImmediate(containingObject);
}

[Test]
public void PassThroughCameraEnabled()
{
UnityEventListenerMock passthruEnabledMock = new UnityEventListenerMock();
UnityEventListenerMock passthruDisabledMock = new UnityEventListenerMock();
subject.PassThroughCameraWasEnabled.AddListener(passthruEnabledMock.Listen);
subject.PassThroughCameraWasDisabled.AddListener(passthruDisabledMock.Listen);

subject.hasPassThroughCamera = false;
subject.PassThroughCameraEnabled = true;
Assert.IsFalse(subject.PassThroughCameraEnabled);
Assert.IsFalse(passthruEnabledMock.Received);
Assert.IsFalse(passthruDisabledMock.Received);

passthruEnabledMock.Reset();
passthruDisabledMock.Reset();

subject.hasPassThroughCamera = true;
subject.PassThroughCameraEnabled = true;

Assert.IsTrue(subject.PassThroughCameraEnabled);
Assert.IsTrue(passthruEnabledMock.Received);
Assert.IsFalse(passthruDisabledMock.Received);

passthruEnabledMock.Reset();
passthruDisabledMock.Reset();

subject.PassThroughCameraEnabled = false;
Assert.IsFalse(subject.PassThroughCameraEnabled);
Assert.IsFalse(passthruEnabledMock.Received);
Assert.IsTrue(passthruDisabledMock.Received);
}

[Test]
public void TrackingBegun()
{
UnityEventListenerMock trackingBegunMock = new UnityEventListenerMock();
subject.TrackingBegun.AddListener(trackingBegunMock.Listen);

subject.isConnected = false;
subject.Process();
Assert.IsFalse(trackingBegunMock.Received);
Assert.IsFalse(subject.TrackingHasBegun);

trackingBegunMock.Reset();
subject.isConnected = true;
subject.Process();

Assert.IsTrue(trackingBegunMock.Received);
Assert.IsTrue(subject.TrackingHasBegun);

trackingBegunMock.Reset();
subject.isConnected = false;
subject.Process();
Assert.IsFalse(trackingBegunMock.Received);
Assert.IsTrue(subject.TrackingHasBegun);
}

[Test]
public void ConnectionStatusChanged()
{
UnityEventListenerMock connectionStatusChanged = new UnityEventListenerMock();
subject.ConnectionStatusChanged.AddListener(connectionStatusChanged.Listen);

subject.isConnected = false;
subject.Process();
Assert.IsTrue(connectionStatusChanged.Received);
Assert.IsFalse(subject.IsConnected);

connectionStatusChanged.Reset();
subject.Process();
Assert.IsFalse(connectionStatusChanged.Received);
Assert.IsFalse(subject.IsConnected);

connectionStatusChanged.Reset();
subject.isConnected = true;
subject.Process();
Assert.IsTrue(connectionStatusChanged.Received);
Assert.IsTrue(subject.IsConnected);

connectionStatusChanged.Reset();
subject.Process();
Assert.IsFalse(connectionStatusChanged.Received);
Assert.IsTrue(subject.IsConnected);

connectionStatusChanged.Reset();
subject.isConnected = false;
subject.Process();
Assert.IsTrue(connectionStatusChanged.Received);
Assert.IsFalse(subject.IsConnected);
}

[Test]
public void BatteryChargeStatusChanged()
{
UnityEventListenerMock batteryChargeStatusChanged = new UnityEventListenerMock();
subject.BatteryChargeStatusChanged.AddListener(batteryChargeStatusChanged.Listen);

subject.batteryChargeStatus = BatteryStatus.Unknown;
subject.Process();
Assert.IsFalse(batteryChargeStatusChanged.Received);
Assert.AreEqual(BatteryStatus.Unknown, subject.BatteryChargeStatus);

batteryChargeStatusChanged.Reset();
subject.Process();
Assert.IsFalse(batteryChargeStatusChanged.Received);
Assert.AreEqual(BatteryStatus.Unknown, subject.BatteryChargeStatus);

batteryChargeStatusChanged.Reset();
subject.batteryChargeStatus = BatteryStatus.Discharging;
subject.Process();
Assert.IsTrue(batteryChargeStatusChanged.Received);
Assert.AreEqual(BatteryStatus.Discharging, subject.BatteryChargeStatus);

batteryChargeStatusChanged.Reset();
subject.Process();
Assert.IsFalse(batteryChargeStatusChanged.Received);
Assert.AreEqual(BatteryStatus.Discharging, subject.BatteryChargeStatus);

batteryChargeStatusChanged.Reset();
subject.batteryChargeStatus = BatteryStatus.Charging;
subject.Process();
Assert.IsTrue(batteryChargeStatusChanged.Received);
Assert.AreEqual(BatteryStatus.Charging, subject.BatteryChargeStatus);
}

[Test]
public void TrackingTypeChanged()
{
UnityEventListenerMock trackingTypeChanged = new UnityEventListenerMock();
subject.TrackingTypeChanged.AddListener(trackingTypeChanged.Listen);

subject.trackingType = DeviceDetailsRecord.SpatialTrackingType.Unknown;
subject.Process();
Assert.IsFalse(trackingTypeChanged.Received);
Assert.AreEqual(DeviceDetailsRecord.SpatialTrackingType.Unknown, subject.TrackingType);

trackingTypeChanged.Reset();
subject.Process();
Assert.IsFalse(trackingTypeChanged.Received);
Assert.AreEqual(DeviceDetailsRecord.SpatialTrackingType.Unknown, subject.TrackingType);

trackingTypeChanged.Reset();
subject.trackingType = DeviceDetailsRecord.SpatialTrackingType.RotationAndPosition;
subject.Process();
Assert.IsTrue(trackingTypeChanged.Received);
Assert.AreEqual(DeviceDetailsRecord.SpatialTrackingType.RotationAndPosition, subject.TrackingType);

trackingTypeChanged.Reset();
subject.Process();
Assert.IsFalse(trackingTypeChanged.Received);
Assert.AreEqual(DeviceDetailsRecord.SpatialTrackingType.RotationAndPosition, subject.TrackingType);

trackingTypeChanged.Reset();
subject.trackingType = DeviceDetailsRecord.SpatialTrackingType.RotationOnly;
subject.Process();
Assert.IsTrue(trackingTypeChanged.Received);
Assert.AreEqual(DeviceDetailsRecord.SpatialTrackingType.RotationOnly, subject.TrackingType);
}
}

public class MockBaseDeviceDetailsRecord : BaseDeviceDetailsRecord
{
public XRNode xrNodeType;
public int priority;
public bool hasPassThroughCamera;
public bool isConnected;
public string manufacturer;
public string model;
public SpatialTrackingType trackingType;
public float batteryLevel;
public BatteryStatus batteryChargeStatus;

public override XRNode XRNodeType { get => xrNodeType; protected set => throw new System.NotImplementedException(); }
public override int Priority { get => priority; protected set => throw new System.NotImplementedException(); }
public override bool HasPassThroughCamera { get => hasPassThroughCamera; protected set => throw new System.NotImplementedException(); }
public override bool IsConnected { get => isConnected; protected set => throw new System.NotImplementedException(); }
public override string Manufacturer { get => manufacturer; protected set => throw new System.NotImplementedException(); }
public override string Model { get => model; protected set => throw new System.NotImplementedException(); }
public override SpatialTrackingType TrackingType { get => trackingType; protected set => throw new System.NotImplementedException(); }
public override float BatteryLevel { get => batteryLevel; protected set => throw new System.NotImplementedException(); }
public override BatteryStatus BatteryChargeStatus { get => batteryChargeStatus; protected set => throw new System.NotImplementedException(); }
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 646db80

Please sign in to comment.