/* 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; } if (layersButtons != null) { foreach (CompoundButton button in layersButtons.Values) { // remove from ButtonsClickReceiver.interactables ButtonsClickReceiver clickReceiver = GetComponent <ButtonsClickReceiver>(); clickReceiver.interactables.Remove(button.gameObject); 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; }
/* 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 Dictionary <ModelLayer, LayerLoaded>(); /* Instantiate BoundingBoxRig dynamically, as in the next frame (when BoundingBoxRig.Start is run) * it will assume that bounding box of children is not empty. * So we cannot create BoundingBoxRig (for rotations) earlier. * We also cannot create it later, right before calling Activate, as then BoundingBoxRig.Activate would * happen before BoundingBoxRig.Start. */ 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; } // 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>() . rotationBoxCollider.enabled = false; // reset animation speed slider to value 1 animationSpeed = 1f; SliderAnimationSpeed.GetComponent <SliderGestureControl>().SetSliderValue(animationSpeed); // reset transparency to false Transparent = false; // add buttons to toggle layers layersButtons = new Dictionary <ModelLayer, CompoundButton>(); int buttonIndex = 0; foreach (ModelLayer layer in instanceBundle.Layers) { // add button to scene GameObject buttonGameObject = Instantiate <GameObject>(ButtonLayerTemplate, LayersSection.transform); buttonGameObject.transform.localPosition = buttonGameObject.transform.localPosition + new Vector3(0f, 0f, buttonLayerHeight * buttonIndex); buttonIndex++; // configure button text CompoundButton button = buttonGameObject.GetComponent <CompoundButton>(); if (button == null) { Debug.LogWarning("Missing component CompoundButton in ButtonLayerTemplate"); continue; } button.GetComponent <CompoundButtonText>().Text = layer.Caption; // extend ButtonsClickReceiver.interactables ButtonsClickReceiver clickReceiver = GetComponent <ButtonsClickReceiver>(); clickReceiver.interactables.Add(buttonGameObject); // update layersButtons dictionary layersButtons[layer] = button; } }