Currently, I'm looking in the setup of one of our Spine rigs which needs clippings. Because the rig is fairly complex, setting up clipping is extremely expensive, so I've been looking into trying to split up rig using a SkeletonRenderSeperator.
When I import the rig into Unity, everything works as is, however the moment I setup a SkeletonRenderSeperator, even with no separation, clipping breaks.
I've spent time looking into the unity sdk to figure out why this is happening and it looks like the code isn't going through any clipping calculations at all.
public void RenderParts (ExposedList<SubmeshInstruction> instructions, int startSubmesh, int endSubmesh) {
LazyIntialize();
// STEP 1: Create instruction
var smartMesh = buffers.GetNextMesh();
currentInstructions.SetWithSubset(instructions, startSubmesh, endSubmesh);
bool updateTriangles = SkeletonRendererInstruction.GeometryNotEqual(currentInstructions, smartMesh.instructionUsed);
// STEP 2: Generate mesh buffers.
var currentInstructionsSubmeshesItems = currentInstructions.submeshInstructions.Items;
meshGenerator.Begin();
if (currentInstructions.hasActiveClipping) {
for (int i = 0; i < currentInstructions.submeshInstructions.Count; i++)
meshGenerator.AddSubmesh(currentInstructionsSubmeshesItems[i], updateTriangles);
} else {
meshGenerator.BuildMeshWithArrays(currentInstructions, updateTriangles);
}
...
When it runs through the single render code, currentInstructions.hasActiveClipping is true and it runs clipping. However here currentInstructions.hasActiveClipping is always false.
That is because the render instruction is built rather than passed in but for when its being built.
public void SetWithSubset (ExposedList<SubmeshInstruction> instructions, int startSubmesh, int endSubmesh) {
#if SPINE_TRIANGLECHECK
int runningVertexCount = 0;
#endif
var submeshes = this.submeshInstructions;
submeshes.Clear(false);
int submeshCount = endSubmesh - startSubmesh;
submeshes.Resize(submeshCount);
var submeshesItems = submeshes.Items;
var instructionsItems = instructions.Items;
for (int i = 0; i < submeshCount; i++) {
var instruction = instructionsItems[startSubmesh + i];
submeshesItems[i] = instruction;
#if SPINE_TRIANGLECHECK
this.hasActiveClipping = instruction.hasClipping;
submeshesItems[i].rawFirstVertexIndex = runningVertexCount; // Ensure current instructions have correct cached values.
runningVertexCount += instruction.rawVertexCount; // vertexCount will also be used for the rest of this method.
#endif
}
...
The clipping happens only if the last instruction has clipping. Why is this the case instead of checking if any of the instructions have clipping?
Just as a follow up, I do think this is a potential issue with the Spine Unity SDK when separating meshes.
this.hasActiveClipping = instruction.hasClipping;
should be
this.hasActiveClipping |= instruction.hasClipping;