using KF3; using System.Collections; using System.Collections.Generic; using System.Linq; using UnityEngine; public class KF3ModelViewerMain : ModelViewerMain { public float SpecialDistance = 1; public bool IsOnline = true; public static KF3ModelViewerMain Instance => GetInstance(); public KF3ModelViewerInterface UI => ModelViewerInterface.GetInstance(); public KF3AssetLibrary Assets => AssetLibrary.GetInstance(); public KF3ModelBuilder Builder => ModelBuilder.GetInstance(); public AdditionalResources Resources => SharedResources.Instance as AdditionalResources; public AnimationClip OverrideClip; protected override void Awake() { Debug.LogError("Fix this"); Settings.Load(); _backupTimers = _backupTimes.ToArray(); } private IEnumerator Start() { Application.targetFrameRate = 30; Error.Log(Color.green, "Viewer version: " + Application.version); float warningTimer = 0; yield return GetComponent().Init(); while (KF3ModelBuilder.Instance == null || KF3ModelViewerInterface.Instance == null || SharedResources.Instance == null) { warningTimer += Time.deltaTime; if (warningTimer > 2) { warningTimer = 0; string report = $"AssetLibrary: {KF3AssetLibrary.Instance != null}\nModelBuilder: {KF3ModelBuilder.Instance != null}\nInterface: {KF3ModelViewerInterface.Instance != null}\nResources: {SharedResources.Instance != null}"; Error.Log(report, Color.red); } yield return 0; } _mainInstance = this; CurrentScene = SceneContainer.Create(this); KF3ModelViewerInterface.SetDropdownData(GetCurrentScene().Settings.StageDropdown, KF3ModelViewerMain.Instance.Assets.Stages.Select(s => s.DisplayName).ToList(), true); KF3ModelViewerInterface.SetDropdownData(GetCurrentScene().Settings.BackgroundDropdown, KF3ModelViewerMain.Instance.Assets.Skies.Select(s => s.DisplayName).ToList(), true); } private void Update() { AutoSaveUpdate(); } public override void SelectionClear() { base.SelectionClear(); KF3ModelViewerInterface.Instance.SelectionClear(); } public static void DisposeOf(GameObject go) { if (go == null) return; var rends = go.GetComponentsInChildren(); foreach(var rend in rends) { for(int i=rend.materials.Length-1; i>=0; i--) { Destroy(rend.materials[i]); } } Destroy(go); UnityEngine.Resources.UnloadUnusedAssets(); System.GC.Collect(); } public override IEnumerator LoadScene(SceneSerializable bc) { Debug.Log("Emptying scene"); EmptyScene(); foreach (var c in bc.Objects) { Debug.Log($"Loading {c.Filename} {c.GUID} {c.Frames.Count}"); if (c.GUID == "cameraOrbit") { MainCameraOrbit.DeserializeFrames(c); } else { yield return Builder.SpawnSerializedCoroutine(c); } } bc.Timeline.Deserialize(TimelineController.Instance); (CurrentScene as KF3SceneContainer).Frames = (bc as KF3SceneSerializable).Frames.Select(f => new FrameContent(f)).ToList(); yield return 0; TimelineController.SetCurrentFrame(TimelineController.Instance.CurrentFrame); } public static void FocusOn(Camera camera, GameObject focusedObject, float cameraDistance) { Bounds bounds = GetBoundsWithChildren(focusedObject); Vector3 objectSizes = bounds.max - bounds.min; float objectSize = Mathf.Max(objectSizes.x, objectSizes.y, objectSizes.z); float cameraView = 2.0f * Mathf.Tan(0.5f * Mathf.Deg2Rad * Camera.main.fieldOfView); // Visible height 1 meter in front float distance = cameraDistance * objectSize / cameraView; // Combined wanted distance from the object distance += 0.5f * objectSize; // Estimated offset from the center to the outside of the object Camera.main.transform.position = bounds.center - distance * Camera.main.transform.forward; } public static Bounds GetBoundsWithChildren(GameObject gameObject) { Renderer parentRenderer = gameObject.GetComponent(); Renderer[] childrenRenderers = gameObject.GetComponentsInChildren(); Bounds bounds = parentRenderer != null ? parentRenderer.bounds : childrenRenderers.FirstOrDefault(x => x.enabled).bounds; if (childrenRenderers.Length > 0) { foreach (Renderer renderer in childrenRenderers) { if (renderer.enabled) { bounds.Encapsulate(renderer.bounds); } } } return bounds; } }