コード例 #1
0
ファイル: USDSceneExporter.cs プロジェクト: ubisoft/vrtist
        public static void SyncExportContext(GameObject exportRoot,
                                             ExportContext context)
        {
            context.exportRoot = exportRoot.transform.parent;
            Traverse(exportRoot, InitExportableObjects, context);

            Transform expRoot        = context.exportRoot;
            var       foundAnimators = new List <Transform>();

            foreach (var rootBoneXf in context.meshToSkelRoot.Values.ToArray())
            {
                bool alreadyProcessed = false;
                foreach (var xf in foundAnimators)
                {
                    if (rootBoneXf.IsChildOf(xf))
                    {
                        alreadyProcessed = true;
                        break;
                    }
                }

                if (alreadyProcessed)
                {
                    continue;
                }

                var animatorXf = rootBoneXf;

                while (animatorXf != null)
                {
                    // If there is an animator, assume this is the root of the rig.
                    // This feels very ad hoc, it would be nice to not use a heuristic.
                    var anim = animatorXf.GetComponent <Animator>();
                    if (anim != null)
                    {
                        // Any root bones under this animator will be merged into their most common ancestor,
                        // which is returned here and becomes the skeleton root.
                        Transform skeletonRoot = MergeBonesBelowAnimator(animatorXf, context);

                        if (skeletonRoot == null)
                        {
                            animatorXf = animatorXf.parent;
                            Debug.LogWarning("No children found under animator: " +
                                             UnityTypeConverter.GetPath(animatorXf) + " Root bone XF: " +
                                             UnityTypeConverter.GetPath(rootBoneXf));
                            continue;
                        }

                        foundAnimators.Add(anim.transform);

                        // The skeleton is exported at the skeleton root and UsdSkelAnimation is nested under
                        // this prim as a new prim called "_anim".
                        Unity.Formats.USD.SkelRootSample rootSample = CreateSample <Unity.Formats.USD.SkelRootSample>(context);
                        string skelRootPath   = UnityTypeConverter.GetPath(animatorXf.transform, expRoot);
                        string skelPath       = UnityTypeConverter.GetPath(skeletonRoot, expRoot);
                        string skelPathSuffix = "";
                        string skelAnimSuffix = "/_anim";

                        // When there is a collision between the SkelRoot and the Skeleton, make a new USD Prim
                        // for the Skeleton object. The reason this is safe is as follows: if the object was
                        // imported from USD, then the structure should already be correct and this code path will
                        // not be hit (and hence overrides, etc, will work correctly). If the object was created
                        // in Unity and there happened to be a collision, then we can safely create a new prim
                        // for the Skeleton prim because there will be no existing USD skeleton for which
                        // the namespace must match, hence adding a new prim is still safe.
                        if (skelPath == skelRootPath)
                        {
                            Debug.LogWarning("SkelRoot and Skeleton have the same path, renaming Skeleton");
                            skelPathSuffix = "/_skel";
                        }

                        rootSample.animationSource = skelPath + skelAnimSuffix;

                        // For any skinned mesh exported under this SkelRoot, pass along the skeleton path in
                        // the "additional data" member of the exporter. Note that this feels very ad hoc and
                        // should probably be formalized in some way (perhaps as a separate export event for
                        // which the SkinnedMesh exporter can explicitly register).
                        //
                        // While it is possible to bind the skel:skeleton relationship at the SkelRoot and
                        // have it inherit down namespace, the Apple importer did not respect this inheritance
                        // and it sometimes causes issues with geometry embedded in the bone hierarchy.
                        foreach (var p in context.plans)
                        {
                            if (p.Key.transform.IsChildOf(animatorXf.transform))
                            {
                                foreach (var e in p.Value.exporters)
                                {
                                    if (e.exportFunc == MeshExporter.ExportSkinnedMesh)
                                    {
                                        e.data = skelPath + skelPathSuffix;
                                    }
                                }
                            }
                        }

                        CreateExportPlan(
                            animatorXf.gameObject,
                            rootSample,
                            SkeletonExporter.ExportSkelRoot,
                            context,
                            insertFirst: true);
                        CreateExportPlan(
                            animatorXf.gameObject,
                            rootSample,
                            NativeExporter.ExportObject,
                            context,
                            insertFirst: false);

                        CreateExportPlan(
                            skeletonRoot.gameObject,
                            CreateSample <SkeletonSample>(context),
                            SkeletonExporter.ExportSkeleton,
                            context,
                            insertFirst: true,
                            pathSuffix: skelPathSuffix);
                        CreateExportPlan(
                            skeletonRoot.gameObject,
                            CreateSample <SkeletonSample>(context),
                            NativeExporter.ExportObject,
                            context,
                            insertFirst: false,
                            pathSuffix: skelPathSuffix);

                        CreateExportPlan(
                            skeletonRoot.gameObject,
                            CreateSample <SkelAnimationSample>(context),
                            SkeletonExporter.ExportSkelAnimation,
                            context,
                            insertFirst: true,
                            pathSuffix: skelAnimSuffix);

                        // Exporting animation is only possible while in-editor (in 2018 and earlier).
#if UNITY_EDITOR
#if false // Currently disabled, future work.
                        if (anim.layerCount > 0)
                        {
                            for (int l = 0; l < anim.layerCount; l++)
                            {
                                int clipCount = anim.GetCurrentAnimatorClipInfoCount(l);
                                var clipInfos = anim.GetCurrentAnimatorClipInfo(l);
                                foreach (var clipInfo in clipInfos)
                                {
                                    var bindings = UnityEditor.AnimationUtility.GetCurveBindings(clipInfo.clip);
                                    // Properties are expressed as individual values, for transforms this is:
                                    //   m_LocalPosition.x,y,z
                                    //   m_LocalScale.x,y,z
                                    //   m_LocalRotation.x,y,z,w
                                    // Which means they must be reaggregated into matrices.
                                    foreach (var binding in bindings)
                                    {
                                        if (binding.type != typeof(Transform))
                                        {
                                            continue;
                                        }
                                        Debug.Log(binding.path + "." + binding.propertyName);
                                        var knot = UnityEditor.AnimationUtility.GetEditorCurve(clipInfo.clip, binding);
                                    }
                                }
                            }
                        }
#endif // disabled.
#endif // Editor only.

                        break;
                    }

                    animatorXf = animatorXf.parent;
                }
            }
        }
コード例 #2
0
    public static void SyncExportContext(GameObject exportRoot,
                              ExportContext context) {
      context.exportRoot = exportRoot.transform.parent;
      Traverse(exportRoot, InitExportableObjects, context);

      Transform expRoot = context.exportRoot;
      var foundAnimators = new List<Transform>();
      foreach (var rootBoneXf in context.meshToSkelRoot.Values.ToArray()) {
        bool alreadyProcessed = false;
        foreach (var xf in foundAnimators) {
          if (rootBoneXf.IsChildOf(xf)) {
            alreadyProcessed = true;
            break;
          }
        }
        if (alreadyProcessed) {
          continue;
        }

        var animatorXf = rootBoneXf;
        
        while (animatorXf != null) {

          // If there is an animator, assume this is the root of the rig.
          // This feels very ad hoc, it would be nice to not use a heuristic.
          var anim = animatorXf.GetComponent<Animator>();
          if (anim != null) {
            // Any root bones under this animator will be merged into their most common ancestor,
            // which is returned here and becomes the skeleton root.
            Transform skeletonRoot = MergeBonesBelowAnimator(animatorXf, context);

            if (skeletonRoot == null) {
              animatorXf = animatorXf.parent;
              Debug.LogWarning("No children found under animator: " + UnityTypeConverter.GetPath(animatorXf) + " Root bone XF: " + UnityTypeConverter.GetPath(rootBoneXf));
              continue;
            }

            foundAnimators.Add(anim.transform);

            // The skeleton is exported at the skeleton root and UsdSkelAnimation is nested under
            // this prim as a new prim called "_anim".
            SkelRootSample rootSample = CreateSample<SkelRootSample>(context);
            string skelPath = UnityTypeConverter.GetPath(skeletonRoot, expRoot);
            rootSample.skeleton = skelPath;
            rootSample.animationSource = skelPath + "/_anim";

            CreateExportPlan(
                animatorXf.gameObject,
                rootSample,
                SkeletonExporter.ExportSkelRoot,
                context,
                insertFirst: true);
            CreateExportPlan(
                animatorXf.gameObject,
                rootSample,
                NativeExporter.ExportObject,
                context,
                insertFirst: false);

            CreateExportPlan(
                skeletonRoot.gameObject,
                CreateSample<SkeletonSample>(context),
                SkeletonExporter.ExportSkeleton,
                context,
                insertFirst: true);
            CreateExportPlan(
                skeletonRoot.gameObject,
                CreateSample<SkeletonSample>(context),
                NativeExporter.ExportObject,
                context,
                insertFirst: false);

            CreateExportPlan(
                skeletonRoot.gameObject,
                CreateSample<SkelAnimationSample>(context),
                SkeletonExporter.ExportSkelAnimation,
                context,
                insertFirst: true,
                pathSuffix: "/_anim");

            // Exporting animation is only possible while in-editor (in 2018 and earlier).
#if UNITY_EDITOR
#if false   // Currently disabled, future work.
            if (anim.layerCount > 0) {
              for (int l = 0; l < anim.layerCount; l++) {
                int clipCount = anim.GetCurrentAnimatorClipInfoCount(l);
                var clipInfos = anim.GetCurrentAnimatorClipInfo(l);
                foreach (var clipInfo in clipInfos) {
                  var bindings = UnityEditor.AnimationUtility.GetCurveBindings(clipInfo.clip);
                  // Properties are expressed as individual values, for transforms this is:
                  //   m_LocalPosition.x,y,z
                  //   m_LocalScale.x,y,z
                  //   m_LocalRotation.x,y,z,w
                  // Which means they must be reaggregated into matrices.
                  foreach (var binding in bindings) {
                    if (binding.type != typeof(Transform)) {
                      continue;
                    }
                    Debug.Log(binding.path + "." + binding.propertyName);
                    var knot = UnityEditor.AnimationUtility.GetEditorCurve(clipInfo.clip, binding);
                  }
                }
              }
            }
#endif // disabled.
#endif // Editor only.

            break;
          }
          animatorXf = animatorXf.parent;
        }
      }
    }