This commit is contained in:
Pascal Serrarens 2024-12-11 14:52:57 +01:00
parent 3523de1197
commit ae20e7a203
2 changed files with 303 additions and 124 deletions

View File

@ -1,5 +1,4 @@
using System; using System;
using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Net; using System.Net;
@ -7,7 +6,6 @@ using System.Net.Sockets;
using System.Threading.Tasks; using System.Threading.Tasks;
using UnityEngine; using UnityEngine;
using GLTFast; using GLTFast;
using Unity.Collections.LowLevel.Unsafe;
#if hNW_ROBOID #if hNW_ROBOID
@ -38,12 +36,16 @@ namespace Passer.Humanoid {
protected IPEndPoint endPoint; protected IPEndPoint endPoint;
protected object obj; protected object obj;
protected AsyncCallback receiveCallback; protected AsyncCallback receiveCallback;
protected Client client; protected HumanoidClient client;
//ConcurrentQueue<HumanoidNetworking.IMessage> messageQueue = new ConcurrentQueue<HumanoidNetworking.IMessage>();
protected Stream dataStream; protected Stream dataStream;
public byte networkId; public byte networkId;
public const byte Pose_Position = 0x01;
public const byte Pose_Orientation = 0x02;
public const byte Pose_LinearVelocity = 0x04;
public const byte Pose_AngularVelocity = 0x08;
#region Dummy Interface #region Dummy Interface
public void Send(bool b) { } public void Send(bool b) { }
@ -128,13 +130,13 @@ namespace Passer.Humanoid {
public class HumanoidClient : Client { public class HumanoidClient : Client {
readonly HumanoidPlayer player; readonly HumanoidPlayer player;
public List<Thing> allThings = new();
public HumanoidClient(UdpClient udpClient, string ipAddress, int port, HumanoidPlayer player) : base(udpClient, port) { public HumanoidClient(UdpClient udpClient, string ipAddress, int port, HumanoidPlayer player) : base(udpClient, port) {
this.player = player; this.player = player;
} }
protected override void ProcessNetworkId(NetworkIdMsg msg) { protected override void ProcessNetworkId(NetworkIdMsg msg) {
Debug.Log($"NetworkId [{msg.networkId}]");
if (this.networkId == msg.networkId) if (this.networkId == msg.networkId)
return; return;
@ -142,12 +144,35 @@ namespace Passer.Humanoid {
player.ProcessNetworkId(this, msg); player.ProcessNetworkId(this, msg);
} }
protected override void ProcessInvestigate(InvestigateMsg msg) {
Debug.Log($"Investigate [{msg.networkId}/{msg.thingId}]");
Thing thing = Thing.GetThing(msg.networkId, msg.thingId);
Thing parentThing = thing.transform.parent.GetComponentInParent<Thing>();
if (parentThing != null)
ThingMsg.Send(this, thing.networkId, thing.thingId, parentThing.thingId);
else
ThingMsg.Send(this, thing.networkId, thing.thingId, 0);
NameMsg.Send(this, thing.thingId, thing.name);
if (thing.modelUrl != null)
ModelUrlMsg.Send(this, thing.thingId, thing.modelUrl);
}
protected override void ProcessThing(ThingMsg thing) {
player.ProcessThing(this, thing);
}
protected override void ProcessName(NameMsg msg) { protected override void ProcessName(NameMsg msg) {
Debug.Log($"Name [{msg.networkId}/{msg.thingId} {msg.name}]"); Debug.Log($"Name [{msg.networkId}/{msg.thingId}] {msg.name}");
Thing thing = Thing.GetThing(msg.networkId, msg.thingId);
if (thing == null) {
Debug.LogWarning($"could not find thing [{msg.networkId}/{msg.thingId}] for name {msg.name}");
return;
}
thing.gameObject.name = msg.name;
} }
protected override void ProcessModelUrl(ModelUrlMsg msg) { protected override void ProcessModelUrl(ModelUrlMsg msg) {
Debug.Log($"Model [{msg.networkId}/{msg.thingId} {msg.url}]"); Debug.Log($"Model [{msg.networkId}/{msg.thingId}] {msg.url}");
int ix = msg.url.LastIndexOf("."); int ix = msg.url.LastIndexOf(".");
if (ix < 0) if (ix < 0)
return; return;
@ -161,19 +186,31 @@ namespace Passer.Humanoid {
} }
protected override void ProcessPose(PoseMsg msg) { protected override void ProcessPose(PoseMsg msg) {
Debug.Log($"Pose [{msg.networkId}/{msg.thingId}]"); Thing thing = Thing.allThings.Find(thing => thing.networkId == msg.networkId && thing.thingId == msg.thingId);
Thing thing = allThings.Find(thing => thing.networkId == msg.networkId && thing.thingId == msg.thingId);
if (thing == null) { if (thing == null) {
Debug.Log($"Unknown thing [{msg.networkId}/{msg.thingId}]"); Debug.Log($"Pose for unknown thing [{msg.networkId}/{msg.thingId}] -> create thing");
thing = Thing.Create(player.gameObject, this, msg.thingId, 0); thing = player.CreateThing(this, msg.networkId, msg.thingId, 0, 0);
InvestigateMsg.Send(this, msg.networkId, msg.thingId); InvestigateMsg.Send(this, msg.networkId, msg.thingId);
} }
if (msg.thingId != 0)
Debug.Log($"Pose [{msg.networkId}/{msg.thingId}] {thing.transform.name} {ToQuaternion(msg.orientation).eulerAngles} ");
if ((msg.poseType & Pose_Position) != 0)
thing.transform.localPosition = ToVector3(msg.position);
if ((msg.poseType & Pose_Orientation) != 0) {
thing.transform.localRotation = ToQuaternion(msg.orientation);
}
} }
} }
protected virtual void Awake() { protected virtual void Awake() {
mInstance = this; mInstance = this;
endPoint = new IPEndPoint(IPAddress.Any, sitePort + 3);
udpClient = new UdpClient(endPoint);
receiveCallback = new System.AsyncCallback(result => ReceiveUDP(client, result));
udpClient.BeginReceive(receiveCallback, obj);
client = new HumanoidClient(udpClient, siteAddress, sitePort, this);
GameObject.DontDestroyOnLoad(this.gameObject); GameObject.DontDestroyOnLoad(this.gameObject);
humanoids = HumanoidNetworking.FindLocalHumanoids(); humanoids = HumanoidNetworking.FindLocalHumanoids();
@ -185,12 +222,6 @@ namespace Passer.Humanoid {
humanoid.humanoidNetworking = this; humanoid.humanoidNetworking = this;
} }
endPoint = new IPEndPoint(IPAddress.Any, sitePort + 3);
udpClient = new UdpClient(endPoint);
receiveCallback = new System.AsyncCallback(result => ReceiveUDP(client, result));
udpClient.BeginReceive(receiveCallback, obj);
client = new HumanoidClient(udpClient, siteAddress, sitePort, this);
// //
//endpoint = new IPEndPoint(IPAddress.Any, sitePort); //endpoint = new IPEndPoint(IPAddress.Any, sitePort);
//udpClient = new UdpClient(sitePort); //udpClient = new UdpClient(sitePort);
@ -199,7 +230,7 @@ namespace Passer.Humanoid {
dataStream = new EchoStream(); dataStream = new EchoStream();
//client = newClient ? Client.NewUDPClient(udpClient, endpoint.Address.ToString(), endpoint.Port) : Client.clients[0]; //client = newClient ? Client.NewUDPClient(udpClient, endpoint.Address.ToString(), endpoint.Port) : Client.clients[0];
//udpClient.BeginReceive(new System.AsyncCallback(result => ReceiveUDP(client, result)), null); //udpClient.BeginReceive(new System.AsyncCallback(result => ReceiveUDP(client, result)), null);
Task task = Task.Run(() => SiteServer.ReceiveData(dataStream, client)); Task task = Task.Run(() => SiteServer.ReceiveData(dataStream, client));
} }
protected void ReceiveUDP(Client client, IAsyncResult result) { protected void ReceiveUDP(Client client, IAsyncResult result) {
@ -251,7 +282,7 @@ namespace Passer.Humanoid {
humanoidClient.ProcessMessage(msg); humanoidClient.ProcessMessage(msg);
} }
} }
if (Time.time > lastSend + 1 / sendRate) { if (Time.time > lastSend + 1 / sendRate) {
if (humanoids != null) { if (humanoids != null) {
foreach (HumanoidControl humanoid in humanoids) { foreach (HumanoidControl humanoid in humanoids) {
@ -262,7 +293,7 @@ namespace Passer.Humanoid {
} }
lastSend = Time.time; lastSend = Time.time;
} }
if (Time.time > lastClientMsg + clientMsgInterval) { if (Time.time > lastClientMsg + clientMsgInterval) {
SendClientMsg(humanoids[0]); // We just need it for the networkId SendClientMsg(humanoids[0]); // We just need it for the networkId
lastClientMsg = Time.time; lastClientMsg = Time.time;
} }
@ -304,6 +335,60 @@ namespace Passer.Humanoid {
} }
#endregion Client #endregion Client
#region Investigate
protected void ProcessInvestigate(InvestigateMsg investigate) {
}
#endregion Investigate
#region Thing
protected virtual void ProcessThing(Client client, ThingMsg msg) {
DebugLog($"Process Thing [{msg.networkId}/{msg.thingId}] parent:{msg.parentId} type: {msg.thingType}");
Thing thing = Thing.GetThing(msg.networkId, msg.thingId);
if (thing == null)
CreateThing(client, msg.networkId, msg.thingId, msg.thingType, msg.parentId);
else {
thing.objectType = msg.thingType;
if (msg.parentId != 0) {
Thing parentThing = Thing.GetThing(msg.networkId, msg.parentId);
if (parentThing != null) {
if (thing.transform.parent != parentThing.transform) {
Debug.Log($"Changed parent to {parentThing.gameObject.name} {parentThing.thingId}");
thing.transform.SetParent(parentThing.transform, true);
}
}
else {
Debug.LogWarning($"Could not find the parent {msg.parentId} for {msg.thingId}");
thing.transform.SetParent(this.transform);
}
}
}
}
protected virtual Thing CreateThing(Client client, byte networkId, byte thingId, byte thingType, byte parentId) {
DebugLog($"Create new thing [{networkId}/{thingId}]");
GameObject thingObject = new("Thing " + thingId);
Thing thing = Thing.Create(thingObject, client, networkId, thingId, thingType);
if (parentId != 0) {
Thing parentThing = Thing.allThings.Find(thing => thing.networkId == networkId && thing.thingId == parentId);
if (parentThing != null)
thing.transform.SetParent(parentThing.transform);
else {
Debug.LogWarning($"Could not find the parent {parentId} for {thingId}");
thing.transform.SetParent(this.transform);
}
}
return thing;
}
#endregion Thing
#region Pose #region Pose
public virtual void UpdateHumanoidPose(HumanoidControl humanoid) { public virtual void UpdateHumanoidPose(HumanoidControl humanoid) {
@ -318,11 +403,11 @@ namespace Passer.Humanoid {
SendBone(humanoid.leftHandTarget.upperArm); SendBone(humanoid.leftHandTarget.upperArm);
SendBone(humanoid.leftHandTarget.forearm); SendBone(humanoid.leftHandTarget.forearm);
SendBone(humanoid.leftHandTarget.hand); SendBone(humanoid.leftHandTarget.hand, false, true);
SendBone(humanoid.rightHandTarget.upperArm); SendBone(humanoid.rightHandTarget.upperArm);
SendBone(humanoid.rightHandTarget.forearm); SendBone(humanoid.rightHandTarget.forearm);
SendBone(humanoid.rightHandTarget.hand); SendBone(humanoid.rightHandTarget.hand, false, true);
SendBone(humanoid.leftFootTarget.upperLeg); SendBone(humanoid.leftFootTarget.upperLeg);
SendBone(humanoid.leftFootTarget.lowerLeg); SendBone(humanoid.leftFootTarget.lowerLeg);
@ -333,7 +418,7 @@ namespace Passer.Humanoid {
SendBone(humanoid.rightFootTarget.foot); SendBone(humanoid.rightFootTarget.foot);
} }
private void SendBone(HumanoidTarget.TargetedBone bone, bool isRoot = false) { private void SendBone(HumanoidTarget.TargetedBone bone, bool isRoot = false, bool calculateOrientation = false) {
//RoboidBonePose bonePose = new(bone, isRoot); //RoboidBonePose bonePose = new(bone, isRoot);
//byte[] data = bonePose.Serialize(); //byte[] data = bonePose.Serialize();
//if (bonePose.bonePosition != null) { //if (bonePose.bonePosition != null) {
@ -351,6 +436,9 @@ namespace Passer.Humanoid {
} }
else { else {
Quaternion orientation = bone.bone.transform.localRotation; Quaternion orientation = bone.bone.transform.localRotation;
if (calculateOrientation)
orientation = Quaternion.Inverse(bone.parent.bone.transform.rotation) * bone.bone.transform.rotation;
//orientation = Quaternion.Inverse(bone.bone.transform.parent.rotation) * bone.bone.transform.rotation;
Quat32 boneOrientation = new(orientation.x, orientation.y, orientation.z, orientation.w); Quat32 boneOrientation = new(orientation.x, orientation.y, orientation.z, orientation.w);
PoseMsg.Send(client, (byte)bone.boneId, null, boneOrientation); PoseMsg.Send(client, (byte)bone.boneId, null, boneOrientation);
} }
@ -386,36 +474,45 @@ namespace Passer.Humanoid {
SendName(remoteHumanoid, 0, "Humanoid"); SendName(remoteHumanoid, 0, "Humanoid");
SendModel(remoteHumanoid, "https://gitlab.passervr.com/passer/models/humanoid/-/raw/main/MakeHumanPasserMedium.glb?ref_type=heads&inline=false"); SendModel(remoteHumanoid, "https://gitlab.passervr.com/passer/models/humanoid/-/raw/main/MakeHumanPasserMedium.glb?ref_type=heads&inline=false");
SendSubThing(remoteHumanoid, remoteHumanoid.hipsTarget.hips); InitBone(client, remoteHumanoid, remoteHumanoid.hipsTarget.hips);
SendSubThing(remoteHumanoid, remoteHumanoid.hipsTarget.spine); InitBone(client, remoteHumanoid, remoteHumanoid.hipsTarget.spine);
SendSubThing(remoteHumanoid, remoteHumanoid.hipsTarget.chest); InitBone(client, remoteHumanoid, remoteHumanoid.hipsTarget.chest);
SendSubThing(remoteHumanoid, remoteHumanoid.headTarget.neck); InitBone(client, remoteHumanoid, remoteHumanoid.headTarget.neck);
SendSubThing(remoteHumanoid, remoteHumanoid.headTarget.head); InitBone(client, remoteHumanoid, remoteHumanoid.headTarget.head);
SendSubThing(remoteHumanoid, remoteHumanoid.leftHandTarget.shoulder); InitBone(client, remoteHumanoid, remoteHumanoid.leftHandTarget.shoulder);
SendSubThing(remoteHumanoid, remoteHumanoid.leftHandTarget.upperArm); InitBone(client, remoteHumanoid, remoteHumanoid.leftHandTarget.upperArm);
SendSubThing(remoteHumanoid, remoteHumanoid.leftHandTarget.forearm); InitBone(client, remoteHumanoid, remoteHumanoid.leftHandTarget.forearm);
SendSubThing(remoteHumanoid, remoteHumanoid.leftHandTarget.hand); InitBone(client, remoteHumanoid, remoteHumanoid.leftHandTarget.hand);
SendSubThing(remoteHumanoid, remoteHumanoid.rightHandTarget.shoulder); InitBone(client, remoteHumanoid, remoteHumanoid.rightHandTarget.shoulder);
SendSubThing(remoteHumanoid, remoteHumanoid.rightHandTarget.upperArm); InitBone(client, remoteHumanoid, remoteHumanoid.rightHandTarget.upperArm);
SendSubThing(remoteHumanoid, remoteHumanoid.rightHandTarget.forearm); InitBone(client, remoteHumanoid, remoteHumanoid.rightHandTarget.forearm);
SendSubThing(remoteHumanoid, remoteHumanoid.rightHandTarget.hand); InitBone(client, remoteHumanoid, remoteHumanoid.rightHandTarget.hand);
SendSubThing(remoteHumanoid, remoteHumanoid.rightFootTarget.upperLeg); InitBone(client, remoteHumanoid, remoteHumanoid.rightFootTarget.upperLeg);
SendSubThing(remoteHumanoid, remoteHumanoid.rightFootTarget.lowerLeg); InitBone(client, remoteHumanoid, remoteHumanoid.rightFootTarget.lowerLeg);
SendSubThing(remoteHumanoid, remoteHumanoid.rightFootTarget.foot); InitBone(client, remoteHumanoid, remoteHumanoid.rightFootTarget.foot);
SendSubThing(remoteHumanoid, remoteHumanoid.rightFootTarget.toes); InitBone(client, remoteHumanoid, remoteHumanoid.rightFootTarget.toes);
SendSubThing(remoteHumanoid, remoteHumanoid.leftFootTarget.upperLeg); InitBone(client, remoteHumanoid, remoteHumanoid.leftFootTarget.upperLeg);
SendSubThing(remoteHumanoid, remoteHumanoid.leftFootTarget.lowerLeg); InitBone(client, remoteHumanoid, remoteHumanoid.leftFootTarget.lowerLeg);
SendSubThing(remoteHumanoid, remoteHumanoid.leftFootTarget.foot); InitBone(client, remoteHumanoid, remoteHumanoid.leftFootTarget.foot);
SendSubThing(remoteHumanoid, remoteHumanoid.leftFootTarget.toes); InitBone(client, remoteHumanoid, remoteHumanoid.leftFootTarget.toes);
SendSubThing(remoteHumanoid, remoteHumanoid.rightFootTarget.upperLeg); InitBone(client, remoteHumanoid, remoteHumanoid.rightFootTarget.upperLeg);
SendSubThing(remoteHumanoid, remoteHumanoid.rightFootTarget.lowerLeg); InitBone(client, remoteHumanoid, remoteHumanoid.rightFootTarget.lowerLeg);
SendSubThing(remoteHumanoid, remoteHumanoid.rightFootTarget.foot); InitBone(client, remoteHumanoid, remoteHumanoid.rightFootTarget.foot);
SendSubThing(remoteHumanoid, remoteHumanoid.rightFootTarget.toes); InitBone(client, remoteHumanoid, remoteHumanoid.rightFootTarget.toes);
}
protected void InitBone(Client client, HumanoidControl humanoid, HumanoidTarget.TargetedBone bone) {
Thing thing = Thing.Create(bone.bone.transform.gameObject, client, client.networkId, (byte)bone.boneId, 0x00);
if (bone.parent != null)
ThingMsg.Send(client, thing.thingId, thing.objectType, (byte)bone.parent.boneId);
else
ThingMsg.Send(client, thing.thingId, thing.objectType, 0);
NameMsg.Send(client, thing.thingId, bone.bone.transform.name);
} }
//#endregion //#endregion
@ -540,91 +637,153 @@ namespace Passer.Humanoid {
private Dictionary<string, GltfImport> gltfCache = new(); private Dictionary<string, GltfImport> gltfCache = new();
private async void ProcessGltfModel(ModelUrlMsg msg) { private async void ProcessGltfModel(ModelUrlMsg msg) {
Transform parentTransform = this.transform;
Thing parentThing = Thing.GetThing(msg.networkId, msg.thingId);
if (parentThing != null) {
if (parentThing.modelUrl == msg.url) {
// Thing already has this model
Debug.Log($"thing [{msg.networkId}/{msg.thingId}] already has model {msg.url}");
return;
}
else
parentThing.modelUrl = msg.url;
parentTransform = parentThing.transform;
}
if (gltfCache.TryGetValue(msg.url, out GltfImport gltfImport)) { if (gltfCache.TryGetValue(msg.url, out GltfImport gltfImport)) {
Debug.Log("Found buffered GLTF for: " + msg.url); Debug.Log($"Instantiate [{msg.networkId}/{msg.thingId}] ***** buffered GLTF: " + msg.url);
Transform parentTransform = await InstantiateGltf(gltfImport, msg.thingId, msg.scale); await gltfImport.InstantiateMainSceneAsync(parentTransform);
}
else {
Debug.Log("Loading GLTF model from: " + msg.url);
gltfImport = new();
bool success = await gltfImport.Load(msg.url);
if (success == false)
return;
gltfCache.Add(msg.url, gltfImport);
Debug.Log($"Instantiate [{msg.networkId}/{msg.thingId}] ***** loaded GLTF: " + msg.url);
await gltfImport.InstantiateMainSceneAsync(parentTransform);
}
parentTransform.localScale = Vector3.one * msg.scale;
ScanModelForThings(parentTransform);
// Correct lights
if (parentTransform != null) {
Light[] lights = parentTransform.GetComponentsInChildren<Light>();
foreach (Light light in lights)
light.intensity = 1; // light.intensity / 1000;
}
}
//private async Task<Transform> InstantiateGltf(GltfImport gltfImport, byte objectId, float scale) {
// Debug.Log("Instantiate GLTF model");
// Transform parentTransform = this.transform;
// //Thing parentThing = allThings.Find(thing => thing.thingId == objectId);
// //if (parentThing != null)
// // parentTransform = parentThing.transform;
// await gltfImport.InstantiateMainSceneAsync(parentTransform);
// parentTransform.localScale = Vector3.one * scale;
// return parentTransform;
//}
private void ScanModelForThings(Transform parentTransform) {
if (parentTransform == null)
return;
Debug.Log("scanning model for things.....");
SkinnedMeshRenderer[] meshRenderers = parentTransform.GetComponentsInChildren<SkinnedMeshRenderer>();
if (meshRenderers.Length > 0) {
foreach (SkinnedMeshRenderer meshRenderer in meshRenderers) {
if (meshRenderer.rootBone != null) {
Debug.Log("Found a skinned mesh with bones");
ScanForThings(parentTransform);//meshRenderer.rootBone);
break;
}
}
}
else {
Renderer[] renderers = parentTransform.GetComponentsInChildren<Renderer>(); Renderer[] renderers = parentTransform.GetComponentsInChildren<Renderer>();
foreach (Renderer renderer in renderers) { foreach (Renderer renderer in renderers) {
MeshCollider c = renderer.gameObject.AddComponent<MeshCollider>(); MeshCollider c = renderer.gameObject.AddComponent<MeshCollider>();
c.convex = true; c.convex = true;
} }
ScanForThings(parentTransform);
} }
else { }
if (!loadingModel) {
loadingModel = true;
Debug.Log("Loading GLTF model from: " + msg.url); private void ScanForThings(Transform rootTransform) {
gltfImport = new(); Thing[] thingArray = Thing.allThings.ToArray();
bool success = await gltfImport.Load(msg.url);
if (success) {
gltfCache.Add(msg.url, gltfImport);
loadingModel = false;
Transform parentTransform = await InstantiateGltf(gltfImport, msg.thingId, msg.scale);
ScanModelForThings(parentTransform);
// Correct lights
Light[] lights = parentTransform.GetComponentsInChildren<Light>();
foreach (Light light in lights)
light.intensity = 1; // light.intensity / 1000;
for (int thingIx = 0; thingIx < thingArray.Length; thingIx++) {
Thing thing = thingArray[thingIx];
//Debug.Log($"find {thing.name}");
GameObject foundObj = FindThingByName(thing, rootTransform);
if (foundObj != null) {
Thing foundThing = foundObj.GetComponent<Thing>();
if (foundObj != thing.gameObject) {
if (foundThing == null) {
Debug.Log($"move thing [{thing.networkId}/{thing.thingId}] to {foundObj.name}");
Thing.allThings.Remove(thing);
foundThing = thing.CopyTo(foundObj);
Thing.allThings.Add(foundThing);
}
} }
else { if (thing.transform.childCount > foundObj.transform.childCount) {
this.transform.localScale = Vector3.one * 1; CopyChildren(thing, foundObj.transform);
}
}
//else
// Debug.LogWarning($"Could not find thing {thing.name}");
}
}
private GameObject FindThingByName(Thing thing, Transform rootTransform) {
if (rootTransform == null || thing == null)
return null;
if (rootTransform.name == thing.name)
return rootTransform.gameObject;
for (int childIx = 0; childIx < rootTransform.childCount; childIx++) {
Transform child = rootTransform.GetChild(childIx);
GameObject foundObj = FindThingByName(thing, child);
if (foundObj != null)
return foundObj;
}
return null;
}
private void CopyChildren(Thing from, Transform to) {
for (int childIx = 0; childIx < from.transform.childCount; childIx++) {
Transform child = from.transform.GetChild(childIx);
//Debug.Log(child.name);
bool found = false;
foreach (Transform toChild in to) {
if (child.name == toChild.name) {
found = true;
break;
}
}
if (!found) {
//Debug.Log("...not found");
Thing childThing = child.GetComponent<Thing>();
if (childThing != null) {
Thing.allThings.Remove(childThing);
GameObject newChildObj = new GameObject(child.name);
newChildObj.transform.SetParent(to.transform);
//newChildObj.transform.SetLocalPositionAndRotation(
// child.transform.localPosition, child.transform.localRotation);
//newChildObj.transform.localScale = Vector3.one;
Thing newThing = childThing.CopyTo(newChildObj);
Thing.allThings.Add(newThing);
} }
} }
} }
} }
private async Task<Transform> InstantiateGltf(GltfImport gltfImport, byte objectId, float scale) {
Debug.Log("Instantiate GLTF model");
Transform parentTransform = this.transform;
//Thing parentThing = allThings.Find(thing => thing.thingId == objectId);
//if (parentThing != null)
// parentTransform = parentThing.transform;
await gltfImport.InstantiateMainSceneAsync(parentTransform);
parentTransform.localScale = Vector3.one * scale;
return parentTransform;
}
private void ScanModelForThings(Transform parentTransform) {
//Debug.Log("scanning model for things.....");
//SkinnedMeshRenderer[] meshRenderers = parentTransform.GetComponentsInChildren<SkinnedMeshRenderer>();
//if (meshRenderers.Length > 0) {
// foreach (SkinnedMeshRenderer meshRenderer in meshRenderers) {
// if (meshRenderer.rootBone != null) {
// Debug.Log("Found a skinned mesh with bones");
// //string meshRendererName = meshRenderer.transform.name;
// //Thing meshRendererThing = allThings.Find(thing => thing.name == meshRendererName);
// //SkinnedMeshRenderer thingMeshRenderer = meshRendererThing.gameObject.AddComponent<SkinnedMeshRenderer>();
// //thingMeshRenderer.materials = meshRenderer.materials;
// //thingMeshRenderer.sharedMesh = meshRenderer.sharedMesh;
// //thingMeshRenderer.bones = GetSkinnedThings(meshRenderer);
// //ReplaceSkinnedBones(meshRenderer);
// //string rootBoneName = meshRenderer.rootBone.name;
// //Thing rootBoneThing = allThings.Find(thing => thing.name == rootBoneName);
// //if (rootBoneName != null)
// // meshRenderer.rootBone = rootBoneThing.transform;
// //else
// // Debug.LogWarning("Could not find the root bone thing");
// ScanForThings(meshRenderer.rootBone);
// //meshRenderer.rootBone = allThings.Find(thing => thing.thingId == 0).transform;
// break;
// }
// }
//}
//else {
// Renderer[] renderers = parentTransform.GetComponentsInChildren<Renderer>();
// foreach (Renderer renderer in renderers) {
// MeshCollider c = renderer.gameObject.AddComponent<MeshCollider>();
// c.convex = true;
// }
// ScanForThings(parentTransform);
//}
}
//private void ReplaceSkinnedBones(SkinnedMeshRenderer meshRenderer) { //private void ReplaceSkinnedBones(SkinnedMeshRenderer meshRenderer) {
// Transform[] bones = meshRenderer.bones; // Transform[] bones = meshRenderer.bones;
// //foreach(Transform bone in bones) { // //foreach(Transform bone in bones) {
@ -780,6 +939,16 @@ namespace Passer.Humanoid {
} }
} }
protected static Vector3 ToVector3(Spherical s) {
Vector3 v = Quaternion.AngleAxis(s.horizontal, Vector3.up) * Quaternion.AngleAxis(s.vertical, Vector3.left) * (Vector3.forward * s.distance);
return v;
}
protected static Quaternion ToQuaternion(Quat32 q32) {
Quaternion q = new(q32.x, q32.y, q32.z, q32.w);
return q;
}
//#endregion Pose //#endregion Pose
//#endregion Messages //#endregion Messages

View File

@ -1,3 +1,4 @@
using System.Collections.Generic;
using UnityEngine; using UnityEngine;
using Passer.Control; using Passer.Control;
@ -6,8 +7,16 @@ public class Thing : MonoBehaviour {
public byte networkId; public byte networkId;
public byte thingId; public byte thingId;
public byte objectType; public byte objectType;
public string modelUrl;
//protected Sensor sensor; //protected Sensor sensor;
public static List<Thing> allThings = new();
public static Thing GetThing(byte networkId, byte thingId) {
Thing thing = allThings.Find(aThing => aThing.networkId == networkId && aThing.thingId == thingId);
return thing;
}
protected virtual void Init() { protected virtual void Init() {
//if (this.objectType == 2) { //if (this.objectType == 2) {
// sensor = this.gameObject.AddComponent<DistanceSensor>(); // sensor = this.gameObject.AddComponent<DistanceSensor>();
@ -15,28 +24,29 @@ public class Thing : MonoBehaviour {
//} //}
} }
public static Thing Create(GameObject obj, Client client, byte objId, byte objType) { public static Thing Create(GameObject obj, Client client, byte networkId, byte objId, byte objType) {
Thing thing = obj.AddComponent<Thing>(); Thing thing = obj.AddComponent<Thing>();
thing.client = client; thing.client = client;
thing.thingId = objId; thing.thingId = objId;
thing.objectType = objType; thing.objectType = objType;
thing.networkId = client.networkId; thing.networkId = networkId;
thing.Init(); thing.Init();
allThings.Add(thing);
return thing; return thing;
} }
public virtual Thing CopyTo(GameObject obj) { public virtual Thing CopyTo(GameObject obj) {
//Debug.Log($"copy {obj}"); //Debug.Log($"copy {obj}");
Thing foundThing = Thing.Create(obj, this.client, this.thingId, this.objectType); Thing foundThing = Thing.Create(obj, this.client, this.networkId, this.thingId, this.objectType);
Destroy(this.gameObject); Destroy(this.gameObject);
return foundThing; return foundThing;
} }
//public void ProcessBytes(byte[] bytes) { public void ProcessBytes(byte[] bytes) {
// if (sensor != null) //if (sensor != null)
// sensor.ProcessBytes(bytes); // sensor.ProcessBytes(bytes);
//} }
//public void Update() { //public void Update() {
// if (objectId == 0) // if (objectId == 0)
// Debug.Log(this.transform.eulerAngles); // Debug.Log(this.transform.eulerAngles);