GetBindposes
Obtains the bind pose matrices used in skinning calculations.
Read time 4 minutesLast updated 6 days ago
Definition
- Type: Method
- Namespace: UnityEngine
- Assembly: UnityEngine.CoreModule
GetBindposes()
Obtains the bind pose matrices used in skinning calculations.
public NativeArray<Matrix4x4> GetBindposes()
Returns
Type | Description |
|---|---|
| NativeArray<Matrix4x4> | A |
Remarks
Provides access to the mesh's bind pose matrices, which define the inverse transform of each bone in the mesh's initial pose.
The bind pose at each index corresponds to the bone at the same index in SkinnedMeshRenderer.bones. This method provides direct access to the mesh's internal data without creating a copy.
using System.Collections.Generic;using UnityEngine;using Unity.Collections;public class BindPoseProcessor : MonoBehaviour{ // This example assumes the script is attached to a GameObject // with a SkinnedMeshRenderer component. [ContextMenu("Restore Bindpose")] void ProcessBindPoses() { var renderer = GetComponent<SkinnedMeshRenderer>(); if (renderer == null || renderer.sharedMesh == null) return; var bones = renderer.bones; // Get the bind poses from the mesh. This returns a NativeArray for direct, // allocation-free access to the data. NativeArray<Matrix4x4> bindPoses = renderer.sharedMesh.GetBindposes(); if (bones.Length != bindPoses.Length) return; var bindposesDict = new Dictionary<Transform, Matrix4x4>(); for (int i = 0; i < bones.Length; ++i) { bindposesDict.Add(bones[i], bindPoses[i]); } // Iterate over each bone to reset its transform to its original bind pose. foreach (var bone in bones) { var matrix = bindposesDict[bone]; var wMatrix = matrix.inverse; var isRootBone = !bindposesDict.ContainsKey(bone.parent); if (!isRootBone) { if (bone.parent) { // To get the local matrix, multiply the bone's bindpose by the inverse of its parent's bindpose. matrix *= bindposesDict[bone.parent].inverse; } // Invert the resulting matrix to get the final local-to-parent transformation. matrix = matrix.inverse; // Decompose the local matrix to extract and set the bone's local scale and position. bone.localScale = new Vector3( matrix.GetColumn(0).magnitude, matrix.GetColumn(1).magnitude, matrix.GetColumn(2).magnitude ); bone.localPosition = matrix.MultiplyPoint(Vector3.zero); } // Set the bone's world rotation from the inverse bindpose matrix. bone.rotation = wMatrix.rotation; } }}
Additional Resources: Mesh.bindposes, SkinnedMeshRenderer.bones.
GetBindposes(List<Matrix4x4>)
Obtains the bind pose matrices used in skinning calculations.
public void GetBindposes(List<Matrix4x4> bindposes)
Parameters
The list to receive the bind pose matrices.
Remarks
Provides access to the mesh's bind pose matrices, which define the inverse transform of each bone in the mesh's initial pose.
The bind pose at each index corresponds to the bone at the same index in SkinnedMeshRenderer.bones. This method is useful for scenarios where you want to reuse the same list across multiple calls and you want to avoid allocating a new array with every access.
using System.Collections.Generic;using UnityEngine;public class BindPoseProcessor : MonoBehaviour{ // A reusable list to store the bind poses, avoiding repeated memory allocations. private List<Matrix4x4> m_BindPoses = new List<Matrix4x4>(); // This example assumes the script is attached to a GameObject // with a SkinnedMeshRenderer component. [ContextMenu("Restore Bindpose")] void ProcessBindPoses() { var renderer = GetComponent<SkinnedMeshRenderer>(); if (renderer == null || renderer.sharedMesh == null) return; var bones = renderer.bones; // Get the bind poses by populating the pre-existing list. This avoids // allocating a new list for every call. renderer.sharedMesh.GetBindposes(m_BindPoses); if (bones.Length != m_BindPoses.Count) return; var bindposesDict = new Dictionary<Transform, Matrix4x4>(); for (int i = 0; i < bones.Length; ++i) { bindposesDict.Add(bones[i], m_BindPoses[i]); } // Iterate over each bone to reset its transform to its original bind pose. foreach (var bone in bones) { var matrix = bindposesDict[bone]; var wMatrix = matrix.inverse; var isRootBone = !bindposesDict.ContainsKey(bone.parent); if (!isRootBone) { if (bone.parent) { // To get the local matrix, multiply the bone's bindpose by the inverse of its parent's bindpose. matrix *= bindposesDict[bone.parent].inverse; } // Invert the resulting matrix to get the final local-to-parent transformation. matrix = matrix.inverse; // Decompose the local matrix to extract and set the bone's local scale and position. bone.localScale = new Vector3( matrix.GetColumn(0).magnitude, matrix.GetColumn(1).magnitude, matrix.GetColumn(2).magnitude ); bone.localPosition = matrix.MultiplyPoint(Vector3.zero); } // Set the bone's world rotation from the inverse bindpose matrix. bone.rotation = wMatrix.rotation; } }}
Additional Resources: Mesh.bindposes, SkinnedMeshRenderer.bones.