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

3DsMax: Option for multi-animation #7

Closed
deltakosh opened this issue Oct 16, 2017 · 42 comments
Closed

3DsMax: Option for multi-animation #7

deltakosh opened this issue Oct 16, 2017 · 42 comments

Comments

@deltakosh
Copy link
Contributor

Exemple: to have an array in the babylon options in 3ds in order to manually enter the range of different animations and put them inside the export (0-50: walk, 100-150: run)? This option would greatly help 3D graphic designers for complex projects.
BabylonJS/Babylon.js#2360

@Selmar
Copy link
Contributor

Selmar commented Dec 8, 2017

Yes, a tool to specify "this animation name" with "these nodes" at "these frames" is something I need. How is that coming along? I am willing to help with this, if needed.

@deltakosh
Copy link
Contributor Author

We will plan to get back to this in February after finishing the maya exporter
But if you want to tackle it you are more than welcome. Any help will be appreciated

@Selmar
Copy link
Contributor

Selmar commented Jan 3, 2018

I would like to start on this, but I don't want to do something that ends up being useless. I am not very familiar with the 3dsmax API. I think it's wise to give me some pointers on how to implement this, if you have some ideas about that, both from a technical and user point of view.

@noalak
Copy link
Contributor

noalak commented Jan 8, 2018

Hi Selmar,

Good news you are willing to help on this! Let me introduce you with our plans on this feature.

--- USER POV ---

The goal is to have a tool to:

  • run several animations at once. Those animations could be of either type (position, rotation, scaling) on several nodes.
  • split animation timeline into ranges

Let's name AnimationGroup a set of animations for a specific range of frames

So as you said, for a single AnimationGroup we need to specify:

  • a name like "Idle", "move"
  • the animated nodes
  • a range of frames (min and max) like [10; 40]

Once exported, a gltf scene can be loaded by an engine. The Babylon engine automatically starts and loops the first AnimationGroup in the list.

In a nutshell, the tool is similar to the FBX multi take exporter but for gltf / babylon formats.

--- TECH POV ---

The naming can be quite confusing. To make sure we understand each other:
BABYLON.AnimationGroup = glTF animation
BABYLON.Animation = glTF animation channel

The normal exportation workflow is:
3ds max => Babylon => gltf

Do you want to create the tool for gltf format only or for both babylon and gltf?
If interested in Babylon, you can read documentation about AnimationGroup here.
Assuming you want to use the tool asap, you can bypass Babylon step. Bypassing is not ideal but will be fixed later. What you will do however will still be used!

Do you need help on how to contribute to a github project (how to fork, pull request...) ?

Do you need help on how to build and deploy the exporter?

You can read gltf documentation about animations here. It's quite hard to get by at first but exporter already implements such specifications. You will mostly only modify things here and there :)

Also have a look at BabylonExporter.GLTFExporter.Animation.cs file, especially 'ExportNodeAnimation' function.

