void OnBuildGameObject(RpcContext <BuildGameObject> ctx) { var materialCache = new MaterialCache { Materials = ctx.Data.Materials }; var meshCache = new MeshCache { Meshes = ctx.Data.Meshes }; var configs = new SyncObjectImportConfig { settings = new SyncObjectImportSettings { defaultMaterial = ReflectMaterialManager.defaultMaterial, importLights = true }, materialCache = materialCache, meshCache = meshCache }; var gameObject = m_Importer.Import(ctx.Data.InstanceData.SourceId, ctx.Data.Object, configs); gameObject.name = ctx.Data.Instance.Name; gameObject.transform.SetParent(m_Settings.Root); ImportersUtils.SetTransform(gameObject.transform, ctx.Data.Instance.Transform); ImportersUtils.SetMetadata(gameObject, ctx.Data.Instance.Metadata); ctx.SendSuccess(gameObject); }
public void OnStreamEvent(SyncedData <StreamInstanceData> stream, StreamEvent streamEvent) { var objectKey = new StreamKey(stream.key.source, PersistentKey.GetKey <SyncObject>(stream.data.syncObject.Id)); if (streamEvent == StreamEvent.Added) { m_SyncObjects[objectKey] = stream.data.syncObject; var syncObjectBinding = ImportInstance(stream.data.instance); var key = stream.data.instance.key; m_Instances[key] = syncObjectBinding; syncObjectBinding.streamKey = key; m_Output.SendStreamAdded(new SyncedData <GameObject>(key, syncObjectBinding.gameObject)); } else if (streamEvent == StreamEvent.Changed) { var key = stream.data.instance.key; // The instance moved, or the name/metadata changed. var syncObjectBinding = m_Instances[key]; ImportersUtils.SetTransform(syncObjectBinding.transform, stream.data.instance.instance.Transform); ImportersUtils.SetMetadata(syncObjectBinding.gameObject, stream.data.instance.instance.Metadata); syncObjectBinding.gameObject.name = stream.data.instance.instance.Name; m_Output.SendStreamChanged(new SyncedData <GameObject>(key, syncObjectBinding.gameObject)); } else if (streamEvent == StreamEvent.Removed) { var key = stream.data.instance.key; // The instance either moved, or the metadata changed. var syncObjectBinding = m_Instances[key]; m_Instances.Remove(key); m_Output.SendStreamRemoved(new SyncedData <GameObject>(key, syncObjectBinding.gameObject)); if (m_Originals.TryGetValue(objectKey, out var original)) { UntrackDependencies(original.Dependencies); if (original.NbActiveInstances == 1) { m_Originals.Remove(objectKey); } else { --original.NbActiveInstances; m_Originals[objectKey] = original; } } Object.Destroy(syncObjectBinding.gameObject); } }
static void Import(string sourceId, SyncObject syncObject, GameObject gameObject, SyncObjectImportConfig config) { if (syncObject.MeshId != SyncId.None) { var meshKey = StreamKey.FromSyncId <SyncMesh>(sourceId, syncObject.MeshId); var mesh = config.meshCache.GetMesh(meshKey); if (mesh != null) { var meshFilter = gameObject.AddComponent <MeshFilter>(); meshFilter.sharedMesh = mesh; var renderer = gameObject.GetComponent <MeshRenderer>(); if (renderer == null) { renderer = gameObject.AddComponent <MeshRenderer>(); } var materials = new Material[meshFilter.sharedMesh.subMeshCount]; for (int i = 0; i < materials.Length; ++i) { Material material = null; if (i < syncObject.MaterialIds.Count) { var materialId = syncObject.MaterialIds[i]; if (materialId != SyncId.None) { var materialKey = StreamKey.FromSyncId <SyncMaterial>(sourceId, materialId); material = config.materialCache.GetMaterial(materialKey); } } materials[i] = material ? material : config.settings.defaultMaterial; } renderer.sharedMaterials = materials; } } if (config.settings.importLights && syncObject.Light != null) { ImportLight(syncObject.Light, gameObject); } if (syncObject.Rpc != null) { // TODO } if (syncObject.Camera != null) { ImportCamera(syncObject.Camera, gameObject); } if (syncObject.Children != null) { foreach (var child in syncObject.Children) { if (IsEmpty(child, config)) { continue; } var childObject = new GameObject(child.Name); childObject.transform.parent = gameObject.transform; ImportersUtils.SetTransform(childObject.transform, child.Transform); Import(sourceId, child, childObject, config); } } }
static void ImportLight(SyncLight syncLight, GameObject parent) { // Conversion parameters const float defaultIntensity = 1.0f; const double intensityExponent = 0.25; const double intensityMultiplier = 0.2; const float intensityAtRange = 0.02f; // Convert syncLight intensity to unity light intensity var intensity = defaultIntensity; if (syncLight.Intensity > 0) { intensity = ImportersUtils.GetCandelasIntensity(syncLight.Intensity, syncLight.IntensityUnit, syncLight.Type, syncLight.SpotAngle); intensity = (float)(intensityMultiplier * Math.Pow(intensity, intensityExponent)); } // Compute the range if not provided var range = syncLight.Range; if (range <= 0) { range = (float)Math.Sqrt(intensity / intensityAtRange); } // TODO Investigate why Light.UseColorTemperature is not exposed to C# and let the light do this calculation var cct = ImportersUtils.ColorFromTemperature(syncLight.Temperature); var filter = new Color(syncLight.Color.R, syncLight.Color.G, syncLight.Color.B); var light = parent.AddComponent <Light>(); light.color = cct * filter; light.colorTemperature = syncLight.Temperature; switch (syncLight.Type) { case SyncLightType.Spot: { light.spotAngle = syncLight.SpotAngle; light.shadows = LightShadows.Hard; light.range = range; light.type = LightType.Spot; light.intensity = intensity; } break; case SyncLightType.Point: { light.type = LightType.Point; light.range = range; light.intensity = intensity; } break; case SyncLightType.Directional: { light.type = LightType.Directional; light.intensity = intensity; } break; } }