261 lines
7.0 KiB
C#
261 lines
7.0 KiB
C#
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();
|
|
}
|
|
|
|
ModelViewerMain.RegisterObject(this);
|
|
}
|
|
|
|
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);
|
|
ModelViewerMain.OnObjectDeleteEvent.Invoke(this);
|
|
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 virtual void Destroy()
|
|
{
|
|
Destroy(this.gameObject);
|
|
}
|
|
|
|
public void EnableKeyframeSet()
|
|
{
|
|
_setKeyframe = true;
|
|
}
|
|
|
|
public void DisableKeyframeSet()
|
|
{
|
|
_setKeyframe = false;
|
|
}
|
|
#endregion
|
|
|
|
private void OnApplicationQuit()
|
|
{
|
|
_applicationQuitting = true;
|
|
}
|
|
}
|