Hello,
I’m working with my own custom model format and have already written a parser for it. However, I’m struggling to find documentation on how PlayCanvas expects certain data for loading and animating skinned meshes. Specifically, I’m unsure about:
- What coordinate space PlayCanvas uses for bone and animation matrices?
- How to properly create a skinned mesh and bind animations to it using code (not the editor)?
- Why my mesh gets deformed after binding the skeleton, which suggests an issue with the coordinate space or data being supplied.
- How to debug and visualize the bone structure to ensure my bone data is correct. Is there any helper function to display the bones and check how they look?
I learn faster through examples, so example code demonstrating how to create a mesh, skin it, and add animation would be very helpful for me to understand the process.
Here’s my current code for creating the skinned mesh and adding the skin, but when I add the skin to the mesh, it gets broken. Any advice would be greatly appreciated!
function createSkinnedMeshInstance(
app: pc.Application,
skin: pc.Skin,
boneNodes: pc.GraphNode[],
geo: any,
name: string
): pc.MeshInstance {
const mesh = new pc.Mesh(app.graphicsDevice);
mesh.setPositions(geo.positions.flat());
mesh.setNormals(geo.normals.flat());
mesh.setUvs(0, geo.uvs.flat());
mesh.setIndices(geo.indices);
// Skinning data
const boneIndices: number[] = [];
const boneWeights: number[] = [];
for (const w of geo.weights) {
boneIndices.push(...w.bones);
boneWeights.push(...w.weights);
}
mesh.setVertexStream(pc.SEMANTIC_BLENDINDICES, boneIndices, 4);
mesh.setVertexStream(pc.SEMANTIC_BLENDWEIGHT, boneWeights, 4);
mesh.skin = skin;
mesh.update();
const material = new pc.StandardMaterial();
material.diffuse.set(1, 1, 1);
material.update();
const meshInstance = new pc.MeshInstance(mesh, material, boneNodes[0]);
const skinInstance = new pc.SkinInstance(skin);
skinInstance.bones = boneNodes;
meshInstance.skinInstance = skinInstance;
return meshInstance;
}
Thanks for your help!