I’m creating my own scripted implementation of a Skinned Mesh in unity for collision detection. But I’ve run into some problems whenever I update the vertex positions using the update armature function to match the white model, the blue wireframe model which is my custom implementation does match its white counterpart and is in correctly positioned. Updating the armature multiple times without changing the model’s rotation will change the wiresframe’s orientation.
I’m sure I’m doing something wrong with transformation matrix, but I don’t know what.
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
public class MeshArmature : MonoBehaviour
{
public SkinnedMeshRenderer skinnedMesh;
public Mesh mesh;
public BoneWeight[] weights;
public Transform[] bones;
public Transform rootBone;
DynamicMeshCollider meshCollider;
bool manualVolumes;
public Transform player;
// Use this for initialization
public void Start()
{
Setup();
}
public void Setup()
{
skinnedMesh = GetComponentInChildren<SkinnedMeshRenderer>();
mesh = new Mesh();
skinnedMesh.BakeMesh(mesh);
mesh.name = skinnedMesh.sharedMesh.name;
bones = skinnedMesh.bones;
rootBone = skinnedMesh.rootBone;
weights = skinnedMesh.sharedMesh.boneWeights;
meshCollider = GetComponent<DynamicMeshCollider>();
meshCollider.mesh = mesh;
meshCollider.Setup();
}
public void UpdateArmature()
{
List<Vector3> verts = new List<Vector3>();
mesh.GetVertices(verts);
for (int i = 0; i < mesh.vertices.Length; i++)
{
Vector3 vert = new Vector4(verts[i].x, verts[i].y, verts[i].z);
Matrix4x4 trs = Matrix4x4.TRS(bones[weights[i].boneIndex0].position, bones[weights[i].boneIndex0].rotation, bones[weights[i].boneIndex0].localScale);
vert = trs.MultiplyPoint(vert) * weights[i].weight0;
verts[i] = vert;
}
meshCollider.mesh.SetVertices(verts);
}
}
//Render Code For Blue Mesh
public class DMAGizmoDrawer
{
[DrawGizmo(GizmoType.Selected | GizmoType.Active)]
static void DrawGizmo(MeshArmature arm, GizmoType type)
{
Gizmos.color = Color.blue;
if (arm.mesh)
Gizmos.DrawWireMesh(arm.mesh, arm.transform.position);
}
}