Once done, I will detail to you how to:

  • create an UI component (form) displayed in 3ds max
  • refactor animations handling in the exporter (c#)

@tkazik
Copy link
Contributor

tkazik commented Jan 9, 2018

Awesome! Looking forward to that! 👍

@tkazik
Copy link
Contributor

tkazik commented Jan 9, 2018 via email

@Selmar
Copy link
Contributor

Selmar commented Jan 9, 2018

Sorry for the late reply and thanks a lot for the information!

I will start with gltf-only, if that is possible, certainly. I doubt I will get the time to develop the babylon part as well, but we'll see.

I think I understand forking and building/deploying for the most part. I also think I understand the gltf file format quite well, as I've written the importer we currently use in the game.

I haven't worked with javascript before though, so I'm curious about how you edit/test that? Do you use a different IDE or does it work with Visual Studio?

@noalak
Copy link
Contributor

noalak commented Jan 9, 2018

The exporter is written in c#. Javascript is only used on the engine side by BabylonJS.
We advise you to edit the exporter with Visual Studio.
To test the exporter, generate some outputs (.gltf & .bin files). Then give them to any gltf reader. Could be your own or the Babylon Sandbox. You can also submit the .gltf file to Khronos validator.

@noalak
Copy link
Contributor

noalak commented Jan 9, 2018

--- UI ---

You should probably start with the UI creation.
We would like an UI component to provide extra data related to AnimationGroup.

Those data are specified for a specific node. This way, the node and all its children are used to create the AnimationGroup.

This panel can be either:

  • added to BabylonProperties (right click on an object in the scene viewport > "Babylon..." > "Babylon Properties")
  • displayed in a new window (right click on an object in the scene viewport > "Babylon..." > "Animation Group Properties")
  • displayed in the 3ds Max Command panel like FBX multitake

We prefer option 1 or 2 to be coherent with other panels we made.

The panel contains a form which asks for:

  • a name
  • a range of frames

When form is submit, it adds an entry to a list aside.

--- Animation refactoring ---

Now that the UI provides extra info about AnimationGroups, you can use them inside the exporter.
See line 119 in BabylonExporter.Mesh.cs file for an example of how to retreive extra data.

What we have now:

The exporter goes through node hierarchy using depth-first search. Each node and its animations are exported one after the other.

What we want:

When going through each node, if a node contains AnimationGroup data the animations are not exported as they are currently with 'ExportNodeAnimation' method.
Instead you create AnimationGroups with a new method like 'ExportAnimationGroups'.
It does a similar job of creating GLTFAnimations but instead of exporting animations of the current node, it exports animations of the node and all its children recursively (see getDescendants method in BabylonExporter.GLTFExporter.cs file).

You create a number of GLTFAnimation equals to the number of AnimationGroup setup in the UI.
For each node containing animations, you add channels and samplers to each GLTFAnimation.
Each animation is added to the GLTFAnimation with inputs range clamped by the min and max provided in the UI for this AnimationGroup.

Then, you remove BabylonAnimations of node and its children so that they are not exported when reached afterwards. This guarentees animations are exported only once.

Going step by step:
Start by ignoring node children assuming nodes don't have children. Test with a single and simple object in your scene like a cube. Simply split animations with ranges.

Does it make sense to you ? If not i'm here to answer your questions!

@Selmar
Copy link
Contributor

Selmar commented Jan 9, 2018

Ah, I see. I thought the exporter UI was in javascript, my bad. I see now.

Everything makes perfect sense! Thanks for the information about the data retrieval, that was my next question. I'll start with creating a UI similar to the FBX exporter, like you suggest.

There is some additional functionality that I would like to add, which may slightly change the design. In our case, we have a lot of small animations per object, which may overlap in frame times (but need to be exported separately). This is to prevent having a very large number of frames in the max timeline. So ideally, I will also add (the option of) selecting specific nodes instead of using all animated nodes at a certain timeframe. Does this fit in your ideas about the tool?

@Selmar
Copy link
Contributor

Selmar commented Jan 9, 2018

In that case, I think the most fitting place to add the window would be in the menu toolbar under "Babylon" > "Animation Groups...", where the "Babylon File Exporter..." option currently resides.

@Selmar
Copy link
Contributor

Selmar commented Jan 9, 2018

So, forking it here: https://github.com/Selmar/Exporters

There seem to be some .cache files added to the repository: (...)\3ds Max\GltfExport.Entities\obj\Debug\GLTFExport.Entities.csproj.CoreCompileInputs.cache, is there a specific reason for this or can I remove those?

@noalak
Copy link
Contributor

noalak commented Jan 9, 2018

There is some additional functionality that I would like to add, which may slightly change the design. In our case, we have a lot of small animations per object, which may overlap in frame times (but need to be exported separately). This is to prevent having a very large number of frames in the max timeline. So ideally, I will also add (the option of) selecting specific nodes instead of using all animated nodes at a certain timeframe. Does this fit in your ideas about the tool?

Well it's something that could be quite complex.
Let's say you have a root dummy with 2 meshes as children.

AnimationGroup1 =
[
{mesh1 animations between frames 0 and 50}
{mesh2 animations between frames 0 and 50}
]

AnimationGroup2 =
[
{mesh1 animations between frames 0 and 50}
{mesh2 animations between frames 75 and 125}
]

Is it something like AnimationGroup1 you want to do or AnimationGroup2?

If it's AnimationGroup2, do you want to the animations to be played

  • in sequence: mesh1 moves for 50 frames, nothing moves for 25 frames finally mesh2 moves for 50
  • simultaneously: mesh1 and mesh2 moves for 50 frames

In 2nd case, the timeline loose any "time" sense and is just a place to put animations into and the timing is handled by the tool. It's obviously something much more complex.

@noalak
Copy link
Contributor

noalak commented Jan 9, 2018

There seem to be some .cache files added to the repository: (...)\3ds Max\GltfExport.Entities\obj\Debug\GLTFExport.Entities.csproj.CoreCompileInputs.cache, is there a specific reason for this or can I remove those?

Removable

@Selmar
Copy link
Contributor

Selmar commented Jan 9, 2018

Definitely like AnimationGroup1. Anything more complex seems unnecessary, at least for our purposes. The goal is only to be able to split a fully animated object into separately animated parts.

I can imagine someone might find it "handy" to have a complex system that can do things like AnimationGroup2, but I feel like that is way out of scope at the current time.

@noalak
Copy link
Contributor

noalak commented Jan 10, 2018

Well that seems reasonable.

From our point of view, the main purpose of the tool is to export bones animations ("Idle", "Move", "Shoot"). For that, the tool should be easy to use and straight forward. So automatically selecting all children of a node is very convenient here.

As advanced option, then we could allow the user to specify which children to include or not. Selecting the nodes among the children of a root node is something that suits your needs ?
Or do you need to select nodes from all over the scene ? In that case, as you said, the tool should be at global level instead of node level.

@deltakosh Your opinion on this ?

@Selmar
Copy link
Contributor

Selmar commented Jan 10, 2018

Yes, I need to select nodes from all over the scene. A car that has an animation that turns its wheels would be a good example. An animation could use dummy nodes as well, which are not necessarily part of the same hierarchy.

In my case, 3dsmax already selects all children when you select an object in the scene view, so simply adding all selected nodes to an animation would be effective in that case. Does it behave like that for you as well? Of course, an option to "Add all children of selected nodes" is not so difficult to add.

@Selmar
Copy link
Contributor

Selmar commented Jan 10, 2018

I'm currently looking for a place to save the animation data generated by the UI. As the data is not specific to any node, attaching it to nodes would lead to a lot of data duplication and perhaps synchronization issues with hierarchy edits.

I did not find a way to save this kind of information related to scenes in the plugin. Am I missing it?

In the max documentation I found this. Would something like that be appropriate? Or perhaps you already have an idea about how to implement this?

@deltakosh
Copy link
Contributor Author

Hello!
So I think we can add this at global level (on the scene: right click, inside Babylon.js properties perhaps)
Data can be saved at scene level also in .babylonjs format.

I think that by default the system can take only selected nodes and we can add a checkbox to select all node hierarchy

Does it make sense?

@Selmar
Copy link
Contributor

Selmar commented Jan 10, 2018

Okay, I will take a look at the Scene Properties form. I read in the max documentation that the RootNode was not saved disk, but a quick test shows that the data is indeed updated after rebooting max.

That all makes sense, thanks! I think I'll be able to figure out the rest for now. I'll come back to you when I have something usable and we can discuss about the details.

@deltakosh
Copy link
Contributor Author

Thanks a lot for your appreciated help!

@noalak
Copy link
Contributor

noalak commented Jan 10, 2018

Do not hesitate to post if you encounter any issue, either design or technical. GL :)

