Race offsets and keyframe cloning

This commit is contained in:
AbstractConcept 2022-09-24 14:12:18 -05:00
parent d3b676df06
commit 007e2dd513
135 changed files with 1408 additions and 107 deletions

File diff suppressed because it is too large Load Diff

View File

@ -53,6 +53,38 @@ namespace RimWorldAnimationStudio
{ this.alienRaceDef = alienRaceDef; }
}
public Vector3 GetAlienRaceOffset()
{
if (alienRaceDef == null)
{ alienRaceDef = AlienRaceDefs.GetNamed("Human"); }
AlienRaceOffset raceOffset = raceOffsets.FirstOrDefault(x => x.defName == alienRaceDef.defName);
if (raceOffset == null)
{
raceOffset = new AlienRaceOffset(alienRaceDef.defName);
raceOffsets.Add(raceOffset);
}
return raceOffset.GetOffset();
}
public void SetAlienRaceOffset(Vector2 offset)
{
if (alienRaceDef == null)
{ return; }
AlienRaceOffset raceOffset = raceOffsets.FirstOrDefault(x => x.defName == alienRaceDef.defName);
if (raceOffset == null)
{
raceOffset = new AlienRaceOffset(alienRaceDef.defName);
raceOffsets.Add(raceOffset);
}
raceOffset.SetOffset(offset);
}
public void ValidateData()
{
bodyDefTypes = bodyDefTypes.Intersect(Tags.bodyDefTypes.Concat(CustomTags.bodyDefTypes))?.ToList();

View File

@ -7,7 +7,33 @@ namespace RimWorldAnimationStudio
[Serializable]
public class AlienRaceOffset
{
public string defName;
public Vector2 offset;
public string defName = "Human";
public string offset = "(0, 0)";
public AlienRaceOffset()
{
}
public AlienRaceOffset(string defName)
{
this.defName = defName;
}
public void SetOffset(Vector2 raceOffset)
{
offset = "(" + raceOffset.x + ", " + raceOffset.y + ")";
}
public Vector3 GetOffset()
{
string raceOffset = offset;
raceOffset = raceOffset.Trim();
raceOffset = raceOffset.Replace("(", "");
raceOffset = raceOffset.Replace(")", "");
var raceOffsets = raceOffset.Split(',');
return new Vector3(float.Parse(raceOffsets[0]), 0f, float.Parse(raceOffsets[1]));
}
}
}

View File

@ -55,8 +55,8 @@ namespace RimWorldAnimationStudio
if (Workspace.actorManipulationMode == ActorManipulationMode.Pan)
{
keyframe.bodyOffsetX = mousePosition.x;
keyframe.bodyOffsetZ = mousePosition.y;
keyframe.bodyOffsetX = mousePosition.x - Workspace.animationDef.actors[actorID].GetAlienRaceOffset().x;
keyframe.bodyOffsetZ = mousePosition.y - Workspace.animationDef.actors[actorID].GetAlienRaceOffset().z;
}
else if (Workspace.actorManipulationMode == ActorManipulationMode.Rotate)

View File

