Skip to content

Commit

Permalink
[animgraph] Animgraph v0.1 (#262)
Browse files Browse the repository at this point in the history
* [animgraph] Begin

* [animgraph] Created GenericGraphEditor to serve as a base for full screen graph editors

* [animgraph] First poc

* [animgraph] testblend workgin

* [animgraph] cleanup

* [animgraph] avoid crash when nodes get renamed

* [animgraph] Cleanup, now use decomposed matrices exclusively inside of anim graph

* [animgraph] blend node

* [animgraph] Begin work on parameters

* [animgraph] Refactored node storage

* [animgraph] Parameters somewhat working

* [animgraph] Param working

* [animgraph] Added preview button prototype

* [animgraph] Play/preview graph from a certain point

* [animgraph] Rename parameters

* [animgraph] Can drag&drop parameters in the graph now

* [animgraph] Parameter styling

* [animgraph] Default pose node

* [animgraph] Unlinked AnimNode inputs default to a global DefaultPose now

* [animgraph] Fix default animNode input for inputs after the last

* [animgraph] Param ux tweaks

* [animgraph] Style

* [animgraph] param tweaks

* [hide] Allow clickables submenus in context menu

* [animgraph] Improved bone picked for Blend per bone node

* [animgraph] Started working on blend spaces

* [animgraph] Blendspace somewhat working prototype

* [animgraph] Blendspaces almost working

* [hide] fix bug with extreme position values

* [animgraph] Begin working on BlendSpace2D ui

* [animgraph] Refactored BlendSpace2D so each animation instance is unique inside of a node

* [animgraph] More work on BlendSpace tool

* [animgraph] Save blendSpace2D

* [animgraph] More BlendSpace Editor tweaks

* [animgraph] Refactored AnimGraphInstance to be independant of the AnimGraph prefab

* [blendspace] Implemented animation preview

* [animgraph] UI tweaks

* [animgraph] Tweaks, bugfix and ux improvement

* [animgraph] Added ranges to preview values

* [animgraph] Restore runtime value when recompiling graph

* [animgraph] Parameter reordering and deletion

* [animgraph] Fix bugs, added input box to float params

* [animgraph] Better focus of preview mesh on init

* [animgraph] Refactored node param default value overrides

* [animgraph] Root Folder selection, choose preview model

* [animgraph] Refactored previews into ScenePreview, fixed many issues in the BlendSpaceEditor

* [animgraph] Refactored genericGraphEditor to use a ScenePreview

* [hide] Add support for directory path in scene.listAnims

* [animgraph] Anim list component

* [animgraph] Added AnimList to AnimGraphEditor

* [animgraph] Fix crash when object.defaultTransform was null

* [animgraph] Bugfixes

- prevent animgraph Output from being removed
- Style tweaks
- Editor crash fixes
- Ui improvements

* [scene] Auto load a render props in ScenePreview

* [animgraph] ScenePreview mesh picker

* [animgraph] Fix crash with null matrix

* [hide] Fix context menu not closing on enter

* [animgraph] Compile in game

* [animgraph] Fix animation translations in animgraph, added setParam api to Instance

* [animgraph] Added animgraph.Resource, fixed compilation

* [animgraph] Code review cleanup
  • Loading branch information
EspeuteClement authored Jan 10, 2025
1 parent ea9c548 commit 9aba39e
Show file tree
Hide file tree
Showing 32 changed files with 4,523 additions and 106 deletions.
444 changes: 418 additions & 26 deletions bin/style.css

Large diffs are not rendered by default.

550 changes: 518 additions & 32 deletions bin/style.less

Large diffs are not rendered by default.

45 changes: 45 additions & 0 deletions hide/comp/Button.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package hide.comp;


typedef Options = {
?hasDropdown: Bool,
}

/**
Dropdown that uses a ContextMenu for it's dropdown element
**/
class Button extends hide.comp.Component {
public var label(default, set) : String;

var labelElem : hide.Element;
function set_label(newLabel: String) : String {
label = newLabel;
labelElem.text(label);
return label;
}

public function new(parent: hide.Element = null, element: hide.Element = null, ?label: String, ?options: Options) {
options ??= {};
if (element != null) {
if (element.get(0).nodeName != "BUTTON-2")
throw "button to wrap must be a <button-2> element";
} else {
element = new Element("<button-2></button-2>");
}

super(parent, element);
labelElem = new Element("<value></value>").appendTo(element);

this.label = label;

if (options.hasDropdown) {
new Element('<div class="ico ico-chevron-down"></div>').appendTo(element);
}

element.click((e) -> onClick());
}

public dynamic function onClick() {

}
}
67 changes: 54 additions & 13 deletions hide/comp/ContextMenu.hx
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@ typedef MenuOptions = {

?placementHeight: Int,

/**
If true, the sub-menus will be inlined (like they are when the search is active)
**/
?flat: Bool,

}

class ContextMenu {
Expand Down Expand Up @@ -285,12 +290,13 @@ class ContextMenu {
else if (e.key == "Enter") {
e.preventDefault();
if (selected >= 0 && flatItems != null) {
if (flatItems[selected].menuItem.menu != null) {
if (flatItems[selected].menuItem.click != null) {
flatItems[selected].elem.click();
}
else if (flatItems[selected].menuItem.menu != null) {
currentSubmenuItemId = flatItems[selected].index;
refreshSubmenu();
currentSubmenu.updateSelection(0);
} else {
flatItems[selected].elem.click();
}
}
return true;
Expand Down Expand Up @@ -324,7 +330,7 @@ class ContextMenu {

menu.innerHTML = "";

if (filter == "") {
if (filter == "" && !options.flat) {
flatItems = [];
selected = -1;

Expand Down Expand Up @@ -364,7 +370,7 @@ class ContextMenu {
if (item.menu != null) {
var subItems = filterElements(item.menu, match);
if (subItems.length > 0) {
filteredItems.push({label: item.label, menu: subItems});
filteredItems.push({label: item.label, menu: subItems, click: item.click});
}
}
else {
Expand Down Expand Up @@ -399,13 +405,30 @@ class ContextMenu {

var item = top.next();
if (item.menu != null) {
var li = js.Browser.document.createLIElement();
menu.appendChild(li);
li.style.setProperty("--level", '${submenuStack.length-1}');
li.innerText = item.label;
li.classList.add("submenu-inline-header");
lastSeparator = null;
submenuStack.push(item.menu.iterator());
if (item.click != null) {
var newItem = {label: item.label, click: item.click, enabled: item.enabled};
var li = createItem(newItem, flatItems.length);

menu.appendChild(li);
li.style.setProperty("--level", '${submenuStack.length-1}');
if (item.enabled == null || item.enabled == true) {
flatItems.push({menuItem: item, elem: li, index: flatItems.length});
}
lastSeparator = null;
//li.classList.add("submenu-inline-header");

submenuStack.push(item.menu.iterator());
}
else {
var li = js.Browser.document.createLIElement();
menu.appendChild(li);
li.style.setProperty("--level", '${submenuStack.length-1}');
li.style.setProperty("--menu-level", '${submenuStack.length}');
li.innerText = item.label;
li.classList.add("submenu-inline-header");
lastSeparator = null;
submenuStack.push(item.menu.iterator());
}
}
else {
var li = createItem(item, flatItems.length);
Expand All @@ -424,6 +447,8 @@ class ContextMenu {
lastSeparator.remove();
}
}

refreshPos();
}

function close() {
Expand Down Expand Up @@ -562,7 +587,23 @@ class ContextMenu {
else {
selected = newIndex;
flatItems[selected].elem.classList.add("highlight");
flatItems[selected].elem.scrollIntoView({block: cast "nearest"});

var pos = flatItems[selected].elem.offsetTop;
var itemHeight = flatItems[selected].elem.getBoundingClientRect().height;

var top = menu.scrollTop;
var bot = menu.scrollTop + menu.clientHeight;

trace(pos, top, bot);


if (pos < top + 60) {
menu.scrollTo(0, pos - 60);
}
else if (pos + itemHeight > bot) {
menu.scrollTo(0,pos - (bot - top));
}

}
}

Expand Down
29 changes: 29 additions & 0 deletions hide/comp/Range.hx
Original file line number Diff line number Diff line change
Expand Up @@ -163,4 +163,33 @@ class Range extends Component {
public dynamic function onChange( tempChange : Bool ) {
}


/**
Automatically handle undo/redo, tracking automatically if a change is temporary or not.
get : a function that returns the current value you wanna change
set : a function that set the value you wanna change.
**/
public function setOnChangeUndo( undo: hide.ui.UndoHistory, get : () -> Float, set : (newValue: Float) -> Void) {
var save : Null<Float> = get();
onChange = (tempChange) -> {
if (!tempChange) {
var prev = save ?? get();
var curr = value;
function exec(isUndo) {
var newValue = !isUndo ? curr : prev;
value = newValue;
set(newValue);
}
exec(false);
undo.change(Custom(exec));
save = null;
}
else {
if (save == null) {
save = get();
}
set(value);
}
}
}
}
12 changes: 12 additions & 0 deletions hide/comp/SVG.hx
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,18 @@ class SVG extends Component {
return make(parent, "path", {d: lines.join("")}, style);
}

/**
Use the polygon element instead of path
**/
public function polygon2(?parent: Element, points: Array<h2d.col.Point>, ?style:Dynamic) {
// https://developer.mozilla.org/en-US/docs/Web/SVG/Element/polygon
var lines : Array<String> = [];
for(i in 0...points.length) {
lines.push('${points[i].x},${points[i].y}');
}
return make(parent, "polygon", {points: lines.join(" ")}, style);
}

public function group(?parent: Element, ?className: String, ?attr: Dynamic) {
var g = make(parent, "g", attr);
if(className != null)
Expand Down
54 changes: 35 additions & 19 deletions hide/comp/Scene.hx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class Scene extends hide.comp.Component implements h3d.IDrawable {
public var editor : hide.comp.SceneEditor;
public var autoDisposeOutOfDocument : Bool = true;

var currentRenderProps: hrt.prefab.Prefab;
var currentRenderProps: hrt.prefab.Reference;

public var errorMessageBox : Element;
var unFocusedTime = 0.;
Expand Down Expand Up @@ -153,6 +153,7 @@ class Scene extends hide.comp.Component implements h3d.IDrawable {
sevents.addScene(s2d);
sevents.addScene(s3d);
@:privateAccess window.checkResize();
preOnReady();
onReady();
onResize();
sync();
Expand Down Expand Up @@ -181,6 +182,9 @@ class Scene extends hide.comp.Component implements h3d.IDrawable {
errorThisFrame = true;
}

function preOnReady() {
}

function clearErrorMessage() {
errorMessageBox.html("");
errorMessageBox.css("visibility", "collapse");
Expand Down Expand Up @@ -336,23 +340,29 @@ class Scene extends hide.comp.Component implements h3d.IDrawable {
cleanup.push(function() { ide.fileWatcher.unregister( path, onChange ); });
}

public function listAnims( path : String ) {
public function listAnims( path : String, customFilter : (f:String) -> Bool = null ) {
var isDir = sys.FileSystem.isDirectory(ide.getPath(path));

var config = hide.Config.loadForFile(ide, path);

var dirs : Array<String> = config.get("hmd.animPaths");
if( dirs == null ) dirs = [];
dirs = [for( d in dirs ) ide.resourceDir + d];

var parts = path.split("/");
parts.pop();
dirs.unshift(ide.getPath(parts.join("/")));

var parts = path.split("/");
var anims = [];

var lib = loadHMD(path, false);
if( lib.header.animations.length > 0 )
anims.push(ide.getPath(path));
if (!isDir) {
parts.pop();
dirs.unshift(ide.getPath(parts.join("/")));

var lib = loadHMD(path, false);
if( lib.header.animations.length > 0 )
anims.push(ide.getPath(path));
} else {
dirs.unshift(path);
}

for( dir in dirs ) {
var dir = dir;
Expand All @@ -361,6 +371,8 @@ class Scene extends hide.comp.Component implements h3d.IDrawable {
var file = f.toLowerCase();
if( StringTools.startsWith(f,"Anim_") && (StringTools.endsWith(file,".hmd") || StringTools.endsWith(file,".fbx")) )
anims.push(dir+"/"+f);
if (customFilter != null && customFilter(f))
anims.push(dir+"/"+f);
}
}
return anims;
Expand Down Expand Up @@ -567,20 +579,24 @@ class Scene extends hide.comp.Component implements h3d.IDrawable {
}
currentRenderProps = null;

if (path == null)
return;
try {
currentRenderProps = Ide.inst.loadPrefab(path);
} catch(e) {
if (path == null) {
return;
}
var ctx = new hide.prefab.ContextShared(null, new h3d.scene.Object(s3d));
ctx.scene = this;
currentRenderProps.setSharedRec(ctx);
currentRenderProps = new hrt.prefab.Reference(null, new hide.prefab.ContextShared(null, new h3d.scene.Object(s3d)));
currentRenderProps.shared.scene = this;
currentRenderProps.source = path;

currentRenderProps.make();
var renderProps = currentRenderProps.getOpt(hrt.prefab.RenderProps, true);
if (renderProps != null)
renderProps.applyProps(s3d.renderer);

if (currentRenderProps.refInstance != null) {
var renderProps = currentRenderProps.refInstance.getOpt(hrt.prefab.RenderProps, true);
if (renderProps != null)
renderProps.applyProps(s3d.renderer);

for (light in currentRenderProps.refInstance.findAll(hrt.prefab.Light, true)) {
@:privateAccess light.icon.visible = false;
}
}
}

public dynamic function onUpdate(dt:Float) {
Expand Down
Loading

0 comments on commit 9aba39e

Please sign in to comment.