Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: sdk camera control minor iteration #2058

Merged
merged 11 commits into from
Sep 20, 2024
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,7 @@ private void HandleVirtualCameraChange(Entity entity, ref MainCameraComponent ma
{
if (entity != cameraEntity || !sceneStateProvider.IsCurrent) return;

// The 'uint' pbMainCamera.VirtualCameraEntity at 0 represents the empty field
CRDTEntity? virtualCameraCRDTEntity = pbMainCamera.VirtualCameraEntity > 0 ? new CRDTEntity((int)pbMainCamera.VirtualCameraEntity) : null;
CRDTEntity? virtualCameraCRDTEntity = pbMainCamera.HasVirtualCameraEntity ? new CRDTEntity((int)pbMainCamera.VirtualCameraEntity) : null;

// Cannot rely on pbComponent.IsDirty since the VirtualCamera may not yet be on the target CRDTEntity
// when the pbComponent is dirty and may have to be re-checked on subsequent updates. This can happen
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ public void UpdateCinemachineCameraCorrectly()
Assert.IsTrue(sdkCinemachineCam1.enabled);

// Release active vCam in MainCameraComponent
pbMainCameraComponent.VirtualCameraEntity = 0;
pbMainCameraComponent.ClearVirtualCameraEntity();
world.Set(mainCameraEntity, pbMainCameraComponent);

SystemUpdate();
Expand Down Expand Up @@ -212,7 +212,7 @@ public void UpdateGlobalWorldCameraModeCorrectly()
Assert.AreEqual(CameraMode.SDKCamera, globalWorld.Get<CameraComponent>(globalWorldCameraEntity).Mode);

// Release active vCam in MainCameraComponent
pbMainCameraComponent.VirtualCameraEntity = 0;
pbMainCameraComponent.ClearVirtualCameraEntity();
world.Set(mainCameraEntity, pbMainCameraComponent);

SystemUpdate();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,53 @@ public void GetTargetLookAtCRDTEntityCorrectlyForInvalidTargets()
Assert.IsNull(VirtualCameraUtils.GetPBVirtualCameraLookAtCRDTEntity(pbComponent, virtualCameraCRDTEntity));
}

[Test]
public void ConfigureCameraDefaultTransitionCorrectly()
{
// Setup
CinemachineBrain cinemachineBrain = new GameObject("CinemachineBrain").AddComponent<CinemachineBrain>();
IExposedCameraData exposedCameraData = Substitute.For<IExposedCameraData>();
exposedCameraData.CinemachineBrain.Returns(cinemachineBrain);
int virtualCamCRDTEntity = world.Get<CRDTEntity>(entity1).Id;

// Virtual Camera without any 'Default Transition'
PBVirtualCamera pbComponent = new PBVirtualCamera();
world.Add(entity1, pbComponent);
VirtualCameraUtils.ConfigureVirtualCameraTransition(
world,
entitiesMap,
exposedCameraData,
virtualCamCRDTEntity,
20);
Assert.AreEqual(CinemachineBlendDefinition.Style.Cut, cinemachineBrain.m_DefaultBlend.m_Style);

// Time = 2.78 transition
pbComponent.DefaultTransition = new CameraTransition() { Time = 2.78f };
world.Set(entity1, pbComponent);
VirtualCameraUtils.ConfigureVirtualCameraTransition(
world,
entitiesMap,
exposedCameraData,
virtualCamCRDTEntity,
20);
Assert.AreEqual(CinemachineBlendDefinition.Style.EaseInOut, cinemachineBrain.m_DefaultBlend.m_Style);
Assert.AreEqual(pbComponent.DefaultTransition.Time, cinemachineBrain.m_DefaultBlend.m_Time);

// Remove 'Default Transition' from VirtualCamera
pbComponent.DefaultTransition.ClearTransitionMode();
world.Set(entity1, pbComponent);
VirtualCameraUtils.ConfigureVirtualCameraTransition(
world,
entitiesMap,
exposedCameraData,
virtualCamCRDTEntity,
68);
Assert.AreEqual(CinemachineBlendDefinition.Style.Cut, cinemachineBrain.m_DefaultBlend.m_Style);

// Cleanup
GameObject.DestroyImmediate(cinemachineBrain.gameObject);
}

[Test]
public void ConfigureCameraTimeTransitionCorrectly()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,25 +44,40 @@ public static void ConfigureVirtualCameraTransition(in World world, IReadOnlyDic

var pbVirtualCamera = world.Get<PBVirtualCamera>(vCamEntity);

// Using custom blends array doesn't work because there's no direct way of getting the custom blend index,
// and we would have to hardcode it...
if (pbVirtualCamera.DefaultTransition.TransitionModeCase == CameraTransition.TransitionModeOneofCase.Time)
// Using cinemachine custom blends array doesn't work because there's no direct way of getting the custom
// blend index, and we would have to hardcode it...
if (pbVirtualCamera.DefaultTransition == null)
{
float timeValue = pbVirtualCamera.DefaultTransition.Time;
cameraData.CinemachineBrain!.m_DefaultBlend.m_Time = timeValue;
cameraData.CinemachineBrain!.m_DefaultBlend.m_Style = timeValue <= 0 ? CinemachineBlendDefinition.Style.Cut : CinemachineBlendDefinition.Style.EaseInOut;
cameraData.CinemachineBrain!.m_DefaultBlend.m_Style = CinemachineBlendDefinition.Style.Cut;
return;
}
else
{
float speedValue = pbVirtualCamera.DefaultTransition.Speed;
cameraData.CinemachineBrain!.m_DefaultBlend.m_Style = speedValue <= 0 ? CinemachineBlendDefinition.Style.Cut : CinemachineBlendDefinition.Style.EaseInOut;

// SPEED = 1 -> 1 meter per second
float blendTime = CalculateDistanceBlendTime(distanceBetweenCameras, speedValue);
if (blendTime == 0)
switch (pbVirtualCamera.DefaultTransition.TransitionModeCase)
{
case CameraTransition.TransitionModeOneofCase.Time:
float timeValue = pbVirtualCamera.DefaultTransition.Time;
cameraData.CinemachineBrain!.m_DefaultBlend.m_Time = timeValue;
cameraData.CinemachineBrain!.m_DefaultBlend.m_Style = timeValue <= 0 ? CinemachineBlendDefinition.Style.Cut : CinemachineBlendDefinition.Style.EaseInOut;
break;
case CameraTransition.TransitionModeOneofCase.Speed:
float speedValue = pbVirtualCamera.DefaultTransition.Speed;
if (speedValue > 0)
{
cameraData.CinemachineBrain!.m_DefaultBlend.m_Style = CinemachineBlendDefinition.Style.EaseInOut;
float blendTime = CalculateDistanceBlendTime(distanceBetweenCameras, speedValue); // SPEED = 1 -> 1 meter per second
if (blendTime == 0)
cameraData.CinemachineBrain!.m_DefaultBlend.m_Style = CinemachineBlendDefinition.Style.Cut;
else
cameraData.CinemachineBrain!.m_DefaultBlend.m_Time = blendTime;
}
else
{
cameraData.CinemachineBrain!.m_DefaultBlend.m_Style = CinemachineBlendDefinition.Style.Cut;
}
break;
default:
cameraData.CinemachineBrain!.m_DefaultBlend.m_Style = CinemachineBlendDefinition.Style.Cut;
else
cameraData.CinemachineBrain!.m_DefaultBlend.m_Time = blendTime;
break;
}
}

Expand Down
140 changes: 20 additions & 120 deletions Explorer/Assets/Protocol/DecentralandProtocol/CameraTransition.gen.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,29 +26,30 @@ static CameraTransitionReflection() {
string.Concat(
"CjpkZWNlbnRyYWxhbmQvc2RrL2NvbXBvbmVudHMvY29tbW9uL2NhbWVyYV90",
"cmFuc2l0aW9uLnByb3RvEiJkZWNlbnRyYWxhbmQuc2RrLmNvbXBvbmVudHMu",
"Y29tbW9uIpYBChBDYW1lcmFUcmFuc2l0aW9uEhgKC2Zyb21fZW50aXR5GAEg",
"ASgNSAGIAQESFgoJdG9fZW50aXR5GAIgASgNSAKIAQESDgoEdGltZRgDIAEo",
"AkgAEg8KBXNwZWVkGAQgASgCSABCEQoPdHJhbnNpdGlvbl9tb2RlQg4KDF9m",
"cm9tX2VudGl0eUIMCgpfdG9fZW50aXR5QhSqAhFEQ0wuRUNTQ29tcG9uZW50",
"c2IGcHJvdG8z"));
"Y29tbW9uIkYKEENhbWVyYVRyYW5zaXRpb24SDgoEdGltZRgBIAEoAkgAEg8K",
"BXNwZWVkGAIgASgCSABCEQoPdHJhbnNpdGlvbl9tb2RlQhSqAhFEQ0wuRUNT",
"Q29tcG9uZW50c2IGcHJvdG8z"));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { },
new pbr::GeneratedClrTypeInfo(null, null, new pbr::GeneratedClrTypeInfo[] {
new pbr::GeneratedClrTypeInfo(typeof(global::DCL.ECSComponents.CameraTransition), global::DCL.ECSComponents.CameraTransition.Parser, new[]{ "FromEntity", "ToEntity", "Time", "Speed" }, new[]{ "TransitionMode", "FromEntity", "ToEntity" }, null, null, null)
new pbr::GeneratedClrTypeInfo(typeof(global::DCL.ECSComponents.CameraTransition), global::DCL.ECSComponents.CameraTransition.Parser, new[]{ "Time", "Speed" }, new[]{ "TransitionMode" }, null, null, null)
}));
}
#endregion

}
#region Messages
/// <summary>
/// Defines the transition used towards the camera that contains the CameraTransition.
/// This structure may be updated in the future to specify from/to entities and to have easing functions.
/// </summary>
public sealed partial class CameraTransition : pb::IMessage<CameraTransition>
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
, pb::IBufferMessage
#endif
{
private static readonly pb::MessageParser<CameraTransition> _parser = new pb::MessageParser<CameraTransition>(() => new CameraTransition());
private pb::UnknownFieldSet _unknownFields;
private int _hasBits0;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public static pb::MessageParser<CameraTransition> Parser { get { return _parser; } }
Expand Down Expand Up @@ -76,9 +77,6 @@ public CameraTransition() {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public CameraTransition(CameraTransition other) : this() {
_hasBits0 = other._hasBits0;
fromEntity_ = other.fromEntity_;
toEntity_ = other.toEntity_;
switch (other.TransitionModeCase) {
case TransitionModeOneofCase.Time:
Time = other.Time;
Expand All @@ -97,58 +95,8 @@ public CameraTransition Clone() {
return new CameraTransition(this);
}

/// <summary>Field number for the "from_entity" field.</summary>
public const int FromEntityFieldNumber = 1;
private uint fromEntity_;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public uint FromEntity {
get { if ((_hasBits0 & 1) != 0) { return fromEntity_; } else { return 0; } }
set {
_hasBits0 |= 1;
fromEntity_ = value;
}
}
/// <summary>Gets whether the "from_entity" field is set</summary>
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public bool HasFromEntity {
get { return (_hasBits0 & 1) != 0; }
}
/// <summary>Clears the value of the "from_entity" field</summary>
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public void ClearFromEntity() {
_hasBits0 &= ~1;
}

/// <summary>Field number for the "to_entity" field.</summary>
public const int ToEntityFieldNumber = 2;
private uint toEntity_;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public uint ToEntity {
get { if ((_hasBits0 & 2) != 0) { return toEntity_; } else { return 0; } }
set {
_hasBits0 |= 2;
toEntity_ = value;
}
}
/// <summary>Gets whether the "to_entity" field is set</summary>
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public bool HasToEntity {
get { return (_hasBits0 & 2) != 0; }
}
/// <summary>Clears the value of the "to_entity" field</summary>
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public void ClearToEntity() {
_hasBits0 &= ~2;
}

/// <summary>Field number for the "time" field.</summary>
public const int TimeFieldNumber = 3;
public const int TimeFieldNumber = 1;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public float Time {
Expand All @@ -160,7 +108,7 @@ public float Time {
}

/// <summary>Field number for the "speed" field.</summary>
public const int SpeedFieldNumber = 4;
public const int SpeedFieldNumber = 2;
/// <summary>
/// meters per second; e.g. speed 1 -> 1 meter per second
/// </summary>
Expand All @@ -178,8 +126,8 @@ public float Speed {
/// <summary>Enum of possible cases for the "transition_mode" oneof.</summary>
public enum TransitionModeOneofCase {
None = 0,
Time = 3,
Speed = 4,
Time = 1,
Speed = 2,
}
private TransitionModeOneofCase transitionModeCase_ = TransitionModeOneofCase.None;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
Expand Down Expand Up @@ -210,8 +158,6 @@ public bool Equals(CameraTransition other) {
if (ReferenceEquals(other, this)) {
return true;
}
if (FromEntity != other.FromEntity) return false;
if (ToEntity != other.ToEntity) return false;
if (!pbc::ProtobufEqualityComparers.BitwiseSingleEqualityComparer.Equals(Time, other.Time)) return false;
if (!pbc::ProtobufEqualityComparers.BitwiseSingleEqualityComparer.Equals(Speed, other.Speed)) return false;
if (TransitionModeCase != other.TransitionModeCase) return false;
Expand All @@ -222,8 +168,6 @@ public bool Equals(CameraTransition other) {
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public override int GetHashCode() {
int hash = 1;
if (HasFromEntity) hash ^= FromEntity.GetHashCode();
if (HasToEntity) hash ^= ToEntity.GetHashCode();
if (transitionModeCase_ == TransitionModeOneofCase.Time) hash ^= pbc::ProtobufEqualityComparers.BitwiseSingleEqualityComparer.GetHashCode(Time);
if (transitionModeCase_ == TransitionModeOneofCase.Speed) hash ^= pbc::ProtobufEqualityComparers.BitwiseSingleEqualityComparer.GetHashCode(Speed);
hash ^= (int) transitionModeCase_;
Expand All @@ -245,20 +189,12 @@ public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (HasFromEntity) {
output.WriteRawTag(8);
output.WriteUInt32(FromEntity);
}
if (HasToEntity) {
output.WriteRawTag(16);
output.WriteUInt32(ToEntity);
}
if (transitionModeCase_ == TransitionModeOneofCase.Time) {
output.WriteRawTag(29);
output.WriteRawTag(13);
output.WriteFloat(Time);
}
if (transitionModeCase_ == TransitionModeOneofCase.Speed) {
output.WriteRawTag(37);
output.WriteRawTag(21);
output.WriteFloat(Speed);
}
if (_unknownFields != null) {
Expand All @@ -271,20 +207,12 @@ public void WriteTo(pb::CodedOutputStream output) {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (HasFromEntity) {
output.WriteRawTag(8);
output.WriteUInt32(FromEntity);
}
if (HasToEntity) {
output.WriteRawTag(16);
output.WriteUInt32(ToEntity);
}
if (transitionModeCase_ == TransitionModeOneofCase.Time) {
output.WriteRawTag(29);
output.WriteRawTag(13);
output.WriteFloat(Time);
}
if (transitionModeCase_ == TransitionModeOneofCase.Speed) {
output.WriteRawTag(37);
output.WriteRawTag(21);
output.WriteFloat(Speed);
}
if (_unknownFields != null) {
Expand All @@ -297,12 +225,6 @@ public void WriteTo(pb::CodedOutputStream output) {
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public int CalculateSize() {
int size = 0;
if (HasFromEntity) {
size += 1 + pb::CodedOutputStream.ComputeUInt32Size(FromEntity);
}
if (HasToEntity) {
size += 1 + pb::CodedOutputStream.ComputeUInt32Size(ToEntity);
}
if (transitionModeCase_ == TransitionModeOneofCase.Time) {
size += 1 + 4;
}
Expand All @@ -321,12 +243,6 @@ public void MergeFrom(CameraTransition other) {
if (other == null) {
return;
}
if (other.HasFromEntity) {
FromEntity = other.FromEntity;
}
if (other.HasToEntity) {
ToEntity = other.ToEntity;
}
switch (other.TransitionModeCase) {
case TransitionModeOneofCase.Time:
Time = other.Time;
Expand All @@ -351,19 +267,11 @@ public void MergeFrom(pb::CodedInputStream input) {
default:
_unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 8: {
FromEntity = input.ReadUInt32();
break;
}
case 16: {
ToEntity = input.ReadUInt32();
break;
}
case 29: {
case 13: {
Time = input.ReadFloat();
break;
}
case 37: {
case 21: {
Speed = input.ReadFloat();
break;
}
Expand All @@ -382,19 +290,11 @@ public void MergeFrom(pb::CodedInputStream input) {
default:
_unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input);
break;
case 8: {
FromEntity = input.ReadUInt32();
break;
}
case 16: {
ToEntity = input.ReadUInt32();
break;
}
case 29: {
case 13: {
Time = input.ReadFloat();
break;
}
case 37: {
case 21: {
Speed = input.ReadFloat();
break;
}
Expand Down
Loading
Loading