@Selmar
Copy link
Contributor

Selmar commented Jan 10, 2018

I will! In fact, that reminds me of a few inconveniences related to the project setup. I guess you are aware of this or perhaps you have a better way to work around them than I do.

Because of the source files being "outside"of the project folders:

  • adding new source files takes some extra work: (exclude from project, move, re-add)
  • adding new forms and controls requires manual editing of the project files (because they are "external" to the project this seems to give some problems, at least in VS2017 15.5.2)

Additionally:

  • the custom controls don't show up in my toolbox, which makes adding them to a form a bit of a hassle

@deltakosh
Copy link
Contributor Author

The project structure is mostly like this because we need to support multiple version of 3dsmax

@Selmar
Copy link
Contributor

Selmar commented Jan 16, 2018

I have finished the basic UI part, including serialization. While I continue with the exporting part, perhaps take a look (at the commits, code and UI) and tell me what you think needs to change.

@Selmar
Copy link
Contributor

Selmar commented Jan 16, 2018

A few things that may be worth noting from my point of view:

  • I added Loader.Global.SetSaveRequiredFlag(true, false); to my saving events, which marks the .max file as dirty. Perhaps the same would be useful for the other windows.
  • Serializing the animation group information was not trivial; I serialize lists as strings with separators. To serialize animation group info, I put all the information for it in one string. I save them with a GUID as property name. To serialize which animation groups exist, I store a list with these GUIDs.
  • I have not adhered to any coding conventions, this cleanup will happen later, but please let me know what you want.
  • I have changed the HasParent() function to check if the parent is a rootnode instead of seeing whether it has an object attached; this seemed more correct. It works for me, but perhaps you know more about this?
  • I am aware the node manipulation buttons are a bit unclear; this will of course change. If you have good ideas for names and layouts I'm all ears.

@Selmar
Copy link
Contributor

Selmar commented Jan 17, 2018

I have finished a basic exportation. I have only tested it with one model. It works well, although I have found a number of issues and a number of small ideas. They are quite arbitrary, so perhaps we could open up a more convenient communication channel (skype/discord/?) and tackle them all at once?

(just repeating so you find it easily); https://github.com/Selmar/Exporters)

@tkazik
Copy link
Contributor

tkazik commented Feb 1, 2018

Hi Selmar, that's very good news! I guess I can' t really help you with the issues, but I would love to test this feature with my model! Any chances you can upload some binaries? Thx!

@tkazik
Copy link
Contributor

tkazik commented Feb 1, 2018

Very weird! By posting the above comment, I somehow unassigned QuentinRillet, which was not intended at all...sorry for that! Can someone please revert that? I dont' have the option in the tiny phone browser. Thx!

