Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Subscene capabilities to Timeline #45

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 45 additions & 13 deletions src/AtomAnimations/Animatables/AnimatablesRegistry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,25 +45,57 @@ public void RemoveStorableFloat(JSONStorableFloatRef t)

public FreeControllerV3Ref GetOrCreateController(Atom atom, string controllerName)
{
var t = _controllers.FirstOrDefault(x => x.Targets(controllerName));
if (t != null) return t;
var controller = atom.freeControllers.FirstOrDefault(fc => fc.name == controllerName);
if (ReferenceEquals(controller, null))

bool subscene = false;
if (atom.type == "SubScene")
{
SuperController.LogError($"Timeline: Atom '{atom.uid}' does not have a controller '{controllerName}'");
return null;
string atomName = null;
string cuid = null;
subscene = true;

if (controllerName.Contains("(")) //Will fail if someone puts a bracket in their atom name.
{
cuid = controllerName.Split('(')[0].Trim(')');
atomName = controllerName.Split('(')[1].Trim(')');

if (!atomName.Contains("/"))
atomName = atom.containingAtom.name + "/" + atomName;
}

var t = _controllers.FirstOrDefault(x => x.Targets(controllerName));
if (t != null) return t;

var controller = SuperController.singleton.GetAtomByUid(atomName).freeControllers.FirstOrDefault(x => x.name == cuid);

t = new FreeControllerV3Ref(controller, subscene);
_controllers.Add(t);
RegisterAnimatableRef(t);
return t;
}
else
{

var t = _controllers.FirstOrDefault(x => x.Targets(controllerName));
if (t != null) return t;
var controller = atom.freeControllers.FirstOrDefault(fc => fc.name == controllerName);
if (ReferenceEquals(controller, null))
{
SuperController.LogError($"Timeline: Atom '{atom.uid}' does not have a controller '{controllerName}'");
return null;
}
t = new FreeControllerV3Ref(controller);
_controllers.Add(t);
RegisterAnimatableRef(t);
return t;
}
t = new FreeControllerV3Ref(controller);
_controllers.Add(t);
RegisterAnimatableRef(t);
return t;
}

