2024-09-03 12:25:06 +02:00

139 lines
4.2 KiB
C#

using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using UnityEngine;
using UnityEditor;
namespace FreeD
{
[ExecuteInEditMode]
public class FreeDSimulator : MonoBehaviour
{
[Header("Sending to destination")]
public string destinationIp = "127.0.0.1";
public int destinationPort = 40_000;
public bool active = true;
[Header("Setup")]
public int cameraId = 0;
public Camera physicalCamera;
private Transform target;
[Tooltip("Run the server in edit mode")]
public new bool runInEditMode = true;
[Tooltip("Show received messages in Unity console")]
public bool showPacketInConsole = true;
public PacketSent sent;
// Communication setup
UdpClient listener;
IPEndPoint groupEP;
Packet packet;
public delegate void PacketSent(Packet packet);
public void OnEnable()
{
if (!Application.isPlaying && !runInEditMode) return;
listener = new UdpClient(destinationIp, destinationPort);
groupEP = new IPEndPoint(IPAddress.Parse(destinationIp), destinationPort);
physicalCamera = GetComponent<Camera>();
target = physicalCamera.gameObject.transform;
active = true;
}
private void OnDisable()
{
Stop();
}
public void Update()
{
if (!Application.isPlaying && !runInEditMode) return;
if (!active) return;
try
{
packet = new Packet();
// Mathematical transformations according to `FreeDLink.cs`
packet.Id = cameraId;
packet.Pan = target.transform.localRotation.eulerAngles.y; // degrees
packet.Tilt = -target.transform.localRotation.eulerAngles.x;
packet.Roll = -target.transform.localRotation.eulerAngles.z;
packet.PosZ = -target.transform.localPosition.z * 1000f; // millimeters
packet.PosX = target.transform.localPosition.x * 1000f;
packet.PosY = target.transform.localPosition.y * 1000f;
if(physicalCamera != null)
{
// Original value FreeD is between [0-4095], but values in the Virtual Studio Labs are between [21-63]
packet.Zoom = physicalCamera.fieldOfView * ((19f-169f)/(63f-21f));
packet.Focus = -physicalCamera.focusDistance * 1000f; // Value between 0-4095
}
else
{
packet.Zoom = 0.5f;
packet.Focus = -800f;
}
try
{
var binary_packet = Packet.Encode(packet);
var result = listener.Send(binary_packet, binary_packet.Length);
if(sent != null) sent(packet);
if(showPacketInConsole)
Debug.Log($"Camera ID {packet.Id} sending: {packet.Id},{packet.Pan},{packet.Tilt},{packet.Roll},{packet.PosZ},{packet.PosX},{packet.PosY},{packet.Zoom},{packet.Focus}");
}
catch(Exception e)
{
Debug.LogError(e);
}
}
catch (SocketException e)
{
Debug.LogError(e);
}
}
public void Stop()
{
active = false;
listener.Close();
}
}
#if UNITY_EDITOR
[CustomEditor(typeof(FreeDSimulator))]
public class FreeDSimulatorEditor : Editor
{
public override void OnInspectorGUI()
{
FreeDSimulator myScript = (FreeDSimulator)target;
if(myScript.active)
{
if (GUILayout.Button($"Stop Simulation Camera ID {myScript.cameraId}"))
myScript.enabled = false;
}
else
{
if (GUILayout.Button($"Start Simulation Camera ID {myScript.cameraId}"))
myScript.enabled = true;
}
DrawDefaultInspector();
}
}
#endif
}