• Bugs
  • [Unity] Optimization Pass Bugs

Related Discussions
...

We recently pushed some changes to Spine-Unity that improved performance around 30% (varies from case to case). It's pretty new so I don't think a lot of people have switched to it yet/tested it thoroughly yet so we may find some bugs.

I just switched to it today and I found this.


This happens when I spawn my effects skeletons. These errors are really cryptic because they don't show a stacktrace.
But it says AABB all over the place so I figured it was the mesh bounds. I think the new manually-calculated mesh bounds don't account for the case when there are no visible attachments. Or it could be some other case.

Quick fix for now to anyone who encounters it is to look for this part of the code.:

Vector3 meshBoundsExtents = meshBoundsMax - meshBoundsMin;
Vector3 meshBoundsCenter = meshBoundsMin + meshBoundsExtents * 0.5f;
mesh.bounds = new Bounds(meshBoundsCenter, meshBoundsExtents);

And replace it with this:

// MANUAL MESH BOUNDS CALCULATION
if (vertexIndex > 0) {
   Vector3 meshBoundsExtents = meshBoundsMax - meshBoundsMin;
   Vector3 meshBoundsCenter = meshBoundsMin + meshBoundsExtents * 0.5f;
   mesh.bounds = new Bounds(meshBoundsCenter, meshBoundsExtents);
} else {         
mesh.bounds = new Bounds(Vector3.zero, Vector3.zero); }

EDIT:
SkeletonRenderer's internal meshBoundsMin and meshBoundsMax values are initialized with float.MinValue and float.MaxValue.
Skipping all the calculations in between as in the case of no renderable attachments, the values that come out are float.NegativeInfinity.
But at least I found that that was the problem.

Indeed, it'd fail if there is nothing to calculate the bounds from.
Try adding this code:

meshBoundsMin.x = meshBoundsMin.x == float.MaxValue ? 0f : meshBoundsMin.x;
meshBoundsMin.y = meshBoundsMin.y == float.MaxValue ? 0f : meshBoundsMin.y;
meshBoundsMax.x = meshBoundsMax.x == float.MinValue ? 0f : meshBoundsMax.x;
meshBoundsMax.y = meshBoundsMax.y == float.MinValue ? 0f : meshBoundsMax.y;

Before this line

Vector3 meshBoundsExtents = meshBoundsMax - meshBoundsMin;

That would be one way to fix it, yeah.

Guess I could recommend that as a quick fix.

EDIT:
See OP post for new fix.

Well, I can't think of a better method to fix this, performance-wise. Can probably set a flag when at least one attachment was processed, and then nullify min/max if the flag wasn't set. Or something.

Actually, I'm quite happy this is the only real bug in the optimization pass yet 🙂

The way I figure, Spine being 2D, it's still faster than mesh.RecalculateBounds

Anything less than float.MinValue is float.NegativeInfinity. We just need a big enough value. This is why I usually choose int.MinValue and int.MaxValue even when dealing with floats. Also, in Java Float.MIN_VALUE is not negative, it's the smallest positive value that can be represented by a float. This is a gotcha if you are used to using Integer.MIN_VALUE, which is negative. Floats are crazy.

I've committed a fix, along with a couple micro optimizations. 🙂

Nate a écrit

Anything less than float.MinValue is float.NegativeInfinity. We just need a big enough value. This is why I usually choose int.MinValue and int.MaxValue even when dealing with floats. Also, in Java Float.MIN_VALUE is not negative, it's the smallest positive value that can be represented by a float. This is a gotcha if you are used to using Integer.MIN_VALUE, which is negative. Floats are crazy.

I've committed a fix, along with a couple micro optimizations. 🙂

I think you've misunderstood the issue, it's not about the float representation at all.
Mesh bounds extents are calculated like this:

Vector3 meshBoundsExtents = meshBoundsMax - meshBoundsMin;

So in case there are no attachments, this transforms into:

Vector3 meshBoundsExtents = new Vector3(int.MinValue, int.MinValue, someZExtents) - new Vector3(int.MaxValue, int.MaxValue, someZExtents);

And the resulting vector will have a value int.MinValue - int.MaxValue in X and Y, and that is... -4294967295. Oops. And even if it was int.MinValue - int.MaxValue, the result would be -1.

So really, this is a special case that should be handled separately by setting non-modifed values to 0 instead.

It wasn't a float thing, Nate.
The problem was that the initialized value was useful for the algorithm to find minimums and maximums but it wasn't a proper default value.
So when the algorithm itself didn't run at all (in the case of no renderables), it gave incorrect results.

It had nothing to do with the subtraction operation.

Good extra optimizations though.

Ah, you guys are right of course. My change stops the error but has bad bounds. I don't have a proper test which doesn't help.

After the first for loop in LateUpdate we know if vertexCount == 0 there is nothing to render. We could check that and just skip the rest of the method (after doing anything we might need to do to clear the mesh). Who wants to take a crack at that? 6am, I'm going to bed! 🙂


Pfft, no one?! :p Fixed!

Ah, I've just half-finished the fix, just to see you've already did it 🙂

Is there a good reason to keep using int.MxxValue instead of float.MxxValue here?
Is it an unnecessary cast for a value that's only used for the > or < conditional and not for actual calculations?
Does it get compiled into a literal anyway? And even if it was, it's still not going into +-*/ operations. So what's a good reason for int.MxxValue?

It is compiled into a float literal, so no performance difference here, but yeah, I too can't see any reason to use int.MxxValue.

It doesn't really matters, just a bit cleaner.

I just had changed it and didn't bother changing it back. 🙂 Both work about the same, at least there is no performance difference.

4 mois plus tard

Filing this here: Triangle Missing from Image in Unity Runtime
Opened an issue here: https://github.com/EsotericSoftware/spine-runtimes/issues/481

I've honed in on the problem as a false negative in SkeletonRenderer.CheckIfMustUpdateMeshStructure
Haven't figured out a fix yet.
How do you make it tell the difference between a RegionAttachment and a 4-vertex MeshAttachment?
The false assumption is that you can recycle the same triangle index array and it will work for both.


Just checking in.
More people experiencing flickering issues. Animation Disappearing and/or Blinking

Has this been applied to the repo yet? Flickering and a solution for it

I'll probably have a pass at it but won't be til Monday.