mirror of
https://gitgud.io/AbstractConcept/rimworld-animation-studio.git
synced 2024-08-15 00:43:27 +00:00
Multi-drag and stretching for keyframes
This commit is contained in:
parent
f449a9b4e2
commit
ab5a2a4c02
151 changed files with 195 additions and 85 deletions
Binary file not shown.
|
@ -242,6 +242,8 @@ MonoBehaviour:
|
||||||
maxGhosts: 50
|
maxGhosts: 50
|
||||||
actorID: 0
|
actorID: 0
|
||||||
keyframeID: 0
|
keyframeID: 0
|
||||||
|
linkedSlider: {fileID: 0}
|
||||||
|
linkedOffset: 0
|
||||||
--- !u!1 &8359461402257861397
|
--- !u!1 &8359461402257861397
|
||||||
GameObject:
|
GameObject:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
|
|
|
@ -8316,7 +8316,7 @@ MonoBehaviour:
|
||||||
actorCard: {fileID: 3804747680621674853}
|
actorCard: {fileID: 3804747680621674853}
|
||||||
animationTimelines: {fileID: 1100016168}
|
animationTimelines: {fileID: 1100016168}
|
||||||
actorBodies: {fileID: 1828035561}
|
actorBodies: {fileID: 1828035561}
|
||||||
stretchkeyframesToggle: {fileID: 462332576}
|
stretchKeyframesToggle: {fileID: 462332576}
|
||||||
playBackSpeedField: {fileID: 1579799916}
|
playBackSpeedField: {fileID: 1579799916}
|
||||||
playToggleButton: {fileID: 79733375}
|
playToggleButton: {fileID: 79733375}
|
||||||
actorBodyPrefab: {fileID: -4411442180840688308, guid: dc4c8b005322f3b46a2f122a55f38db2,
|
actorBodyPrefab: {fileID: -4411442180840688308, guid: dc4c8b005322f3b46a2f122a55f38db2,
|
||||||
|
@ -17458,7 +17458,7 @@ MonoBehaviour:
|
||||||
m_TargetGraphic: {fileID: 922060210}
|
m_TargetGraphic: {fileID: 922060210}
|
||||||
m_HandleRect: {fileID: 922060209}
|
m_HandleRect: {fileID: 922060209}
|
||||||
m_Direction: 2
|
m_Direction: 2
|
||||||
m_Value: 1
|
m_Value: 0
|
||||||
m_Size: 1
|
m_Size: 1
|
||||||
m_NumberOfSteps: 0
|
m_NumberOfSteps: 0
|
||||||
m_OnValueChanged:
|
m_OnValueChanged:
|
||||||
|
|
|
@ -34,15 +34,14 @@ namespace RimWorldAnimationStudio
|
||||||
HeadBob.Clear();
|
HeadBob.Clear();
|
||||||
GenitalAngle.Clear();
|
GenitalAngle.Clear();
|
||||||
|
|
||||||
|
int keyframePosition = 0;
|
||||||
int duration = 0;
|
int duration = 0;
|
||||||
|
|
||||||
|
keyframes[keyframes.Count - 1].tickDuration = 1;
|
||||||
|
|
||||||
foreach (PawnKeyframe frame in keyframes)
|
foreach (PawnKeyframe frame in keyframes)
|
||||||
{ duration += frame.tickDuration; }
|
{ duration += frame.tickDuration; }
|
||||||
|
|
||||||
int keyframePosition = 0;
|
|
||||||
|
|
||||||
keyframes[keyframes.Count - 1].tickDuration = 1;
|
|
||||||
|
|
||||||
for (int i = 0; i < keyframes.Count; i++)
|
for (int i = 0; i < keyframes.Count; i++)
|
||||||
{
|
{
|
||||||
PawnKeyframe keyframe = keyframes[i];
|
PawnKeyframe keyframe = keyframes[i];
|
||||||
|
@ -82,7 +81,7 @@ namespace RimWorldAnimationStudio
|
||||||
quiver.Add(keyframePosition + keyframe.tickDuration - 1, false);
|
quiver.Add(keyframePosition + keyframe.tickDuration - 1, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
keyframe.atTick = keyframePosition + 1;
|
keyframe.atTick = keyframePosition + Constants.minTick;
|
||||||
keyframePosition += keyframe.tickDuration;
|
keyframePosition += keyframe.tickDuration;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ using System.Linq;
|
||||||
using System.Xml;
|
using System.Xml;
|
||||||
using System.Xml.Serialization;
|
using System.Xml.Serialization;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
using UnityEngine.UI;
|
||||||
|
|
||||||
namespace RimWorldAnimationStudio
|
namespace RimWorldAnimationStudio
|
||||||
{
|
{
|
||||||
|
@ -45,5 +46,10 @@ namespace RimWorldAnimationStudio
|
||||||
|
|
||||||
public bool HasValidKeyframeID()
|
public bool HasValidKeyframeID()
|
||||||
{ return keyframeID >= 100000 && keyframeID < 1000000; }
|
{ return keyframeID >= 100000 && keyframeID < 1000000; }
|
||||||
|
|
||||||
|
public KeyframeSlider GetKeyframeSlider()
|
||||||
|
{
|
||||||
|
return Selectable.allSelectablesArray.FirstOrDefault(x => x.GetComponent<KeyframeSlider>()?.keyframeID == keyframeID)?.GetComponent< KeyframeSlider>();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,13 @@ namespace RimWorldAnimationStudio
|
||||||
|
|
||||||
private PawnAnimationClip clip;
|
private PawnAnimationClip clip;
|
||||||
private PawnKeyframe keyframe;
|
private PawnKeyframe keyframe;
|
||||||
|
|
||||||
private float dragTimeStart = -1f;
|
private float dragTimeStart = -1f;
|
||||||
|
private int dragTickStart = -1;
|
||||||
|
|
||||||
|
public KeyframeSlider linkedSlider;
|
||||||
|
public Keyframe pivotKeyframe;
|
||||||
|
public int linkedOffset;
|
||||||
|
|
||||||
public void Initialize(AnimationTimeline timeline, int actorID, int keyframeID)
|
public void Initialize(AnimationTimeline timeline, int actorID, int keyframeID)
|
||||||
{
|
{
|
||||||
|
@ -48,8 +54,6 @@ namespace RimWorldAnimationStudio
|
||||||
keyframe.atTick = (int)value;
|
keyframe.atTick = (int)value;
|
||||||
clip.BuildSimpleCurves();
|
clip.BuildSimpleCurves();
|
||||||
|
|
||||||
//AnimationController.Instance.stageTick = keyframe.atTick.Value;
|
|
||||||
|
|
||||||
timeline.InitiateUpdateOfGhostFrames();
|
timeline.InitiateUpdateOfGhostFrames();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,52 +103,76 @@ namespace RimWorldAnimationStudio
|
||||||
if (Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.LeftCommand))
|
if (Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.LeftCommand))
|
||||||
{ Workspace.keyframeID.Add(keyframeID); }
|
{ Workspace.keyframeID.Add(keyframeID); }
|
||||||
|
|
||||||
else
|
else if (Workspace.keyframeID.NullOrEmpty() || Workspace.keyframeID.Contains(keyframeID) == false)
|
||||||
{ Workspace.keyframeID = new List<int> { keyframeID }; }
|
{ Workspace.keyframeID = new List<int> { keyframeID }; }
|
||||||
|
|
||||||
if (eventData.clickCount >= 2)
|
if (eventData.clickCount >= 2)
|
||||||
{ AnimationController.Instance.stageTick = keyframe.atTick.Value; }
|
{ AnimationController.Instance.stageTick = keyframe.atTick.Value; }
|
||||||
|
|
||||||
//Workspace.Instance.RecordEvent("Keyframe selected");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnBeginDrag(PointerEventData eventData)
|
public void OnBeginDrag(PointerEventData eventData)
|
||||||
{
|
{
|
||||||
//AnimationController.Instance.stageTick = keyframe.atTick.Value;
|
|
||||||
Workspace.actorID = actorID;
|
Workspace.actorID = actorID;
|
||||||
|
|
||||||
Workspace.keyframeID = new List<int> { keyframeID };
|
|
||||||
|
|
||||||
dragTimeStart = Time.unscaledTime;
|
dragTimeStart = Time.unscaledTime;
|
||||||
|
dragTickStart = keyframe.atTick.Value;
|
||||||
|
|
||||||
|
if (Workspace.keyframeID.NullOrEmpty() || Workspace.keyframeID.Contains(keyframeID) == false)
|
||||||
|
{ Workspace.keyframeID = new List<int> { keyframeID }; }
|
||||||
|
|
||||||
|
List<PawnKeyframe> selectedKeyframes = Workspace.Instance.GetPawnKeyframes(Workspace.keyframeID).Except(new List<PawnKeyframe>() { keyframe })?.ToList();
|
||||||
|
|
||||||
|
// Link other slected keyframes to the movement of this one
|
||||||
|
if (selectedKeyframes.NotNullOrEmpty())
|
||||||
|
{
|
||||||
|
foreach (PawnKeyframe selectedKeyframe in selectedKeyframes)
|
||||||
|
{
|
||||||
|
KeyframeSlider unlinkedSlider = selectedKeyframe.GetKeyframeSlider();
|
||||||
|
|
||||||
|
if (unlinkedSlider != null)
|
||||||
|
{
|
||||||
|
unlinkedSlider.linkedSlider = this;
|
||||||
|
unlinkedSlider.linkedOffset = unlinkedSlider.keyframe.atTick.Value - keyframe.atTick.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pivotKeyframe = keyframe.atTick < selectedKeyframes[0].atTick ? selectedKeyframes.Last() : selectedKeyframes.First();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnDrag(PointerEventData eventData)
|
public override void OnDrag(PointerEventData eventData)
|
||||||
{
|
{
|
||||||
if (keyframe.atTick == 1)
|
Workspace.actorID = actorID;
|
||||||
{ value = 1; return; }
|
|
||||||
|
|
||||||
|
// The first keyframe can't be moved
|
||||||
|
if (keyframe.atTick == Constants.minTick)
|
||||||
|
{ value = Constants.minTick; return; }
|
||||||
|
|
||||||
|
// Sticky drag
|
||||||
if (Time.unscaledTime - dragTimeStart < 0.05f) return;
|
if (Time.unscaledTime - dragTimeStart < 0.05f) return;
|
||||||
|
|
||||||
interactable = true;
|
interactable = true;
|
||||||
base.OnDrag(eventData);
|
base.OnDrag(eventData);
|
||||||
|
|
||||||
|
// Snap to nearest keyframe (on another timeline)
|
||||||
int targetTick = Workspace.FindClosestKeyFrameAtTick(keyframe.atTick.Value, Mathf.CeilToInt(Workspace.StageWindowSize * 0.01f), actorID);
|
int targetTick = Workspace.FindClosestKeyFrameAtTick(keyframe.atTick.Value, Mathf.CeilToInt(Workspace.StageWindowSize * 0.01f), actorID);
|
||||||
|
|
||||||
if (Input.GetKey(KeyCode.LeftShift) && Workspace.Instance.DoesPawnKeyframeExistAtTick(Workspace.stageID, actorID, targetTick) == false)
|
if (Input.GetKey(KeyCode.LeftShift) && Workspace.Instance.DoesPawnKeyframeExistAtTick(Workspace.stageID, actorID, targetTick) == false)
|
||||||
{ value = (float)targetTick; }
|
{ value = (float)targetTick; }
|
||||||
|
|
||||||
// Prevent frames from being moved to tick 1
|
// Prevent other frames from being moved to the first keyframe
|
||||||
if (value == 1)
|
if (value == Constants.minTick)
|
||||||
{ value = 2; }
|
{ value = Constants.minTick + 1; }
|
||||||
|
|
||||||
//AnimationController.Instance.stageTick = keyframe.atTick.Value;
|
|
||||||
Workspace.actorID = actorID;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnEndDrag(PointerEventData eventData)
|
public void OnEndDrag(PointerEventData eventData)
|
||||||
{
|
{
|
||||||
if (keyframe.atTick == 1)
|
if (keyframe.atTick == Constants.minTick)
|
||||||
{ value = 1; return; }
|
{ value = Constants.minTick; return; }
|
||||||
|
|
||||||
|
foreach (Selectable otherSlider in Selectable.allSelectablesArray)
|
||||||
|
{
|
||||||
|
if (otherSlider is KeyframeSlider)
|
||||||
|
{ Debug.Log("unlinked keyframes"); (otherSlider as KeyframeSlider).linkedSlider = null; }
|
||||||
|
}
|
||||||
|
|
||||||
interactable = false;
|
interactable = false;
|
||||||
Workspace.Instance.RecordEvent("Keyframe move");
|
Workspace.Instance.RecordEvent("Keyframe move");
|
||||||
|
@ -154,25 +182,60 @@ namespace RimWorldAnimationStudio
|
||||||
{
|
{
|
||||||
base.Update();
|
base.Update();
|
||||||
|
|
||||||
|
// Update outdated values
|
||||||
|
if (Workspace.keyframeID.NullOrEmpty() || Workspace.keyframeID.Contains(keyframeID) == false)
|
||||||
|
{ linkedSlider = null; }
|
||||||
|
|
||||||
|
else if (AnimationController.Instance.stretchKeyframesToggle.isOn && linkedSlider != null && linkedSlider.IsPivotKeyframe(keyframe) == false)
|
||||||
|
{
|
||||||
|
//int minTick = linkedSlider.pivotKeyframe.atTick.Value + GetIndexAmongstSelectedKeyframes();
|
||||||
|
//value = Mathf.Clamp(Mathf.CeilToInt(linkedSlider.keyframe.atTick.Value + linkedOffset * linkedSlider.ScaledOffsetFromPivot()), minTick, Workspace.StageWindowSize);
|
||||||
|
value = Mathf.CeilToInt(linkedSlider.keyframe.atTick.Value + linkedOffset * linkedSlider.ScaledOffsetFromPivot());
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (AnimationController.Instance.stretchKeyframesToggle.isOn == false && linkedSlider != null)
|
||||||
|
{ value = Mathf.Clamp(linkedSlider.keyframe.atTick.Value + linkedOffset, Constants.minTick + 1, Workspace.StageWindowSize); }
|
||||||
|
|
||||||
|
else if (keyframe.atTick.Value != value)
|
||||||
|
{ value = keyframe.atTick.Value; }
|
||||||
|
|
||||||
|
// Update key color
|
||||||
if (keyframe.atTick.HasValue && Workspace.keyframeID.Contains(keyframeID) && AnimationController.Instance.stageTick == keyframe.atTick.Value)
|
if (keyframe.atTick.HasValue && Workspace.keyframeID.Contains(keyframeID) && AnimationController.Instance.stageTick == keyframe.atTick.Value)
|
||||||
{ handleImage.color = Constants.ColorPurple; }
|
{ handleImage.color = Constants.ColorPurple; }
|
||||||
|
|
||||||
else if (Workspace.keyframeID.Contains(keyframeID))
|
else if (Workspace.keyframeID.Contains(keyframeID))
|
||||||
{ handleImage.color = Constants.ColorCyan; }
|
{ handleImage.color = Constants.ColorCyan; }
|
||||||
|
|
||||||
else if (keyframe.atTick.HasValue && AnimationController.Instance.stageTick == keyframe.atTick.Value)
|
else if (AnimationController.Instance.stageTick == keyframe.atTick.Value)
|
||||||
{ handleImage.color = Constants.ColorPink; }
|
{ handleImage.color = Constants.ColorPink; }
|
||||||
|
|
||||||
else
|
else
|
||||||
{ handleImage.color = Constants.ColorGrey; }
|
{ handleImage.color = Constants.ColorGrey; }
|
||||||
|
|
||||||
|
// Show sound symbol
|
||||||
string soundDef = Workspace.Instance.GetPawnKeyframe(actorID, keyframeID)?.soundEffect;
|
string soundDef = Workspace.Instance.GetPawnKeyframe(actorID, keyframeID)?.soundEffect;
|
||||||
|
soundIcon.SetActive(soundDef != null && soundDef != "" && soundDef != "None");
|
||||||
|
}
|
||||||
|
|
||||||
if (soundDef != null && soundDef != "" && soundDef != "None")
|
public float ScaledOffsetFromPivot()
|
||||||
{ soundIcon.SetActive(true); }
|
{
|
||||||
|
//if (IsPivotKeyframe(keyframe)) return 1f;
|
||||||
|
if (dragTickStart == pivotKeyframe.atTick.Value) return 0f;
|
||||||
|
|
||||||
else
|
return (float)(keyframe.atTick.Value - pivotKeyframe.atTick.Value) / (dragTickStart - pivotKeyframe.atTick.Value);
|
||||||
{ soundIcon.SetActive(false); }
|
}
|
||||||
|
|
||||||
|
public bool IsPivotKeyframe(Keyframe otherKeyframe)
|
||||||
|
{
|
||||||
|
return pivotKeyframe == otherKeyframe;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int GetIndexAmongstSelectedKeyframes()
|
||||||
|
{
|
||||||
|
List<PawnKeyframe> selectedKeyframes = Workspace.Instance.GetPawnKeyframes(Workspace.keyframeID).OrderBy(x => x.atTick)?.ToList();
|
||||||
|
if (selectedKeyframes.NullOrEmpty() || selectedKeyframes.Contains(keyframe) == false) return -1;
|
||||||
|
|
||||||
|
return selectedKeyframes.IndexOf(keyframe);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,7 +64,7 @@ namespace RimWorldAnimationStudio
|
||||||
|
|
||||||
if (Workspace.stageID != transform.GetSiblingIndex())
|
if (Workspace.stageID != transform.GetSiblingIndex())
|
||||||
{
|
{
|
||||||
AnimationController.Instance.stageTick = 1;
|
AnimationController.Instance.stageTick = Constants.minTick;
|
||||||
Workspace.Instance.RecordEvent("Stage selected");
|
Workspace.Instance.RecordEvent("Stage selected");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ namespace RimWorldAnimationStudio
|
||||||
{
|
{
|
||||||
[Header("Animation settings")]
|
[Header("Animation settings")]
|
||||||
public bool isAnimating = false;
|
public bool isAnimating = false;
|
||||||
public int stageTick = 1;
|
public int stageTick = Constants.minTick;
|
||||||
|
|
||||||
[Header("Object references")]
|
[Header("Object references")]
|
||||||
public Slider stageTimelineSlider;
|
public Slider stageTimelineSlider;
|
||||||
|
@ -25,7 +25,7 @@ namespace RimWorldAnimationStudio
|
||||||
public ActorCard actorCard;
|
public ActorCard actorCard;
|
||||||
public Transform animationTimelines;
|
public Transform animationTimelines;
|
||||||
public Transform actorBodies;
|
public Transform actorBodies;
|
||||||
public Toggle stretchkeyframesToggle;
|
public Toggle stretchKeyframesToggle;
|
||||||
public InputField playBackSpeedField;
|
public InputField playBackSpeedField;
|
||||||
public Button playToggleButton;
|
public Button playToggleButton;
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ namespace RimWorldAnimationStudio
|
||||||
public GameObject animationTimelinePrefab;
|
public GameObject animationTimelinePrefab;
|
||||||
|
|
||||||
// Private timing variables
|
// Private timing variables
|
||||||
private int lastStageTick = 1;
|
private int lastStageTick = Constants.minTick;
|
||||||
private float timeSinceLastUpdate = 0;
|
private float timeSinceLastUpdate = 0;
|
||||||
private int cycleIndex = 0;
|
private int cycleIndex = 0;
|
||||||
private bool isDirty = true;
|
private bool isDirty = true;
|
||||||
|
@ -57,7 +57,7 @@ namespace RimWorldAnimationStudio
|
||||||
{ Initialize(); }
|
{ Initialize(); }
|
||||||
|
|
||||||
// Update tick if animating
|
// Update tick if animating
|
||||||
stageTick = Mathf.Clamp(stageTick, 1, Workspace.StageWindowSize);
|
stageTick = Mathf.Clamp(stageTick, Constants.minTick, Workspace.StageWindowSize);
|
||||||
|
|
||||||
if (isAnimating)
|
if (isAnimating)
|
||||||
{
|
{
|
||||||
|
@ -72,12 +72,12 @@ namespace RimWorldAnimationStudio
|
||||||
if (stageTick > Workspace.StageWindowSize)
|
if (stageTick > Workspace.StageWindowSize)
|
||||||
{
|
{
|
||||||
if (stageLoopDropdown.value == 1)
|
if (stageLoopDropdown.value == 1)
|
||||||
{ stageTick = 1; }
|
{ stageTick = Constants.minTick; }
|
||||||
|
|
||||||
else if (stageLoopDropdown.value >= 2)
|
else if (stageLoopDropdown.value >= 2)
|
||||||
{
|
{
|
||||||
++cycleIndex;
|
++cycleIndex;
|
||||||
stageTick = 1;
|
stageTick = Constants.minTick;
|
||||||
|
|
||||||
if ((stageLoopDropdown.value == 2 && cycleIndex >= int.Parse(cyclesNormalField.text)) ||
|
if ((stageLoopDropdown.value == 2 && cycleIndex >= int.Parse(cyclesNormalField.text)) ||
|
||||||
(stageLoopDropdown.value == 3 && cycleIndex >= int.Parse(cyclesFastField.text)))
|
(stageLoopDropdown.value == 3 && cycleIndex >= int.Parse(cyclesFastField.text)))
|
||||||
|
@ -148,7 +148,7 @@ namespace RimWorldAnimationStudio
|
||||||
bool requiresGenitals = actor.requiredGenitals.Any(x => x == "Penis") || Workspace.animationDef.actors[actorID].isFucking;
|
bool requiresGenitals = actor.requiredGenitals.Any(x => x == "Penis") || Workspace.animationDef.actors[actorID].isFucking;
|
||||||
|
|
||||||
float clipPercent = (float)(stageTick % clip.duration) / clip.duration;
|
float clipPercent = (float)(stageTick % clip.duration) / clip.duration;
|
||||||
if (stageTick == clip.duration) clipPercent = 1f;
|
if (stageTick > Constants.minTick && stageTick == clip.duration) clipPercent = 1f;
|
||||||
|
|
||||||
if (Workspace.animationDef.animationStages[Workspace.stageID].isLooping == false)
|
if (Workspace.animationDef.animationStages[Workspace.stageID].isLooping == false)
|
||||||
{ clipPercent = (float)stageTick / clip.duration; }
|
{ clipPercent = (float)stageTick / clip.duration; }
|
||||||
|
@ -401,7 +401,7 @@ namespace RimWorldAnimationStudio
|
||||||
if (tickToPasteAt < 1) continue;
|
if (tickToPasteAt < 1) continue;
|
||||||
if (tickToPasteAt > Workspace.StageWindowSize)
|
if (tickToPasteAt > Workspace.StageWindowSize)
|
||||||
{
|
{
|
||||||
if (stretchkeyframesToggle.isOn)
|
if (stretchKeyframesToggle.isOn)
|
||||||
{ ResizeStageWindowSize(tickToPasteAt); }
|
{ ResizeStageWindowSize(tickToPasteAt); }
|
||||||
|
|
||||||
else continue;
|
else continue;
|
||||||
|
@ -487,7 +487,7 @@ namespace RimWorldAnimationStudio
|
||||||
|
|
||||||
if (keyframe == null || clip == null) return;
|
if (keyframe == null || clip == null) return;
|
||||||
|
|
||||||
if (keyframe.atTick == 1 && force == false)
|
if (keyframe.atTick == Constants.minTick && force == false)
|
||||||
{ Debug.LogWarning("Cannot delete key frame - the first key frame of an animation clip cannot be deleted"); return; }
|
{ Debug.LogWarning("Cannot delete key frame - the first key frame of an animation clip cannot be deleted"); return; }
|
||||||
|
|
||||||
if (clip.keyframes.Count <= 2 && force == false)
|
if (clip.keyframes.Count <= 2 && force == false)
|
||||||
|
@ -527,7 +527,7 @@ namespace RimWorldAnimationStudio
|
||||||
if (Workspace.animationDef == null) return;
|
if (Workspace.animationDef == null) return;
|
||||||
|
|
||||||
int.TryParse(animationClipTimeField.text, out int newStageTick);
|
int.TryParse(animationClipTimeField.text, out int newStageTick);
|
||||||
stageTick = Mathf.Clamp(newStageTick, 1, Workspace.StageWindowSize);
|
stageTick = Mathf.Clamp(newStageTick, Constants.minTick, Workspace.StageWindowSize);
|
||||||
stageTimelineSlider.value = stageTick;
|
stageTimelineSlider.value = stageTick;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -540,8 +540,11 @@ namespace RimWorldAnimationStudio
|
||||||
|
|
||||||
Debug.Log("Resizing animation clip length to " + newStageWindowSize.ToString() + " ticks.");
|
Debug.Log("Resizing animation clip length to " + newStageWindowSize.ToString() + " ticks.");
|
||||||
|
|
||||||
if (stretchkeyframesToggle.isOn)
|
if (stretchKeyframesToggle.isOn)
|
||||||
{ StretchKeyframes(newStageWindowSize); }
|
{
|
||||||
|
List<PawnKeyframe> keyframes = Workspace.animationDef.animationStages[Workspace.stageID].animationClips.SelectMany(x => x.keyframes)?.ToList();
|
||||||
|
StretchKeyframes(keyframes, Workspace.StageWindowSize, newStageWindowSize);
|
||||||
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -566,7 +569,7 @@ namespace RimWorldAnimationStudio
|
||||||
ResizeStageWindowSize(newStageWindowSize);
|
ResizeStageWindowSize(newStageWindowSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void StretchKeyframes(int newStageWindowSize)
|
/*public void StretchKeyframes(int newStageWindowSize)
|
||||||
{
|
{
|
||||||
float scale = (float)newStageWindowSize / Workspace.StageWindowSize;
|
float scale = (float)newStageWindowSize / Workspace.StageWindowSize;
|
||||||
|
|
||||||
|
@ -580,6 +583,39 @@ namespace RimWorldAnimationStudio
|
||||||
|
|
||||||
clip.BuildSimpleCurves();
|
clip.BuildSimpleCurves();
|
||||||
}
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
|
public void StretchKeyframes(List<PawnKeyframe> keyframesToStretch, int v1, int v2)
|
||||||
|
{
|
||||||
|
int v0 = keyframesToStretch.Min(x => x.atTick.Value);
|
||||||
|
|
||||||
|
if (v1 == v0)
|
||||||
|
{ OffsetKeyframes(keyframesToStretch, v1, v2); return; }
|
||||||
|
|
||||||
|
float scaleFactor = (float)(v2 - v0) / (v1 - v0);
|
||||||
|
|
||||||
|
foreach (PawnKeyframe keyframe in keyframesToStretch)
|
||||||
|
{
|
||||||
|
keyframe.atTick = Mathf.RoundToInt(scaleFactor * (keyframe.atTick.Value - v0) + v0);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach(PawnAnimationClip clip in Workspace.animationDef.animationStages[Workspace.stageID].animationClips)
|
||||||
|
{ clip.BuildSimpleCurves(); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OffsetKeyframes(List<PawnKeyframe> keyframesToOffset, int v1, int v2)
|
||||||
|
{
|
||||||
|
float offset = v2 - v1;
|
||||||
|
|
||||||
|
foreach (PawnKeyframe keyframe in keyframesToOffset)
|
||||||
|
{
|
||||||
|
keyframe.atTick = Mathf.RoundToInt(keyframe.atTick.Value + offset);
|
||||||
|
Debug.Log(keyframe.atTick);
|
||||||
|
Workspace.Instance.GetAnimationClipThatOwnsKeyframe(keyframe.keyframeID, out int clipID).BuildSimpleCurves();
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (PawnAnimationClip clip in Workspace.animationDef.animationStages[Workspace.stageID].animationClips)
|
||||||
|
{ clip.BuildSimpleCurves(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ResizeStageWindowSize(int newStageWindowSize)
|
public void ResizeStageWindowSize(int newStageWindowSize)
|
||||||
|
|
|
@ -341,19 +341,19 @@ namespace RimWorldAnimationStudio
|
||||||
public void ToPreviousTick()
|
public void ToPreviousTick()
|
||||||
{
|
{
|
||||||
if (Workspace.animationDef == null) return;
|
if (Workspace.animationDef == null) return;
|
||||||
AnimationController.Instance.stageTick = Mathf.Clamp(AnimationController.Instance.stageTick - 1, 1, Workspace.StageWindowSize);
|
AnimationController.Instance.stageTick = Mathf.Clamp(AnimationController.Instance.stageTick - 1, Constants.minTick, Workspace.StageWindowSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ToNextTick()
|
public void ToNextTick()
|
||||||
{
|
{
|
||||||
if (Workspace.animationDef == null) return;
|
if (Workspace.animationDef == null) return;
|
||||||
AnimationController.Instance.stageTick = Mathf.Clamp(AnimationController.Instance.stageTick + 1, 1, Workspace.StageWindowSize);
|
AnimationController.Instance.stageTick = Mathf.Clamp(AnimationController.Instance.stageTick + 1, Constants.minTick, Workspace.StageWindowSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ToFirstTick()
|
public void ToFirstTick()
|
||||||
{
|
{
|
||||||
if (Workspace.animationDef == null) return;
|
if (Workspace.animationDef == null) return;
|
||||||
AnimationController.Instance.stageTick = 1;
|
AnimationController.Instance.stageTick = Constants.minTick;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ToLastTick()
|
public void ToLastTick()
|
||||||
|
|
|
@ -8,6 +8,7 @@ namespace RimWorldAnimationStudio
|
||||||
public static class Constants
|
public static class Constants
|
||||||
{
|
{
|
||||||
public static int defaultAnimationClipLength = 600;
|
public static int defaultAnimationClipLength = 600;
|
||||||
|
public static int minTick = 1;
|
||||||
public static int minAnimationClipLength = 2;
|
public static int minAnimationClipLength = 2;
|
||||||
public static int maxAnimationClipLength = 9999;
|
public static int maxAnimationClipLength = 9999;
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,9 @@ namespace RimWorldAnimationStudio
|
||||||
if (animationDef.animationStages[stageID].stageWindowSize < 0)
|
if (animationDef.animationStages[stageID].stageWindowSize < 0)
|
||||||
{ animationDef.animationStages[stageID].stageWindowSize = animationDef.animationStages[stageID].animationClips.Select(x => x.duration).Max(); }
|
{ animationDef.animationStages[stageID].stageWindowSize = animationDef.animationStages[stageID].animationClips.Select(x => x.duration).Max(); }
|
||||||
|
|
||||||
|
Debug.Log(animationDef.animationStages[stageID].stageWindowSize);
|
||||||
|
|
||||||
|
|
||||||
return animationDef.animationStages[stageID].stageWindowSize;
|
return animationDef.animationStages[stageID].stageWindowSize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Binary file not shown.
BIN
Library/Artifacts/02/02d038242aec7f08a0ae0ef619f35253
Normal file
BIN
Library/Artifacts/02/02d038242aec7f08a0ae0ef619f35253
Normal file
Binary file not shown.
BIN
Library/Artifacts/08/0849b09ca822548dbe60ea1cf0d488a7
Normal file
BIN
Library/Artifacts/08/0849b09ca822548dbe60ea1cf0d488a7
Normal file
Binary file not shown.
Binary file not shown.
BIN
Library/Artifacts/0e/0e12311ad2d088363b0e1aa9d63c6e76
Normal file
BIN
Library/Artifacts/0e/0e12311ad2d088363b0e1aa9d63c6e76
Normal file
Binary file not shown.
BIN
Library/Artifacts/0e/0e9c5317b41cd4f57111a1dd7414a115
Normal file
BIN
Library/Artifacts/0e/0e9c5317b41cd4f57111a1dd7414a115
Normal file
Binary file not shown.
BIN
Library/Artifacts/0f/0fc8b8437dd20dce6456b408a2605838
Normal file
BIN
Library/Artifacts/0f/0fc8b8437dd20dce6456b408a2605838
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Library/Artifacts/1a/1abece6722aa0aef74545a4c54c26668
Normal file
BIN
Library/Artifacts/1a/1abece6722aa0aef74545a4c54c26668
Normal file
Binary file not shown.
BIN
Library/Artifacts/1b/1be3197b4cea048fca37d5d1e008ae8f
Normal file
BIN
Library/Artifacts/1b/1be3197b4cea048fca37d5d1e008ae8f
Normal file
Binary file not shown.
BIN
Library/Artifacts/1c/1cd72c8d9cf2e32d335c1559118249c3
Normal file
BIN
Library/Artifacts/1c/1cd72c8d9cf2e32d335c1559118249c3
Normal file
Binary file not shown.
BIN
Library/Artifacts/1d/1df6d1645d796f1d98c338b82971d674
Normal file
BIN
Library/Artifacts/1d/1df6d1645d796f1d98c338b82971d674
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Library/Artifacts/23/2391bf4e29e8a5b6c1fa9644fc9b7e2a
Normal file
BIN
Library/Artifacts/23/2391bf4e29e8a5b6c1fa9644fc9b7e2a
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Library/Artifacts/2e/2ea355ffc2a6caf29b72c0f2f22af111
Normal file
BIN
Library/Artifacts/2e/2ea355ffc2a6caf29b72c0f2f22af111
Normal file
Binary file not shown.
Binary file not shown.
BIN
Library/Artifacts/32/323cfebd1ab3ab1eb238bca56546faea
Normal file
BIN
Library/Artifacts/32/323cfebd1ab3ab1eb238bca56546faea
Normal file
Binary file not shown.
BIN
Library/Artifacts/34/3443da02546860be97e3e7fa8b74051f
Normal file
BIN
Library/Artifacts/34/3443da02546860be97e3e7fa8b74051f
Normal file
Binary file not shown.
BIN
Library/Artifacts/36/3668d4d5a5812a1434d80ce887fb1b93
Normal file
BIN
Library/Artifacts/36/3668d4d5a5812a1434d80ce887fb1b93
Normal file
Binary file not shown.
Binary file not shown.
BIN
Library/Artifacts/3d/3d24a99f7315ba23370371b8d70e1880
Normal file
BIN
Library/Artifacts/3d/3d24a99f7315ba23370371b8d70e1880
Normal file
Binary file not shown.
BIN
Library/Artifacts/3d/3df8530ec14d4448d800a26ddeb13d49
Normal file
BIN
Library/Artifacts/3d/3df8530ec14d4448d800a26ddeb13d49
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Library/Artifacts/49/498a068a834e39ea2168f2ef4539f92e
Normal file
BIN
Library/Artifacts/49/498a068a834e39ea2168f2ef4539f92e
Normal file
Binary file not shown.
Binary file not shown.
BIN
Library/Artifacts/4d/4d1ccf450769c817225cddb4efa536e8
Normal file
BIN
Library/Artifacts/4d/4d1ccf450769c817225cddb4efa536e8
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Library/Artifacts/51/5131fe4a17a1247a0551a24ba6e1962f
Normal file
BIN
Library/Artifacts/51/5131fe4a17a1247a0551a24ba6e1962f
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Library/Artifacts/56/56c6f1e704206665706fe41ed727b2d0
Normal file
BIN
Library/Artifacts/56/56c6f1e704206665706fe41ed727b2d0
Normal file
Binary file not shown.
Binary file not shown.
BIN
Library/Artifacts/5a/5a57c9b955014b661a1c774bb6ecb782
Normal file
BIN
Library/Artifacts/5a/5a57c9b955014b661a1c774bb6ecb782
Normal file
Binary file not shown.
Binary file not shown.
BIN
Library/Artifacts/5e/5ee82798c357968ec0b9bf4622589f63
Normal file
BIN
Library/Artifacts/5e/5ee82798c357968ec0b9bf4622589f63
Normal file
Binary file not shown.
BIN
Library/Artifacts/60/605d028ce47aa1384a27aa9c11093b4d
Normal file
BIN
Library/Artifacts/60/605d028ce47aa1384a27aa9c11093b4d
Normal file
Binary file not shown.
BIN
Library/Artifacts/64/649a6fc93ff5bff0e8410995bd1d62d0
Normal file
BIN
Library/Artifacts/64/649a6fc93ff5bff0e8410995bd1d62d0
Normal file
Binary file not shown.
Binary file not shown.
BIN
Library/Artifacts/66/66570a981116293f4bacb9581dcbcdbc
Normal file
BIN
Library/Artifacts/66/66570a981116293f4bacb9581dcbcdbc
Normal file
Binary file not shown.
BIN
Library/Artifacts/67/678663bf1ace83d88bb8809803a0feec
Normal file
BIN
Library/Artifacts/67/678663bf1ace83d88bb8809803a0feec
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Library/Artifacts/73/73970973be75cfcba4b6985db34d359e
Normal file
BIN
Library/Artifacts/73/73970973be75cfcba4b6985db34d359e
Normal file
Binary file not shown.
BIN
Library/Artifacts/80/806ca765630a0000d90c11162ca1719a
Normal file
BIN
Library/Artifacts/80/806ca765630a0000d90c11162ca1719a
Normal file
Binary file not shown.
BIN
Library/Artifacts/89/89619f484fdf58b39e0b938400a64608
Normal file
BIN
Library/Artifacts/89/89619f484fdf58b39e0b938400a64608
Normal file
Binary file not shown.
BIN
Library/Artifacts/89/89fa44427cebb99893d66cefec028087
Normal file
BIN
Library/Artifacts/89/89fa44427cebb99893d66cefec028087
Normal file
Binary file not shown.
BIN
Library/Artifacts/8a/8af2c2d0ca781bb4666d524a1922d351
Normal file
BIN
Library/Artifacts/8a/8af2c2d0ca781bb4666d524a1922d351
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Library/Artifacts/91/916b645af3c0b2ef8b41920896a0d165
Normal file
BIN
Library/Artifacts/91/916b645af3c0b2ef8b41920896a0d165
Normal file
Binary file not shown.
Binary file not shown.
BIN
Library/Artifacts/94/944d0e282cd10494e5d6b6f937a01fbf
Normal file
BIN
Library/Artifacts/94/944d0e282cd10494e5d6b6f937a01fbf
Normal file
Binary file not shown.
BIN
Library/Artifacts/94/94856e6bdd22cf835b494abed65be7c0
Normal file
BIN
Library/Artifacts/94/94856e6bdd22cf835b494abed65be7c0
Normal file
Binary file not shown.
BIN
Library/Artifacts/95/9535dba88e96b11a6049796a2486ae9f
Normal file
BIN
Library/Artifacts/95/9535dba88e96b11a6049796a2486ae9f
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Library/Artifacts/9a/9a0d64004528f452f40cc7ec14e196d8
Normal file
BIN
Library/Artifacts/9a/9a0d64004528f452f40cc7ec14e196d8
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Library/Artifacts/a0/a0d9c5823b6824a8c0d942b9b7f9911c
Normal file
BIN
Library/Artifacts/a0/a0d9c5823b6824a8c0d942b9b7f9911c
Normal file
Binary file not shown.
BIN
Library/Artifacts/a1/a1df5a1b70c88300b8b54a1d537be0db
Normal file
BIN
Library/Artifacts/a1/a1df5a1b70c88300b8b54a1d537be0db
Normal file
Binary file not shown.
Binary file not shown.
BIN
Library/Artifacts/a7/a71c575c22c59430a9b7c6052ff5b0b3
Normal file
BIN
Library/Artifacts/a7/a71c575c22c59430a9b7c6052ff5b0b3
Normal file
Binary file not shown.
Binary file not shown.
BIN
Library/Artifacts/ae/ae8acaf5e06375958ac1f8f4e1829be8
Normal file
BIN
Library/Artifacts/ae/ae8acaf5e06375958ac1f8f4e1829be8
Normal file
Binary file not shown.
BIN
Library/Artifacts/af/af3e2b083ded73933e142bd964ee7c6a
Normal file
BIN
Library/Artifacts/af/af3e2b083ded73933e142bd964ee7c6a
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Library/Artifacts/b4/b493d91632c61bbb00bd3a216fb36954
Normal file
BIN
Library/Artifacts/b4/b493d91632c61bbb00bd3a216fb36954
Normal file
Binary file not shown.
BIN
Library/Artifacts/b5/b530e645717e1a38c555ecbb0e87d9b2
Normal file
BIN
Library/Artifacts/b5/b530e645717e1a38c555ecbb0e87d9b2
Normal file
Binary file not shown.
BIN
Library/Artifacts/b6/b63bc4155f99dba0318877c683c97458
Normal file
BIN
Library/Artifacts/b6/b63bc4155f99dba0318877c683c97458
Normal file
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue