public UsdSkelTopology(VtTokenArray topology) : this(UsdCsPINVOKE.new_UsdSkelTopology__SWIG_4(VtTokenArray.getCPtr(topology)), true)
 {
     if (UsdCsPINVOKE.SWIGPendingException.Pending)
     {
         throw UsdCsPINVOKE.SWIGPendingException.Retrieve();
     }
 }
 public UsdSkelSkinningQuery(UsdPrim prim, VtTokenArray skelJointOrder, VtTokenArray blendShapeOrder, UsdAttribute jointIndices, UsdAttribute jointWeights, UsdAttribute geomBindTransform, UsdAttribute joints, UsdAttribute blendShapes, UsdRelationship blendShapeTargets) : this(UsdCsPINVOKE.new_UsdSkelSkinningQuery__SWIG_1(UsdPrim.getCPtr(prim), VtTokenArray.getCPtr(skelJointOrder), VtTokenArray.getCPtr(blendShapeOrder), UsdAttribute.getCPtr(jointIndices), UsdAttribute.getCPtr(jointWeights), UsdAttribute.getCPtr(geomBindTransform), UsdAttribute.getCPtr(joints), UsdAttribute.getCPtr(blendShapes), UsdRelationship.getCPtr(blendShapeTargets)), true)
 {
     if (UsdCsPINVOKE.SWIGPendingException.Pending)
     {
         throw UsdCsPINVOKE.SWIGPendingException.Retrieve();
     }
 }
 public UsdSkelAnimMapper(VtTokenArray sourceOrder, VtTokenArray targetOrder) : this(UsdCsPINVOKE.new_UsdSkelAnimMapper__SWIG_2(VtTokenArray.getCPtr(sourceOrder), VtTokenArray.getCPtr(targetOrder)), true)
 {
     if (UsdCsPINVOKE.SWIGPendingException.Pending)
     {
         throw UsdCsPINVOKE.SWIGPendingException.Retrieve();
     }
 }
 public VtTokenArray(VtTokenArray other) : this(UsdCsPINVOKE.new_VtTokenArray__SWIG_3(VtTokenArray.getCPtr(other)), true)
 {
     if (UsdCsPINVOKE.SWIGPendingException.Pending)
     {
         throw UsdCsPINVOKE.SWIGPendingException.Retrieve();
     }
 }
        // Convenience API: generates garbage, do not use when performance matters.
        static public string[] FromVtArray(VtTokenArray input)
        {
            var output = UsdIo.ArrayAllocator.Malloc <string>(input.size());

            FromVtArray(input, ref output);
            return(output);
        }
Exemple #6
0
 public VtValue(VtTokenArray obj) : this(UsdCsPINVOKE.new_VtValue__SWIG_39(VtTokenArray.getCPtr(obj)), true)
 {
     if (UsdCsPINVOKE.SWIGPendingException.Pending)
     {
         throw UsdCsPINVOKE.SWIGPendingException.Retrieve();
     }
 }
 public void swap(VtTokenArray other)
 {
     UsdCsPINVOKE.VtTokenArray_swap(swigCPtr, VtTokenArray.getCPtr(other));
     if (UsdCsPINVOKE.SWIGPendingException.Pending)
     {
         throw UsdCsPINVOKE.SWIGPendingException.Retrieve();
     }
 }
 public void SetAllowedTokens(VtTokenArray allowedTokens)
 {
     UsdCsPINVOKE.SdfAttributeSpecHandle_SetAllowedTokens(swigCPtr, VtTokenArray.getCPtr(allowedTokens));
     if (UsdCsPINVOKE.SWIGPendingException.Pending)
     {
         throw UsdCsPINVOKE.SWIGPendingException.Retrieve();
     }
 }
        public static bool Equals(VtTokenArray lhs, VtTokenArray rhs)
        {
            bool ret = UsdCsPINVOKE.VtTokenArray_Equals(VtTokenArray.getCPtr(lhs), VtTokenArray.getCPtr(rhs));

            if (UsdCsPINVOKE.SWIGPendingException.Pending)
            {
                throw UsdCsPINVOKE.SWIGPendingException.Retrieve();
            }
            return(ret);
        }
        public bool IsIdentical(VtTokenArray other)
        {
            bool ret = UsdCsPINVOKE.VtTokenArray_IsIdentical(swigCPtr, VtTokenArray.getCPtr(other));

            if (UsdCsPINVOKE.SWIGPendingException.Pending)
            {
                throw UsdCsPINVOKE.SWIGPendingException.Retrieve();
            }
            return(ret);
        }
        // ----------------------------------------------------------------------------------------- //
        // string[], List<string> <--> TokenArray
        // ----------------------------------------------------------------------------------------- //
        static public VtTokenArray ToVtArray(string[] input)
        {
            var output = new VtTokenArray((uint)input.Length);

            // PERFORMANCE: this is super inefficient.
            for (int i = 0; i < input.Length; i++)
            {
                output[i] = new pxr.TfToken(input[i]);
            }
            return(output);
        }
 static public void FromVtArray(VtTokenArray input, ref string[] output)
 {
     if (output.Length != input.size())
     {
         output = UsdIo.ArrayAllocator.Malloc <string>(input.size());
     }
     // PERFORMANCE: this is super inefficient.
     for (int i = 0; i < input.size(); i++)
     {
         output[i] = input[i];
     }
 }
Exemple #13
0
        public static void BuildSkeletonBone(string skelPath,
                                             GameObject go,
                                             Matrix4x4 restXform,
                                             VtTokenArray joints,
                                             SceneImportOptions importOptions)
        {
            // Perform change of basis, if needed.
            XformImporter.ImportXform(ref restXform, importOptions);

            // Decompose into TSR.
            Vector3    pos   = Vector3.zero;
            Quaternion rot   = Quaternion.identity;
            Vector3    scale = Vector3.one;

            if (!UnityTypeConverter.Decompose(restXform, out pos, out rot, out scale))
            {
                throw new Exception("Failed to decompose bind transforms for <" + skelPath + ">");
            }

            go.transform.localScale    = scale;
            go.transform.localRotation = rot;
            go.transform.localPosition = pos;

            var cubeDebugName = "usdSkel_restPose_debug_cube";

            if (importOptions.meshOptions.debugShowSkeletonRestPose)
            {
                var cube = go.transform.Find(cubeDebugName);
                if (!cube)
                {
                    cube      = GameObject.CreatePrimitive(PrimitiveType.Cube).transform;
                    cube.name = cubeDebugName;
                    cube.SetParent(go.transform, worldPositionStays: false);
                    cube.localScale = Vector3.one * 2;
                }
            }
            else
            {
                var existing = go.transform.Find(cubeDebugName);
                if (existing)
                {
                    GameObject.DestroyImmediate(existing.gameObject);
                }
            }
        }
        public VtTokenArray GetJointOrder()
        {
            VtTokenArray ret = new VtTokenArray(UsdCsPINVOKE.UsdSkelSkeletonQuery_GetJointOrder(swigCPtr), true);

            return(ret);
        }
Exemple #15
0
        public VtTokenArray GetBlendShapeOrder()
        {
            VtTokenArray ret = new VtTokenArray(UsdCsPINVOKE.UsdSkelAnimQuery_GetBlendShapeOrder(swigCPtr), true);

            return(ret);
        }
        public VtTokenArray GetAllowedTokens()
        {
            VtTokenArray ret = new VtTokenArray(UsdCsPINVOKE.SdfAttributeSpecHandle_GetAllowedTokens(swigCPtr), true);

            return(ret);
        }
Exemple #17
0
 static public List <string> ListFromVtArray(VtTokenArray input)
 {
     return(FromVtArray(input).ToList());
 }
        public static void BuildSkinnedMesh(string meshPath,
                                            string skelPath,
                                            SkeletonSample skeleton,
                                            UsdSkelSkinningQuery skinningQuery,
                                            GameObject go,
                                            PrimMap primMap,
                                            SceneImportOptions options)
        {
            // The mesh renderer must already exist, since hte mesh also must already exist.
            var smr = go.GetComponent <SkinnedMeshRenderer>();

            if (!smr)
            {
                throw new Exception(
                          "Error importing "
                          + meshPath
                          + " SkinnnedMeshRenderer not present on GameObject"
                          );
            }

            // Get and validate the joint weights and indices informations.
            UsdGeomPrimvar jointWeights = skinningQuery.GetJointWeightsPrimvar();
            UsdGeomPrimvar jointIndices = skinningQuery.GetJointIndicesPrimvar();

            if (!jointWeights.IsDefined() || !jointIndices.IsDefined())
            {
                throw new Exception("Joints information (indices and/or weights) are missing for: " + meshPath);
            }

            // TODO: Both indices and weights attributes can be animated. It's not handled yet.
            // TODO: Having something that convert a UsdGeomPrimvar into a PrimvarSample could help simplify this code.
            int[] indices            = IntrinsicTypeConverter.FromVtArray((VtIntArray)jointIndices.GetAttr().Get());
            int   indicesElementSize = jointIndices.GetElementSize();

            pxr.TfToken indicesInterpolation = jointIndices.GetInterpolation();

            if (indices.Length == 0 ||
                indicesElementSize == 0 ||
                indices.Length % indicesElementSize != 0 ||
                !pxr.UsdGeomPrimvar.IsValidInterpolation(indicesInterpolation))
            {
                throw new Exception("Joint indices information are invalid or empty for: " + meshPath);
            }

            float[] weights            = IntrinsicTypeConverter.FromVtArray((VtFloatArray)jointWeights.GetAttr().Get());
            int     weightsElementSize = jointWeights.GetElementSize();

            pxr.TfToken weightsInterpolation = jointWeights.GetInterpolation();

            if (weights.Length == 0 ||
                weightsElementSize == 0 ||
                weights.Length % weightsElementSize != 0 ||
                !pxr.UsdGeomPrimvar.IsValidInterpolation(weightsInterpolation))
            {
                throw new Exception("Joints weights information are invalid or empty for: " + meshPath);
            }

            // Get and validate the local list of joints.
            VtTokenArray jointsAttr = new VtTokenArray();

            skinningQuery.GetJointOrder(jointsAttr);

            // If jointsAttr wasn't define, GetJointOrder return an empty array and FromVtArray as well.
            string[] joints = IntrinsicTypeConverter.FromVtArray(jointsAttr);

            // WARNING: Do not mutate skeleton values.
            string[] skelJoints = skeleton.joints;

            if (joints == null || joints.Length == 0)
            {
                if (skelJoints == null || skelJoints.Length == 0)
                {
                    throw new Exception("Joints array empty: " + meshPath);
                }
                else
                {
                    joints = skelJoints;
                }
            }

            var mesh = smr.sharedMesh;

            // TODO: bind transform attribute can be animated. It's not handled yet.
            Matrix4x4 geomXf = UnityTypeConverter.FromMatrix(skinningQuery.GetGeomBindTransform());

            // If the joints list is a different length than the bind transforms, then this is likely
            // a mesh using a subset of the total bones in the skeleton and the bindTransforms must be
            // reconstructed.
            var bindPoses = skeleton.bindTransforms;

            if (!JointsMatch(skeleton.joints, joints))
            {
                var boneToPose = new Dictionary <string, Matrix4x4>();
                bindPoses = new Matrix4x4[joints.Length];
                for (int i = 0; i < skelJoints.Length; i++)
                {
                    boneToPose[skelJoints[i]] = skeleton.bindTransforms[i];
                }
                for (int i = 0; i < joints.Length; i++)
                {
                    bindPoses[i] = boneToPose[joints[i]];
                }
            }

            // When geomXf is identity, we can take a shortcut and just use the exact skeleton bindPoses.
            if (!ImporterBase.ApproximatelyEqual(geomXf, Matrix4x4.identity))
            {
                // Note that the bind poses were transformed when the skeleton was imported, but the
                // geomBindTransform is per-mesh, so it must be transformed here so it is in the same space
                // as the bind pose.
                XformImporter.ImportXform(ref geomXf, options);

                // Make a copy only if we haven't already copied the bind poses earlier.
                if (bindPoses == skeleton.bindTransforms)
                {
                    var newBindPoses = new Matrix4x4[skeleton.bindTransforms.Length];
                    Array.Copy(bindPoses, newBindPoses, bindPoses.Length);
                    bindPoses = newBindPoses;
                }

                // Concatenate the geometry bind transform with the skeleton bind poses.
                for (int i = 0; i < bindPoses.Length; i++)
                {
                    // The geometry transform should be applied to the points before any other transform,
                    // hence the right hand multiply here.
                    bindPoses[i] = bindPoses[i] * geomXf;
                }
            }
            mesh.bindposes = bindPoses;

            var bones       = new Transform[joints.Length];
            var sdfSkelPath = new SdfPath(skelPath);

            for (int i = 0; i < joints.Length; i++)
            {
                var jointPath = new SdfPath(joints[i]);

                if (joints[i] == "/")
                {
                    jointPath = sdfSkelPath;
                }
                else if (jointPath.IsAbsolutePath())
                {
                    Debug.LogException(new Exception("Unexpected absolute joint path: " + jointPath));
                    jointPath = new SdfPath(joints[i].TrimStart('/'));
                    jointPath = sdfSkelPath.AppendPath(jointPath);
                }
                else
                {
                    jointPath = sdfSkelPath.AppendPath(jointPath);
                }
                var jointGo = primMap[jointPath];
                if (!jointGo)
                {
                    Debug.LogError("Error importing " + meshPath + " "
                                   + "Joint not found: " + joints[i]);
                    continue;
                }
                bones[i] = jointGo.transform;
            }
            smr.bones = bones;

            bool isConstant = weightsInterpolation.GetString() == pxr.UsdGeomTokens.constant;

            // Unity 2019 supports many-bone rigs, older versions of Unity only support four bones.
#if UNITY_2019
            var bonesPerVertex = new NativeArray <byte>(mesh.vertexCount, Allocator.Persistent);
            var boneWeights1   = new NativeArray <BoneWeight1>(mesh.vertexCount * weightsElementSize, Allocator.Persistent);
            for (int i = 0; i < mesh.vertexCount; i++)
            {
                int unityIndex = i * weightsElementSize;
                int usdIndex   = isConstant
                     ? 0
                     : unityIndex;

                bonesPerVertex[i] = (byte)weightsElementSize;

                for (int wi = 0; wi < weightsElementSize; wi++)
                {
                    var bw = boneWeights1[unityIndex + wi];
                    bw.boneIndex = indices[usdIndex + wi];
                    bw.weight    = weights[usdIndex + wi];
                    boneWeights1[unityIndex + wi] = bw;
                }
            }
            // TODO: Investigate if bone weights should be normalized before this line.
            mesh.SetBoneWeights(bonesPerVertex, boneWeights1);
            bonesPerVertex.Dispose();
            boneWeights1.Dispose();
#else
            var boneWeights = new BoneWeight[mesh.vertexCount];
            for (int i = 0; i < boneWeights.Length; i++)
            {
                // When interpolation is constant, the base usdIndex should always be zero.
                // When non-constant, the offset is the index times the number of weights per vertex.
                int usdIndex = isConstant
                     ? 0
                     : i * weightsElementSize;

                var boneWeight = boneWeights[i];

                if (usdIndex >= indices.Length)
                {
                    Debug.Log("UsdIndex out of bounds: " + usdIndex
                              + " indices.Length: " + indices.Length
                              + " boneWeights.Length: " + boneWeights.Length
                              + " mesh: " + meshPath);
                }

                boneWeight.boneIndex0 = indices[usdIndex];
                boneWeight.weight0    = weights[usdIndex];

                if (indicesElementSize >= 2)
                {
                    boneWeight.boneIndex1 = indices[usdIndex + 1];
                    boneWeight.weight1    = weights[usdIndex + 1];
                }
                if (indicesElementSize >= 3)
                {
                    boneWeight.boneIndex2 = indices[usdIndex + 2];
                    boneWeight.weight2    = weights[usdIndex + 2];
                }
                if (indicesElementSize >= 4)
                {
                    boneWeight.boneIndex3 = indices[usdIndex + 3];
                    boneWeight.weight3    = weights[usdIndex + 3];
                }

                // If weights are less than 1, Unity will not automatically renormalize.
                // If weights are greater than 1, Unity will renormalize.
                // Only normalize when less than one to make it easier to diff bone weights which were
                // round-tripped and were being normalized by Unity.
                float sum = boneWeight.weight0 + boneWeight.weight1 + boneWeight.weight2 + boneWeight.weight3;
                if (sum < 1)
                {
                    boneWeight.weight0 /= sum;
                    boneWeight.weight1 /= sum;
                    boneWeight.weight2 /= sum;
                    boneWeight.weight3 /= sum;
                }

                boneWeights[i] = boneWeight;
            }

            mesh.boneWeights = boneWeights;
#endif
        }
        public bool GetBlendShapeOrder(VtTokenArray blendShapes)
        {
            bool ret = UsdCsPINVOKE.UsdSkelSkinningQuery_GetBlendShapeOrder(swigCPtr, VtTokenArray.getCPtr(blendShapes));

            return(ret);
        }
        public bool GetJointOrder(VtTokenArray jointOrder)
        {
            bool ret = UsdCsPINVOKE.UsdSkelSkinningQuery_GetJointOrder(swigCPtr, VtTokenArray.getCPtr(jointOrder));

            return(ret);
        }
 internal static global::System.Runtime.InteropServices.HandleRef getCPtr(VtTokenArray obj)
 {
     return((obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr);
 }