You've already forked UniversalViewer
Initial files
This commit is contained in:
137
Assets/Scripts/ModelViewerBase/Containers/CameraContainer.cs
Normal file
137
Assets/Scripts/ModelViewerBase/Containers/CameraContainer.cs
Normal file
@@ -0,0 +1,137 @@
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
using System.Linq;
|
||||
|
||||
public class CameraContainer: ObjectContainer
|
||||
{
|
||||
public CameraOrbit Camera;
|
||||
public KeyframeDataCamera LastPosition;
|
||||
public LineRenderer LineRenderer;
|
||||
|
||||
public CameraSettings Settings;
|
||||
|
||||
protected override void Start()
|
||||
{
|
||||
//Set default keyframe in custom ModelViewerMain
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (!LineRenderer.enabled) return;
|
||||
|
||||
float fov = Settings.Fov;
|
||||
float aspect = Camera.Cam.aspect;
|
||||
float nearPlane = Camera.Cam.nearClipPlane;
|
||||
float farPlane = Camera.Cam.farClipPlane;
|
||||
|
||||
Vector3[] far = CalculateCameraFrustRect(fov, aspect, farPlane, transform);
|
||||
Vector3[] near = CalculateCameraFrustRect(fov, aspect, nearPlane, transform);
|
||||
|
||||
var edges = new Vector3[]
|
||||
{
|
||||
far[0], far[1], far[2], far[3], far[0], near[0], near[1], near[2], near[3], near[0], near[1], far[1], far[2], near[2], near[3], far[3]
|
||||
};
|
||||
|
||||
LineRenderer.positionCount = edges.Length;
|
||||
LineRenderer.SetPositions(edges);
|
||||
}
|
||||
|
||||
private static Vector3[] CalculateCameraFrustRect(float fieldOfView, float aspect, float dist, Transform transform)
|
||||
{
|
||||
dist = Mathf.Clamp(dist, 0.1f, 20f);
|
||||
|
||||
Vector3[] rect = new Vector3[4];
|
||||
float frustumHeight = 2.0F * dist * Mathf.Tan(fieldOfView * 0.5F * Mathf.Deg2Rad);
|
||||
rect[0] = transform.TransformPoint(new Vector3(-frustumHeight * aspect / 2, frustumHeight / 2, dist));
|
||||
rect[1] = transform.TransformPoint(new Vector3(frustumHeight * aspect / 2, frustumHeight / 2, dist));
|
||||
rect[2] = transform.TransformPoint(new Vector3(frustumHeight * aspect / 2, -frustumHeight / 2, dist));
|
||||
rect[3] = transform.TransformPoint(new Vector3(-frustumHeight * aspect / 2, -frustumHeight / 2, dist));
|
||||
|
||||
return (rect);
|
||||
}
|
||||
|
||||
Vector3 TransformPoint(Vector3 transforPos, Quaternion transformRotation, Vector3 transformScale, Vector3 pos)
|
||||
{
|
||||
Matrix4x4 matrix = Matrix4x4.TRS(transforPos, transformRotation, transformScale);
|
||||
return matrix.MultiplyPoint3x4(pos);
|
||||
}
|
||||
|
||||
Vector3 InverseTransformPoint(Vector3 transforPos, Quaternion transformRotation, Vector3 transformScale, Vector3 pos)
|
||||
{
|
||||
Matrix4x4 matrix = Matrix4x4.TRS(transforPos, transformRotation, transformScale);
|
||||
Matrix4x4 inverse = matrix.inverse;
|
||||
return inverse.MultiplyPoint3x4(pos);
|
||||
}
|
||||
|
||||
public override ObjectContainerSerializable Serialize()
|
||||
{
|
||||
var serialized = new CameraContainerSerializable(this);
|
||||
return serialized;
|
||||
}
|
||||
|
||||
public override KeyframeData SerializeFrame()
|
||||
{
|
||||
return new KeyframeDataCamera(this);
|
||||
}
|
||||
|
||||
public override void Deserialize(ObjectContainerSerializable serialized)
|
||||
{
|
||||
DeserializeFrames(serialized);
|
||||
}
|
||||
|
||||
public override void Lerp(KeyframeData frame1, KeyframeData frame2, float amount)
|
||||
{
|
||||
var tsf = frame1 as KeyframeDataCamera;
|
||||
|
||||
if (frame1 != frame2)
|
||||
{
|
||||
tsf = tsf.Lerp(frame2, amount) as KeyframeDataCamera;
|
||||
}
|
||||
|
||||
var orbitLocator = ModelViewerMain.GetInstance().MainCameraOrbit;
|
||||
|
||||
if (ModelViewerMain.GetInstance().GetCameraHandler() == ModelViewerMain.GetInstance().WorkCameraOrbit)
|
||||
{
|
||||
//if in work camera mode, move the camera locator only
|
||||
orbitLocator.transform.position = tsf.Root.Position;
|
||||
orbitLocator.transform.eulerAngles = tsf.Root.Rotation;
|
||||
orbitLocator.LastPosition = tsf;
|
||||
}
|
||||
else
|
||||
{
|
||||
orbitLocator.PastePose(tsf, new PoseLoadOptions(true));
|
||||
}
|
||||
}
|
||||
|
||||
public override void Select()
|
||||
{
|
||||
}
|
||||
|
||||
public override void Deselect()
|
||||
{
|
||||
}
|
||||
|
||||
public override void PastePose(KeyframeData frame, PoseLoadOptions pasteParams = null)
|
||||
{
|
||||
var keyframe = frame as KeyframeDataCamera;
|
||||
Camera.transform.localPosition = keyframe.Root.Position;
|
||||
Camera.transform.localEulerAngles = keyframe.Root.Rotation;
|
||||
Camera.lookRotation = keyframe.Root.Rotation;
|
||||
//if (Camera.lookRotation.x > 90) Camera.lookRotation.x -= 360;
|
||||
//if (Camera.lookRotation.x < -90) Camera.lookRotation.x += 360;
|
||||
//lookRotation.x = lookRotation.x - 360;
|
||||
|
||||
using (new KeyframeToggleContext(this))
|
||||
{
|
||||
Settings.DropdownCameraMode.value = keyframe.CameraMode;
|
||||
//Settings.ToggleCameraLock.isOn = keyframe.CameraLock;
|
||||
Settings.SliderFov.value = keyframe.Fov;
|
||||
Settings.SliderCamDist.value = keyframe.CamDist;
|
||||
Settings.SliderCamHeight.value = keyframe.CamHeight;
|
||||
Settings.SliderTargetHeight.value = keyframe.TargetHeigh;
|
||||
Settings.SliderCamAngle.value = keyframe.CamAngle;
|
||||
}
|
||||
|
||||
Camera.UpdateImmediate();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 72e8d74079817324498115876d689669
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,14 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
[Serializable]
|
||||
public class CameraContainerSerializable : ObjectContainerSerializable
|
||||
{
|
||||
public CameraContainerSerializable() { }
|
||||
|
||||
public CameraContainerSerializable(CameraContainer container)
|
||||
{
|
||||
GUID = "cameraOrbit";
|
||||
Frames = container.Frames.Select(f => new FrameContent(f)).ToList();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5a1693bb5411564489cd61fa721c0fd0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
257
Assets/Scripts/ModelViewerBase/Containers/ObjectContainer.cs
Normal file
257
Assets/Scripts/ModelViewerBase/Containers/ObjectContainer.cs
Normal file
@@ -0,0 +1,257 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using Newtonsoft.Json;
|
||||
using System.Collections.Generic;
|
||||
|
||||
public class ObjectContainer : MonoBehaviour, IKeyframeSetter
|
||||
{
|
||||
[JsonIgnore] public bool DoNotSave;
|
||||
public int ModelId;
|
||||
public string GUID = "";
|
||||
public bool LoadInProgress = false;
|
||||
|
||||
public List<UIHandle> Handles = new List<UIHandle>();
|
||||
public List<Renderer> Renderers = new List<Renderer>();
|
||||
public Dictionary<SkinnedMeshRenderer, List<MorphHelper>> Morphs = new Dictionary<SkinnedMeshRenderer, List<MorphHelper>>();
|
||||
public List<FrameContent> Frames = new List<FrameContent>();
|
||||
public List<GameObject> InstantiatedObjects = new List<GameObject>();
|
||||
protected bool _setKeyframe = true;
|
||||
protected bool _applicationQuitting = false;
|
||||
|
||||
public void Awake()
|
||||
{
|
||||
if (GUID == "")
|
||||
GUID = System.Guid.NewGuid().ToString();
|
||||
}
|
||||
|
||||
public static T Create<T>(string name = "Container") where T : ObjectContainer
|
||||
{
|
||||
var container = new GameObject(name).AddComponent<T>();
|
||||
return container;
|
||||
}
|
||||
|
||||
protected virtual void Start()
|
||||
{
|
||||
if (ModelViewerMain.GetInstance() == null) return;
|
||||
if (DoNotSave) return;
|
||||
|
||||
if (Frames.Count == 0)
|
||||
{
|
||||
SetKeyframe();
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void PasteContainer(ObjectContainerSerializable bones, PoseLoadOptions pasteParams)
|
||||
{
|
||||
GUID = bones.GUID;
|
||||
}
|
||||
|
||||
public virtual Vector3 GetCenter() { return transform.position; }
|
||||
|
||||
public void ToggleVisible(GameObject go, bool value)
|
||||
{
|
||||
go.SetActive(value);
|
||||
}
|
||||
|
||||
public void ToggleRendererVisible(Renderer r, bool value)
|
||||
{
|
||||
r.enabled = value;
|
||||
}
|
||||
|
||||
public virtual ObjectContainerSerializable Serialize()
|
||||
{
|
||||
return new ObjectContainerSerializable(this);
|
||||
}
|
||||
|
||||
public virtual KeyframeData SerializeFrame()
|
||||
{
|
||||
return new KeyframeData(this);
|
||||
}
|
||||
|
||||
public virtual void Deserialize(ObjectContainerSerializable serialized)
|
||||
{
|
||||
throw new NotImplementedException(GetType().FullName);
|
||||
}
|
||||
|
||||
protected virtual void OnDestroy()
|
||||
{
|
||||
if (_applicationQuitting) return;
|
||||
|
||||
foreach (var rend in Renderers)
|
||||
{
|
||||
for (int i = rend.sharedMaterials.Length - 1; i >= 0; i--)
|
||||
{
|
||||
Destroy(rend.sharedMaterials[i]);
|
||||
}
|
||||
}
|
||||
foreach (var obj in InstantiatedObjects)
|
||||
{
|
||||
Destroy(obj);
|
||||
}
|
||||
ModelViewerMain.UnregisterObject(this);
|
||||
if (gameObject != null)
|
||||
Destroy(gameObject);
|
||||
Resources.UnloadUnusedAssets();
|
||||
System.GC.Collect();
|
||||
}
|
||||
|
||||
#region Timeline
|
||||
public virtual DataType GetDataType()
|
||||
{
|
||||
switch (this)
|
||||
{
|
||||
case SceneContainer _:
|
||||
return DataType.Scene;
|
||||
case CameraContainer _:
|
||||
return DataType.Camera;
|
||||
default:
|
||||
return DataType.Character;
|
||||
}
|
||||
}
|
||||
|
||||
public FrameContent TryGetFrame(int frameNum)
|
||||
{
|
||||
return Frames.FirstOrDefault(f => f.FrameNum == frameNum);
|
||||
}
|
||||
|
||||
public void GetClosestFrames(int frame, out FrameContent previousFrame, out FrameContent nextFrame)
|
||||
{
|
||||
previousFrame = null;
|
||||
nextFrame = null;
|
||||
|
||||
var frames = Frames.OrderBy(f => f.FrameNum).ToArray();
|
||||
|
||||
for (int i = 0; i < Frames.Count; i++)
|
||||
{
|
||||
if (Frames[i].FrameNum < frame)
|
||||
{
|
||||
previousFrame = nextFrame = frames[i];
|
||||
}
|
||||
else if (Frames[i].FrameNum == frame)
|
||||
{
|
||||
previousFrame = nextFrame = frames[i];
|
||||
break;
|
||||
}
|
||||
else if (Frames[i].FrameNum > frame)
|
||||
{
|
||||
if (previousFrame == null) previousFrame = frames[i];
|
||||
nextFrame = frames[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> Returns true if frame existed or false if it was created </summary>
|
||||
public bool GetCurrentFrame(int frame, out FrameContent currentFrame)
|
||||
{
|
||||
GetClosestFrames(frame, out var previousFrame, out var nextFrame);
|
||||
|
||||
if (previousFrame.FrameNum == frame)
|
||||
{
|
||||
currentFrame = previousFrame;
|
||||
return true;
|
||||
}
|
||||
else if (nextFrame.FrameNum == frame)
|
||||
{
|
||||
currentFrame = nextFrame;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
currentFrame = new FrameContent(frame);
|
||||
Frames.Add(currentFrame);
|
||||
Frames = Frames.OrderBy(f => f.FrameNum).ToList();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void SetKeyframe(int frameNum = -1)
|
||||
{
|
||||
if (DoNotSave || !_setKeyframe) return;
|
||||
Debug.Log("Setting frame for " + name);
|
||||
//if (Frames.Count == 0) SetDefaultFrame();
|
||||
if (frameNum == -1) frameNum = TimelineController.Instance.CurrentFrame;
|
||||
|
||||
GetClosestFrames(frameNum, out var previousFrame, out var nextFrame);
|
||||
|
||||
FrameContent currentFrame = null;
|
||||
if (previousFrame == null || previousFrame.FrameNum != frameNum)
|
||||
{
|
||||
currentFrame = new FrameContent(frameNum);
|
||||
Frames.Add(currentFrame);
|
||||
Frames = Frames.OrderBy(f => f.FrameNum).ToList();
|
||||
}
|
||||
else if (previousFrame.FrameNum == frameNum) currentFrame = previousFrame;
|
||||
else if (nextFrame.FrameNum == frameNum) currentFrame = nextFrame;
|
||||
|
||||
currentFrame.SetObjectData(SerializeFrame());
|
||||
|
||||
TimelineController.UpdateTimeline();
|
||||
}
|
||||
|
||||
public void SetDefaultFrame()
|
||||
{
|
||||
Frames = new List<FrameContent>()
|
||||
{
|
||||
new FrameContent(0).SetObjectData(SerializeFrame())
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public virtual void DeserializeFrames(ObjectContainerSerializable serialized)
|
||||
{
|
||||
Frames = serialized.Frames.Select(f => new FrameContent(f)).ToList();
|
||||
}
|
||||
|
||||
public virtual void Lerp(KeyframeData frame1, KeyframeData frame2, float amount)
|
||||
{
|
||||
if (frame1 == frame2)
|
||||
{
|
||||
PastePose(frame1, new PoseLoadOptions(true));
|
||||
}
|
||||
else
|
||||
{
|
||||
PastePose(frame1.Lerp(frame2, amount), new PoseLoadOptions(true));
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void PastePose(KeyframeData frame, PoseLoadOptions pasteParams)
|
||||
{
|
||||
if (pasteParams.Root)
|
||||
{
|
||||
transform.SetTransform(frame.Root);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Deselect()
|
||||
{
|
||||
throw new NotImplementedException(this.GetType().FullName);
|
||||
}
|
||||
|
||||
public virtual void Select()
|
||||
{
|
||||
throw new NotImplementedException(this.GetType().FullName);
|
||||
}
|
||||
|
||||
public void Destroy()
|
||||
{
|
||||
Destroy(this.gameObject);
|
||||
}
|
||||
|
||||
public void EnableKeyframeSet()
|
||||
{
|
||||
_setKeyframe = true;
|
||||
}
|
||||
|
||||
public void DisableKeyframeSet()
|
||||
{
|
||||
_setKeyframe = false;
|
||||
}
|
||||
#endregion
|
||||
|
||||
private void OnApplicationQuit()
|
||||
{
|
||||
_applicationQuitting = true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2bf6dfe0e5776cd49b8f8923c18704da
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,26 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
[System.Serializable]
|
||||
public class ObjectContainerSerializable
|
||||
{
|
||||
public string Filename;
|
||||
public string GUID;
|
||||
public List<FrameContent> Frames;
|
||||
|
||||
public ObjectContainerSerializable() { }
|
||||
|
||||
public ObjectContainerSerializable(ObjectContainer containerBase)
|
||||
{
|
||||
this.Filename = containerBase.name;
|
||||
this.GUID = containerBase.GUID;
|
||||
this.Frames = containerBase.Frames.Select(frame => new FrameContent(frame)).ToList();
|
||||
}
|
||||
|
||||
public ObjectContainerSerializable(ObjectContainerSerializable source)
|
||||
{
|
||||
this.Filename = source.Filename;
|
||||
this.GUID = source.GUID;
|
||||
this.Frames = source.Frames.Select(frame => new FrameContent(frame)).ToList();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 85c39ae818417104eb7ae9174bd0f708
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
37
Assets/Scripts/ModelViewerBase/Containers/SceneContainer.cs
Normal file
37
Assets/Scripts/ModelViewerBase/Containers/SceneContainer.cs
Normal file
@@ -0,0 +1,37 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
public class SceneContainer : ObjectContainer
|
||||
{
|
||||
public CameraContainer MainCameraOrbit;
|
||||
public CameraContainer WorkCameraOrbit;
|
||||
|
||||
public List<ObjectContainer> AllObjects = new List<ObjectContainer>();
|
||||
|
||||
public List<T> Objects<T>() where T : ObjectContainer
|
||||
{
|
||||
return AllObjects.Cast<T>().ToList();
|
||||
}
|
||||
|
||||
public static SceneContainer Create<T>(ModelViewerMain main) where T : SceneContainer
|
||||
{
|
||||
var container = new GameObject("Scene").AddComponent<T>();
|
||||
container.Init(main);
|
||||
return container;
|
||||
}
|
||||
|
||||
public virtual void Init(ModelViewerMain main)
|
||||
{
|
||||
GUID = "scene";
|
||||
MainCameraOrbit = main.MainCameraOrbit;
|
||||
WorkCameraOrbit = main.WorkCameraOrbit;
|
||||
SetDefaultFrame();
|
||||
AllObjects.Add(MainCameraOrbit);
|
||||
}
|
||||
|
||||
public override ObjectContainerSerializable Serialize()
|
||||
{
|
||||
return new SceneSerializable(this);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 520e0b69d9f17e2488c1eb19d9a50940
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,29 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
[Serializable]
|
||||
public class SceneSerializable : ObjectContainerSerializable
|
||||
{
|
||||
public string Version;
|
||||
public string Date;
|
||||
public TimelineControllerSerializable Timeline;
|
||||
public List<ObjectContainerSerializable> Objects = new List<ObjectContainerSerializable>();
|
||||
|
||||
public SceneSerializable() { }
|
||||
|
||||
public SceneSerializable(SceneContainer scene)
|
||||
{
|
||||
this.Version = Application.version;
|
||||
this.Date = DateTime.Now.ToString("yyyy-MM-dd HH:mm", CultureInfo.InvariantCulture); ;
|
||||
this.Timeline = new TimelineControllerSerializable(TimelineController.Instance);
|
||||
this.Frames = scene.Frames.Select(f => new FrameContent(f)).ToList();
|
||||
foreach (var obj in scene.AllObjects)
|
||||
{
|
||||
if (obj != scene)
|
||||
Objects.Add(obj.Serialize());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7592143342b8b0741831e85e6a2f88b1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user