I need to get the vertices of a skinned mesh as they are deformed… problem is, the SkinnedMeshRenderer component only exposes the sharedMesh, which isn’t updated (it’s the asset itself, not the mesh instance).
Am I missing something?
The MeshFilter component exposes both the mesh and sharedMesh, but from what I see it’s not in synch with the SkinnedMeshRenderer.
I found trace of a SkinnedMeshFilter, which sounds like it would be just what I need, but I fear it’s an obsolete piece of code (doesn’t compile, SkinnedMeshFilter is unknown… I never heard of it before either).
I’d be okay with reinventing the wheel, ie manually calculating the vertices positions using the bones, if anyone knows the algorithm… some sort of barycenter of the bones’ positions balanced by their weights?
I think the skinned mesh data is written to a special write-only portion of memory for performance, or something. I brought this up a while ago but can’t find the thread. At any rate, it’s like how it is for a reason.
especially with the higher end cards and the pure shader engine, its likely not written anywhere outside the GPU RAM, so out of your reach.
it only works if it falls back to CPU animation mode where the data are required to be on RAM (basically only Intel CPU to DVI adapters, that do not have any acceptable hardware vertex transformation performance if any support at all X3100+, the 900 / 950 don’t have it)
Well… that defies my sense of space (which is pretty crappy to start with), but you’re right it works, thanks a bunch!
FWIW, I edited the script above to gizmo normals.
So… which is it? UT, any chance to have a definitive answer on this? (David I know you’re out there, stop hiding ;))
Thanks Aras… so why can’t I get the deformed mesh? (dammit please)
Could you explain what Jon hinted at? and more importantly, will that ever change? (after Windows dammit)
Edit: because right now it kinda works but I seem to have a small offset between the rendered mesh and some vertices I compute, and some normals are way out… plus this reinventing of the wheel is really inelegant, and I like my code pretty.
Because the vertices indeed are directly written into a “dynamic vertex buffer”. That memory usually sits on AGP or PCIe bus, and writing to it is okay, but reading is slow. Possible, but slow.
Will it ever be implemented - probably. What we could do, I guess:
Whenever skinned result is requested, compute skinning at that time. So each reading of the skin would compute the whole result.
Or, the ability to say to the skinned mesh renderer “I’ll need skinned results, keep them around please”. Then it would not skin directly into AGP/PCIe memory, but instead into a temporary buffer. Which then would be copied to AGP/PCIe. And temporary buffer could be returned to your code.
Now, when that will be implemented - good question. I don’t know. If enough people shout “I need it dammit”, then it will be sooner. The problem is that people shout “I need this dammit” for thousand different things, and we have to sort them somehow
I’m not sure if it’s correct, specifically the “deltas” part. Maybe it is, I did not write down the math and see if it matches.
Basically, the skinning is this:
result =
matrices[bone0]*value*weight0 +
// ...
matrices[boneN]*value*weightN;
Where ‘matrices’ would be a matrix array. Each matrix in the array is:
currentBoneMatrix * bindPose
The ‘bind pose’ matrices is nothing more than just an inverse matrix of the bone at mesh export time - i.e. the matrix that transforms from mesh-as-it-is to local space of the bone. Then current bone matrix takes from local space and transforms into world space.
Now, the above skinning code can of course be rewritten as:
here, matrices[bone]*weight just multiplies all components of the matrix by a number. Basically, it’s fine to “blend” the matrices first. Whichever is faster, depends on the situation.
This would actually be useful even if it is slow. For example, you might want to emit particles from the surface of a skinned mesh object to simulate an explosion, disintegration or whatever. I would have found this useful on a couple of occasions.