public FreeControllerV3Ref GetOrCreateController(FreeControllerV3 controller)
public FreeControllerV3Ref GetOrCreateController(FreeControllerV3 controller, bool subscene = false)
{
var t = _controllers.FirstOrDefault(x => x.Targets(controller));

var t = _controllers.FirstOrDefault(x => x.Targets(controller));
if (t != null) return t;
t = new FreeControllerV3Ref(controller);
t = new FreeControllerV3Ref(controller, subscene);
_controllers.Add(t);
RegisterAnimatableRef(t);
return t;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,54 @@
namespace VamTimeline
using System.Linq;

namespace VamTimeline
{
public class FreeControllerV3Ref : AnimatableRefBase
{
public readonly FreeControllerV3 controller;
public readonly Atom parentAtom;
public readonly bool subscene;

public FreeControllerV3Ref(FreeControllerV3 controller)
public FreeControllerV3Ref(FreeControllerV3 controller, bool subscene = false)
{
this.controller = controller;
this.parentAtom = controller.containingAtom;
this.subscene = subscene;
}

public override string name => controller.name;
public override string name => subscene ? controller.name + "("+ this.parentAtom.name+")" : controller.name;

protected string extractEffectorName(string atomName)
{
string effectorName = atomName.Contains('/') ? atomName.Split('/')[1] : atomName;
if (effectorName.ToLower().Contains("effector") || effectorName.ToLower().Contains("bendgoal"))
{
if (effectorName.Contains("&")) //Full body effector
{
string[] tokens = effectorName.Split('&');
if (tokens.Length > 2)
{
effectorName = tokens[1];
}
}
else if (effectorName.Contains("_")) //Fabbrik/LimbIK/CCD Effector
{
string[] tokens = effectorName.Split('_');
if (tokens.Length > 2)
{
effectorName = tokens[2] + " " + tokens[0];
}
}

}

return effectorName;
}

public override string GetShortName()
{
return controller.name.EndsWith("Control")
? controller.name.Substring(0, controller.name.Length - "Control".Length)
: controller.name;
return controller.name.EndsWith("Control")
? controller.name.Substring(0, controller.name.Length - "Control".Length)
: subscene ? extractEffectorName(this.parentAtom.name) : controller.name ;
}

public bool Targets(string controllerName)
Expand Down
16 changes: 13 additions & 3 deletions src/AtomAnimations/Operations/TargetsOperations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,17 @@ public TargetsOperations(Atom containingAtom, AtomAnimation animation, AtomAnima

public FreeControllerV3AnimationTarget Add(FreeControllerV3 fc)
{
if (fc == null || fc.containingAtom != _containingAtom) return null;
bool subscene = false;
if (_containingAtom.type == "SubScene")
{ subscene = true; if (fc == null || fc.containingAtom.containingSubScene.containingAtom != _containingAtom) return null; }
else
{ if (fc == null || fc.containingAtom != _containingAtom) return null; }

var target = _clip.targetControllers.FirstOrDefault(t => t.animatableRef.Targets(fc));
if (target != null) return target;
foreach (var clip in _animation.index.ByLayer(_clip.animationLayer))
{
var t = clip.Add(_animation.animatables.GetOrCreateController(fc));
var t = clip.Add(_animation.animatables.GetOrCreateController(fc, subscene));
if (t == null) continue;
t.SetKeyframeToCurrent(0f);
t.SetKeyframeToCurrent(clip.animationLength);
Expand All @@ -34,7 +39,12 @@ public FreeControllerV3AnimationTarget Add(FreeControllerV3 fc)
public void AddSelectedController()
{
var selected = SuperController.singleton.GetSelectedController();
if (selected == null || selected.containingAtom != _containingAtom) return;

if (_containingAtom.type == "SubScene")
{ if (selected == null || selected.containingAtom.containingSubScene.containingAtom != _containingAtom) return; }
else
{ if (selected == null || selected.containingAtom != _containingAtom) return; }

if (_animation.index.ByController().Any(kvp => kvp.Key.Targets(selected))) return;
Add(selected);
}
Expand Down
56 changes: 47 additions & 9 deletions src/UI/Screens/AddRemoveTargetsScreen.cs
Original file line number Diff line number Diff line change
Expand Up @@ -158,17 +158,40 @@ private void InitControllersUI()

private IEnumerable<string> GetEligibleFreeControllers()
{

yield return "";
var reservedByOtherLayers = new HashSet<FreeControllerV3>(animation.clips
.Where(c => c.animationLayer != current.animationLayer)
.SelectMany(c => c.targetControllers)
.Select(t => t.animatableRef.controller));
foreach (var fc in plugin.containingAtom.freeControllers)

if (plugin.containingAtom.type == "SubScene")
{
foreach (string atomName in SuperController.singleton.GetAtomUIDsWithFreeControllers()) //Get all the scene atoms
{
Atom atom = SuperController.singleton.GetAtomByUid(atomName);
if (atom.subScenePath.Split('/')[0].Equals(plugin.containingAtom.name)) //Check if the atom name has a path that matches the name of the subscene atom.
{
foreach (var fc in atom.freeControllers)
{
if (!fc.name.EndsWith("Control") && fc.name != "control") continue;
if (current.targetControllers.Any(c => c.animatableRef.Targets(fc))) continue;
if (reservedByOtherLayers.Contains(fc)) continue;
yield return fc.name + "(" + atomName.Split('/')[1] + ")"; //Attach the atom name in brackets so we can identify different control atoms.
}
}
}
}
else
{
if (!fc.name.EndsWith("Control") && fc.name != "control") continue;
if (current.targetControllers.Any(c => c.animatableRef.Targets(fc))) continue;
if (reservedByOtherLayers.Contains(fc)) continue;
yield return fc.name;

foreach (var fc in plugin.containingAtom.freeControllers)
{
if (!fc.name.EndsWith("Control") && fc.name != "control") continue;
if (current.targetControllers.Any(c => c.animatableRef.Targets(fc))) continue;
if (reservedByOtherLayers.Contains(fc)) continue;
yield return fc.name;
}
}
}

Expand Down Expand Up @@ -439,7 +462,19 @@ private void AddAnimatedController()

SelectNextInList(_addControllerListJSON);

var controller = plugin.containingAtom.freeControllers.FirstOrDefault(x => x.name == uid);
//new code add subscene atom controllers into targets.
string atomName = null;
bool subscene = false;
if (uid.Contains("(")) //Will fail if someone puts a bracket in their atom name.
{
var newUid = uid.Split('(')[0].Trim(')');
atomName = uid.Split('(')[1].Trim(')');
uid = newUid;
subscene = true;
}

var controller = atomName != null ? SuperController.singleton.GetAtomByUid(plugin.containingAtom.name+"/" + atomName).freeControllers.FirstOrDefault(x => x.name == uid) : plugin.containingAtom.freeControllers.FirstOrDefault(x => x.name == uid);

if (controller == null)
{
SuperController.LogError($"Timeline: Controller {uid} in atom {plugin.containingAtom.uid} does not exist");
Expand All @@ -459,11 +494,12 @@ private void AddAnimatedController()
}

foreach (var clip in animation.index.ByLayer(current.animationLayer))
{
var added = clip.Add(animation.animatables.GetOrCreateController(controller));
{
var added = clip.Add(animation.animatables.GetOrCreateController(controller, subscene));

if (added == null) continue;

var controllerPose = clip.pose?.GetControllerPose(controller.name);
var controllerPose = clip.pose?.GetControllerPose(controller.name);
if (controllerPose == null)
{
added.SetKeyframeToCurrent(0f);
Expand All @@ -475,8 +511,10 @@ private void AddAnimatedController()
added.SetKeyframeByTime(clip.animationLength, controllerPose.position, Quaternion.Euler(controllerPose.rotation));
}


if (!clip.loop)
added.ChangeCurveByTime(clip.animationLength, CurveTypeValues.CopyPrevious);

}
}
catch (Exception exc)
Expand Down