@Jaskar
Copy link
Contributor

Jaskar commented Feb 1, 2018

Hi @tkazik ,
Don't worry, @noalak and @Selmar are on this :)

@Selmar
Copy link
Contributor

Selmar commented Feb 1, 2018

I don't think I have the rights to assign issues either.

I'm not sure whether the max '17 and '18 ones will work, there is still a warning related to them:
warning MSB3270: There was a mismatch between the processor architecture of the project being built "MSIL" and the processor architecture of the reference "Autodesk.Max, Version=17.0.630.0 [...]
This is because the .dll's are x64, but the project is not.

I had to undo this processor architecture change, because the windows forms editor requires an x86 build to be able to show custom forms. In the end, I suppose we should use x86 exclusively to edit forms and build/test/upload x64 builds.

Either way, here are some binaries:
Max2Babylon-0.36.1-animGroups.zip

@Selmar
Copy link
Contributor

Selmar commented Feb 1, 2018

Let me know if you have any bugs, wishes or other issues! :)

@tkazik
Copy link
Contributor

tkazik commented Feb 3, 2018

Thx, @Selmar!
I just 'installed' the binaries in 3ds max '16 and noticed the GameExporter and PrintStudio menu options between Help and Babylon. With the GameExporter, I am able to set the clips, but it seems to me that these are only for the fbx files. How does the workflow look like for the gltf?
Thx!

@Selmar
Copy link
Contributor

Selmar commented Feb 4, 2018

I think you have different binaries (or an extra plugin), I don't know anything about GameExporter or PrintStudio in my version!

You can find the animation groups for babylon under the right-click menu in Babylon... > Animation Groups. I guess that would've been helpful information.. :-P

@tkazik
Copy link
Contributor

tkazik commented Feb 5, 2018

Alright, the right-click hint did the trick :)
Congratulations and a huge thank you for the extension!
I tested one model and it works nicely in versions 2016 and 2017.
Two things:

  • In the 2018 version the "Babylon Animation Groups" does not show up in the right-click menu.
  • The model has animations that are of different length, e.g. one animation is 25 frames and others are 10 frames. When played in this viewer, the shorter animations seem to pause and not loop constantly. Do you experience the same? Is this a thing from the exporter or rather viewer?

multianim

Model with .max file and .glb are here:
A319_gen_multi_animation.zip

PS: There still seems to be a problem with the normals...but I guess that is work in progress by @noalak

edit: added picture

@Selmar
Copy link
Contributor

Selmar commented Feb 5, 2018

I think the 2018 project was added after I did the menus, so that would explain the missing option. I will update it.

I don't think I have experienced pausing of an animation. I will take a look at the plane.

I know there can be some issues with animation frames not being exported. I would like to address these with @noalak, because they are related to some babylon code I don't really know well:

  • Animations can be shorter than expected. This happens because of an optimization in the keyframe evaluation, where frames that are very similar are skipped. I believe this can be disabled by checking a "do not optimize animations" checkbox somewhere.
  • Animations will not be correct if the keyframes are linear and the start/end times are not exactly on the frames being exported. In this case, it will not interpolate. For non-linear keyframes this does not happen, because the curve is transformed into a series of keyframes instead.

@Selmar
Copy link
Contributor

Selmar commented Feb 5, 2018

As for the pausing, I think that's the viewer. The data seems correct on export. In addition, the windows built-in app 3D Builder animates the object correctly. It might have to do with the short animation length, perhaps?

@tkazik
Copy link
Contributor

tkazik commented Feb 8, 2018

Hm, is there an option to display each animation of the group individually in 3D builder? I haven't seen such option. Neither is the babylon viewer able to play these animations individually. Do you have another suggestion for a viewer?
Btw, is the AnimationGroup integrated into this exporter at some point?

@Selmar
Copy link
Contributor

Selmar commented Feb 9, 2018

I only know the viewers you already know. They either have that short animation issue or they don't support showing individual animations. Of course, we have our own engine as well, but that's not helping you.

The animation groups will eventually be integrated, yes. This depends on when @noalak gets time to review it and perhaps add the babylon part. I guess this is after the maya exporter. (@deltakosh ?)

@deltakosh
Copy link
Contributor Author

Correct

@Selmar
Copy link
Contributor

Selmar commented Apr 23, 2018

@deltakosh Any estimation for when this may be integrated? Or should I have submitted a pull request?

We're using it with success, it's been quite stable for a while now. I'm quite sure it will require some work to fully integrate, though.

@deltakosh
Copy link
Contributor Author

A PR is the best way to get it ASAP:)

@deltakosh deltakosh added the working on Someone is currently working on this issue label May 24, 2018
@noalak noalak removed the working on Someone is currently working on this issue label Jun 18, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants