Skip to content

Commit

Permalink
fix: children of lights and cameras were inverted
Browse files Browse the repository at this point in the history
insert inbetween parent that undos the light/camera node flip, better hierarchy, less animation trouble
  • Loading branch information
hybridherbst committed Sep 5, 2022
1 parent fd9fd11 commit 5b7a016
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -58,5 +58,19 @@ public override int GetHashCode()
{
return !left.Equals(right);
}

/// First quaternion.
/// Second quaternion.
/// Result of multiplication.
public static Quaternion operator *(Quaternion left, Quaternion right)
{
float x = left.W * right.X + left.X * right.W + left.Y * right.Z - left.Z * right.Y;
float y = left.W * right.Y + left.Y * right.W + left.Z * right.X - left.X * right.Z;
float z = left.W * right.Z + left.Z * right.W + left.X * right.Y - left.Y * right.X;
float w = left.W * right.W - left.X * right.X - left.Y * right.Y - left.Z * right.Z;
Quaternion result = new Quaternion(x, y, z, w);
return result;

}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ public static bool CoordinateSpaceConversionRequiresHandednessFlip
}
}

internal static readonly Quaternion InvertDirection = new Quaternion(0, -1, 0, 0);

/// <summary>
/// Set a gltf node's converted translation, rotation, and scale from a unity transform
/// </summary>
Expand All @@ -64,7 +66,7 @@ public static bool CoordinateSpaceConversionRequiresHandednessFlip
public static void SetUnityTransform(this Node node, Transform transform, bool invertLookDirection)
{
node.Translation = transform.localPosition.ToGltfVector3Convert();
node.Rotation = (transform.localRotation * (invertLookDirection ? new Quaternion(0, -1, 0, 0) : Quaternion.identity)).ToGltfQuaternionConvert();
node.Rotation = (transform.localRotation * (invertLookDirection ? InvertDirection : Quaternion.identity)).ToGltfQuaternionConvert();
node.Scale = transform.localScale.ToGltfVector3Raw();
}

Expand Down
36 changes: 33 additions & 3 deletions UnityGLTF/Assets/UnityGLTF/Runtime/Scripts/GLTFSceneExporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -694,7 +694,8 @@ private NodeId ExportNode(Transform nodeTransform)
node.Light = ExportLight(unityLight);
}

if (unityLight != null || unityCamera != null)
var needsInvertedLookDirection = unityLight || unityCamera;
if (needsInvertedLookDirection)
{
node.SetUnityTransform(nodeTransform, true);
}
Expand Down Expand Up @@ -731,11 +732,40 @@ private NodeId ExportNode(Transform nodeTransform)
// children that are not primitives get added as child nodes
if (nonPrimitives.Length > 0)
{
node.Children = new List<NodeId>(nonPrimitives.Length);
var parentOfChilds = node;

// when we're exporting a light or camera, we add an implicit node as first child of the camera/light node.
// this ensures that child objects and animations etc. "just work".
if (needsInvertedLookDirection)
{
var inbetween = new Node();

if (ExportNames)
{
inbetween.Name = nodeTransform.name + "-flipped";
}

inbetween.Rotation = Quaternion.Inverse(SchemaExtensions.InvertDirection).ToGltfQuaternionConvert();

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

_root.Nodes.Add(inbetween);

node.Children = new List<NodeId>(1);
node.Children.Add(inbetweenId);

parentOfChilds = inbetween;
}

parentOfChilds.Children = new List<NodeId>(nonPrimitives.Length);
foreach (var child in nonPrimitives)
{
if(!ShouldExportTransform(child.transform)) continue;
node.Children.Add(ExportNode(child.transform));
parentOfChilds.Children.Add(ExportNode(child.transform));
}
}

Expand Down

0 comments on commit 5b7a016

Please sign in to comment.