@ -45,12 +45,13 @@ namespace RimWorldAnimationStudio
{
if (Workspace.actorManipulationMode == ActorManipulationMode.Pan)
{
Vector3 headOffset = new Vector3(0f, 0.34f, 0f);
headOffset = Quaternion.Euler(0, 0, keyframe.bodyAngle) * headOffset;
// It's stupid but it works
Vector3 localPosA = transform.localPosition;
transform.position = mousePosition;
Vector3 localPosB = transform.localPosition;
transform.localPosition = localPosA;
float distance = Vector2.Dot(parent.transform.up, (Vector2)(mousePosition - parent.transform.position - headOffset));
keyframe.headBob = distance;
keyframe.headBob += localPosB.y - localPosA.y;
}
else if (Workspace.actorManipulationMode == ActorManipulationMode.Rotate)

View File

@ -12,6 +12,8 @@ namespace RimWorldAnimationStudio
public Dropdown bodyTypeDropdown;
public InputField bodyOffsetXField;
public InputField bodyOffsetZField;
public InputField raceOffsetXField;
public InputField raceOffsetZField;
public Toggle initiatorToggle;
public void Initialize()
@ -62,6 +64,10 @@ namespace RimWorldAnimationStudio
default: actor.requiredGender = null; break;
}
float.TryParse(raceOffsetXField.text, out x);
float.TryParse(raceOffsetZField.text, out z);
actor.SetAlienRaceOffset(new Vector2(x, z));
Workspace.Instance.RecordEvent("Actor body type offset data");
}
@ -86,6 +92,12 @@ namespace RimWorldAnimationStudio
if (bodyOffsetZField.isFocused == false)
{ bodyOffsetZField.text = actor.bodyTypeOffset.GetOffset(bodyType).z.ToString(); }
if (raceOffsetXField.isFocused == false)
{ raceOffsetXField.text = actor.GetAlienRaceOffset().x.ToString(); }
if (raceOffsetZField.isFocused == false)
{ raceOffsetZField.text = actor.GetAlienRaceOffset().z.ToString(); }
initiatorToggle.isOn = actor.initiator;
}
}

View File

@ -15,15 +15,13 @@ namespace RimWorldAnimationStudio
public Dropdown raceSelectDropdown;
public Transform raceSettingsWindow;
public Toggle isHumanoidToggle;
public InputField scaleField;
public override void Initialize(bool addedNewTag = false)
{
Reset();
string alienRaceDefName = raceSelectDropdown.value < raceSelectDropdown.options.Count ? raceSelectDropdown.options[raceSelectDropdown.value].text : "Human";
if (alienRaceDefName == null || alienRaceDefName == "") alienRaceDefName = "Human";
AlienRaceDef alienRaceDef = AlienRaceDefs.GetNamed(alienRaceDefName);
AlienRaceDef alienRaceDef = GetCurrentRaceDef();
if (alienRaceDef == null) return;
isHumanoidToggle.isOn = alienRaceDef.isHumanoid;
@ -80,6 +78,8 @@ namespace RimWorldAnimationStudio
AddCloneObjectToParent(raceSettingsWindow, 3);
}
scaleField.text = string.Format("{0:0.000}", alienRaceDef.scale.ToString());
}
public void Reset()
@ -89,10 +89,7 @@ namespace RimWorldAnimationStudio
public void SetIsHumanoid()
{
string alienRaceDefName = raceSelectDropdown.value < raceSelectDropdown.options.Count ? raceSelectDropdown.options[raceSelectDropdown.value].text : "Human";
if (alienRaceDefName == null || alienRaceDefName == "") alienRaceDefName = "Human";
AlienRaceDef alienRaceDef = AlienRaceDefs.GetNamed(alienRaceDefName);
AlienRaceDef alienRaceDef = GetCurrentRaceDef();
if (alienRaceDef == null) return;
alienRaceDef.isHumanoid = isHumanoidToggle.isOn;
@ -123,5 +120,22 @@ namespace RimWorldAnimationStudio
Initialize();
}
public AlienRaceDef GetCurrentRaceDef()
{
string alienRaceDefName = raceSelectDropdown.value < raceSelectDropdown.options.Count ? raceSelectDropdown.options[raceSelectDropdown.value].text : "Human";
if (alienRaceDefName == null || alienRaceDefName == "") alienRaceDefName = "Human";
return AlienRaceDefs.GetNamed(alienRaceDefName);
}
public void SetRaceScale()
{
AlienRaceDef alienRaceDef = GetCurrentRaceDef();
if (alienRaceDef == null) return;
float scale = float.Parse(scaleField.text);
alienRaceDef.scale = Mathf.Clamp(scale, 0.05f, 100f);
}
}
}

View File

