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

Export Unity animation clips and skeleton to GLTF #561

Open
wants to merge 10 commits into
base: main
Choose a base branch
from

Conversation

owilliamailliwo
Copy link
Contributor

Add exporting Unity animation clips and skeleton to GLTF. We can export GLTF file with animation clips and skeleton throght "GLTF -> Export ***" menu now.

@hybridherbst
Copy link
Collaborator

@owilliamailliwo couple questions to judge this vs my PR and which pieces to take from which:

  • does this support multiple skeletons
  • does this support multiple clips from an animator
  • does this support actual keyframes or just baked animation (mine is currently "baked but optimized")
  • does this have a timeline recorder clip (see unity usd for why this would be great) (mine doesn't yet)
  • does this work with Google SceneViewer (I had to fix some things in gltf dll to make that work)

@owilliamailliwo
Copy link
Contributor Author

owilliamailliwo commented Feb 29, 2020

Hi @soraryu ,
does this support multiple skeletons
YES
does this support multiple clips from an animator
YES
does this support actual keyframes or just baked animation (mine is currently "baked but optimized")
It supports keyframes animation.
does this have a timeline recorder clip (see unity usd for why this would be great) (mine doesn't yet)
It will soon support this feature.
does this work with Google SceneViewer (I had to fix some things in gltf dll to make that work)
I haven`t tested it with Google SceneViewer, but it works fine with babylon.js. It is fully compatible with the GLTF 2.0 standard.

I will create a new pull request recently, which will support the compression of animation data and geometry properties.
Because we have multiple teams are developing game projects base on this plugin, we will quickly improve the functionality of the plugin and share them out.

@hybridherbst
Copy link
Collaborator

hybridherbst commented Feb 29, 2020

That's great to hear! I'll look into any differences that there may be between mine and yours and notice here.

About compatibility: note that the rest of Khronos' Unity code (currently) itself isn't fully spec compatible in some places unfortunately, and there are big differences in gltf support between babylon, three, filament, scene viewer try etc. Please try in as many as you can.

foreach (var prim in primitives)
{
var smr = prim.GetComponent<SkinnedMeshRenderer>();
if (_existedSkins.TryGetValue(smr.rootBone.GetInstanceID(), out SkinId skinId))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't use the smr.rootbone's instanceid as the key, different skinnmeshrender' may have same rootBone

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have fixed this problem, I will commit it later. Thank you!


node.Mesh = ExportMesh(prim.name, new GameObject[] { prim });

_existedSkins.Add(smr.rootBone.GetInstanceID(), skinId);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here

Comment on lines 763 to 797
var boneNode = new Node
{
Name = bone.gameObject.name,
Translation = new GLTF.Math.Vector3(translation.x, translation.y, translation.z),
Rotation = new GLTF.Math.Quaternion(rotation.x, rotation.y, rotation.z, rotation.w),
Scale = new GLTF.Math.Vector3(scale.x, scale.y, scale.z),
};

if (bone.childCount > 0)
{
boneNode.Children = new List<NodeId>();
for (var i = 0; i < bone.childCount; ++i)
{
var childIndex = Array.IndexOf(smr.bones, bone.GetChild(i));
if (-1 == childIndex)
{
continue;
}
boneNode.Children.Add(
new NodeId
{
Id = childIndex + baseId,
Root = _root
}
);
}
}

nodeId = new NodeId
{
Id = _root.Nodes.Count,
Root = _root
};

_root.Nodes.Add(boneNode);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generate GLTF nodes is not add to existedNode dict and the _root.Nodes. Would cause duplicated nodes when add gameobject.

It would be more clear to generate GLTF nodes for every gameobject first, then parse components like mesh/skin

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be more clear to generate GLTF nodes for every gameobject first, then parse components like mesh/skin

Hi, thanks very much! I've fixed the problems you found. I couldn't agree more with your suggestion, but I don't want to make sweeping changes to the current code structure.

Comment on lines 803 to 821
NodeId rootBoneId = null;
if (!_existedNodes.TryGetValue(smr.rootBone.GetInstanceID(), out rootBoneId))
{
rootBoneId = new NodeId
{
Id = baseId,
Root = _root
};
}

skin.Skeleton = rootBoneId;

skinId = new SkinId
{
Id = _root.Skins.Count,
Root = _root
};

_root.Skins.Add(skin);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same problem

@CLAassistant
Copy link

CLA assistant check
All committers have signed the CLA.

@tufeixp
Copy link

tufeixp commented Nov 4, 2020

This will not work for runtime export 'cause AnimationUtility was called, and disregard legacy Animation system.

@hybridherbst
Copy link
Collaborator

@tufeixp that's correct; as outlined above a good improvement here would be the ability to record via a timeline clip (which would also work at runtime). Similar to how Unity-USD does that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants