/* Unload currently loaded model. * May be safely called even when instance is already unloaded. * LoadInstance() calls this automatically at the beginning. * * After calling this, remember to call RefreshUserInterface at some point. */ private void UnloadInstance() { if (layersLoaded != null) { foreach (LayerLoaded l in layersLoaded.Values) { Destroy(l.Instance); } layersLoaded = null; ColorMap.LayersLoaded = null; } if (layersButtons != null) { foreach (PressableButtonHoloLens2 button in layersButtons.Values) { // remove from ButtonsClickReceiver.interactables button.GetComponent <Interactable>().IsEnabled = false; Destroy(button.gameObject); } layersButtons = null; } if (instanceTransformation != null) { Destroy(instanceTransformation); Destroy(rotationBoxRig); instanceBundle = null; instanceTransformation = null; rotationBoxRig = null; instanceIsPreview = false; // value does not matter, but for security better to set it to something well-defined } InstanceLoaded = false; directionalIndicator.DirectionalTarget = InstanceParent; }
/* Load new model. * * newInstanceBundleName is a bundle name known to the ModelsCollection bundle. * * No layer is initially loaded -- you usually want to call * LoadLayer immediately after this. * * After calling this, remember to call RefreshUserInterface at some point. */ private void LoadInstance(string newInstanceBundleName, bool newIsPreview) { if (instanceBundle != null) { Debug.Log("LoadInstance - currentInstanceName: " + instanceBundle.Name + ", newInstanceName: " + newInstanceBundleName); if (instanceIsPreview != newIsPreview && instanceBundle.Layers.All(l => l.DataType == DataType.Volumetric)) { Debug.Log("LoadInstance - preview accepted!"); instanceIsPreview = newIsPreview; return; } } UnloadInstance(); InstanceLoaded = true; instanceBundle = ModelsCollection.Singleton.BundleLoad(newInstanceBundleName); // Load Volumetric Data if (instanceBundle.Layers.All(x => x.GetComponent <ModelLayer>().DataType == DataType.Volumetric)) { instanceBundle.VolumetricMaterial = DefaultVolumetricMaterial; instanceBundle.LoadVolumetricData(); } instanceIsPreview = newIsPreview; layersLoaded = new LayersLoaded(); ColorMap.LayersLoaded = layersLoaded; rotationBoxRig = Instantiate <GameObject>(RotationBoxRigTemplate, InstanceParent.transform); instanceTransformation = new GameObject("InstanceTransformation"); instanceTransformation.transform.parent = rotationBoxRig.transform; Vector3 boundsSize = Vector3.one; float scale = 1f; if (instanceBundle.Bounds.HasValue) { Bounds b = instanceBundle.Bounds.Value; boundsSize = b.size; float maxSize = Mathf.Max(new float[] { boundsSize.x, boundsSize.y, boundsSize.z }); if (maxSize > Mathf.Epsilon) { scale = instanceMaxSize / maxSize; } instanceTransformation.transform.localScale = new Vector3(scale, scale, scale); instanceTransformation.transform.localPosition = -b.center * scale + instanceMove; //FIXME: this is a hack on instance not rotating properly if we move plate instanceTransformation.transform.localRotation = new Quaternion(0f, 0f, 0f, 0f); } // set proper BoxCollider bounds BoxCollider rotationBoxCollider = rotationBoxRig.GetComponent <BoxCollider>(); rotationBoxCollider.center = instanceMove; rotationBoxCollider.size = boundsSize * scale; // Disable the component, to not prevent mouse clicking on buttons. // It will be taken into account to calculate bbox in BoundingBoxRig anyway, // since inside BoundingBox.GetColliderBoundsPoints it looks at all GetComponentsInChildren<Collider>() . // reset animation speed slider to value 1 animationSpeed = 1f; SliderAnimationSpeed.GetComponent <PinchSlider>().SliderValue = animationSpeed / SliderSpeedFactor; // reset transparency to false Transparent = false; // add buttons to toggle layers layersButtons = new Dictionary <ModelLayer, PressableButtonHoloLens2>(); int buttonIndex = 0; foreach (ModelLayer layer in instanceBundle.Layers) { // add button to scene GameObject buttonGameObject = Instantiate <GameObject>(ButtonLayerTemplate, LayerSubmenu.transform); buttonGameObject.transform.localPosition = buttonGameObject.transform.localPosition + new Vector3(0f, 0f, buttonLayerHeight * buttonIndex); buttonIndex++; // configure button text PressableButtonHoloLens2 button = buttonGameObject.GetComponent <PressableButtonHoloLens2>(); if (button == null) { Debug.LogWarning("Missing component PressableButtonHoloLens2 in ButtonLayerTemplate"); continue; } button.GetComponent <ButtonConfigHelper>().MainLabelText = layer.Caption; button.GetComponent <Interactable>().OnClick.AddListener(() => Click(buttonGameObject)); // update layersButtons dictionary layersButtons[layer] = button; } directionalIndicator.DirectionalTarget = instanceTransformation.transform; }