@ -137,7 +137,7 @@ namespace RimWorldAnimationStudio
string bodyType = alienRaceDef.isHumanoid ? actorBody.bodyType : "None";
Vector3 deltaPos = new Vector3(clip.BodyOffsetX.Evaluate(clipPercent), 0, clip.BodyOffsetZ.Evaluate(clipPercent));
deltaPos += Workspace.animationDef.actors[actorID].bodyTypeOffset.GetOffset(bodyType);
deltaPos += Workspace.animationDef.actors[actorID].bodyTypeOffset.GetOffset(bodyType) + Workspace.animationDef.actors[actorID].GetAlienRaceOffset();
float bodyAngle = clip.BodyAngle.Evaluate(clipPercent);
float headAngle = clip.HeadAngle.Evaluate(clipPercent);
@ -151,10 +151,11 @@ namespace RimWorldAnimationStudio
int bodyFacing = (int)clip.BodyFacing.Evaluate(clipPercent);
int headFacing = (int)clip.HeadFacing.Evaluate(clipPercent);
Vector3 headBob = new Vector3(0, 0, clip.HeadBob.Evaluate(clipPercent)) + PawnUtility.BaseHeadOffsetAt(bodyType, bodyFacing);
float headBob = clip.HeadBob.Evaluate(clipPercent);
Vector3 headOffset = new Vector3(0, 0, headBob) + PawnUtility.BaseHeadOffsetAt(bodyType, bodyFacing);
Vector3 bodyPos = new Vector3(deltaPos.x, deltaPos.z, 0);
Vector3 headPos = new Vector3(headBob.x, headBob.z, 0);
Vector3 headPos = new Vector3(headOffset.x, headOffset.z, 0);
Vector3 appendagePos = PawnUtility.AppendageOffsetAt(bodyType, bodyFacing);
float appendageRotation = clip.GenitalAngle.Evaluate(clipPercent);
@ -185,6 +186,8 @@ namespace RimWorldAnimationStudio
actorBody.headRenderer.flipX = headFacing == 3;
//actorBody.appendageRenderer.flipX = bodyFacing == 3;
actorBody.transform.localScale = new Vector3(alienRaceDef.scale, alienRaceDef.scale, alienRaceDef.scale);
// ActorKeyframeCard update
if (ActorKeyframeCard.Instance.positionXField.isFocused == false) { ActorKeyframeCard.Instance.positionXField.text = bodyPos.x.ToString("0.000"); }
if (ActorKeyframeCard.Instance.positionZField.isFocused == false) { ActorKeyframeCard.Instance.positionZField.text = bodyPos.y.ToString("0.000"); }
@ -318,6 +321,38 @@ namespace RimWorldAnimationStudio
Workspace.Instance.RecordEvent("Keyframe addition");
}
public void ClonePawnKeyframe()
{
PawnAnimationClip clip = Workspace.Instance.GetCurrentPawnAnimationClip();
List<PawnKeyframe> keyframes = clip?.keyframes;
PawnKeyframe keyframe = Workspace.Instance.GetPawnKeyframe(Workspace.actorID, Workspace.keyframeID);
if (clip == null || keyframes == null)
{ Debug.LogWarning("Cannot clone pawn keyframe - the AnimationDef is invalid"); return; }
if (keyframes.FirstOrDefault(x => x.atTick == stageTick) != null)
{ Debug.LogWarning("Cannot clone pawn keyframe - a keyframe already exists at this tick"); return; }
if (keyframe == null)
{ Debug.LogWarning("Cannot clone pawn keyframe - no keyframe has been selected for cloning"); return; }
PawnKeyframe cloneFrame = keyframe.Copy();
cloneFrame.GenerateKeyframeID();
cloneFrame.atTick = stageTick;
PawnKeyframe nextKeyframe = keyframes.FirstOrDefault(x => x.atTick > stageTick);
if (nextKeyframe != null)
{ keyframes.Insert(keyframes.IndexOf(nextKeyframe), cloneFrame); }
else
{ keyframes.Add(cloneFrame); }
clip.BuildSimpleCurves();
animationTimelines.GetComponentsInChildren<AnimationTimeline>()[Workspace.actorID].AddPawnKeyFrame(cloneFrame.keyframeID);
}
public void RemovePawnKeyframe()
{
RemovePawnKeyframe(Workspace.actorID, Workspace.keyframeID);

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More