Having a very strange error when building tutorials Chapter 5 onwards with the Arcball camera on macOS (Catalina 10.15.4 and 10.15.3):
I get a Thread 1: EXC_BAD_ACCESS (code=EXC_I386_GPFLT) in Camera.swift as part of the ArcBall logic. This only pops once the rotation calculation is executed.
Adding print statements in-between those lines fixes this. (can’t post second image in to show; new user)
Ah! I should have tried that. I will reach out to Apple Dev and see if they can advise. It looked like 10.15.4 should have that update but it might be a patch coming later?
I spent most of the day trying to track this down as it just started happening to me also. And I have no idea what I did. Anyway, I made no real progress besides trying a ton of things as you can see from the following code and comments. Maybe you can see a pattern here. I cannot.
override func rotate(delta: float2) {
let sensitivity: Float = 0.005
print(rotation) // does not cause crash
print(delta) // does not cause crash
print(rotation.x) // does not cause crash
print(delta.x) // does not cause crash
rotation.y += sensitivity // does not cause crash
print(rotation.y) // does not cause crash
print(10.0 * sensitivity) // does not cause crash
let temp = 10.0 * sensitivity; print(temp) // does not cause crash
// var temp2 = 10.0 * sensitivity // causes crash at rotation.x += delta.y * sensitivity
// rotation.y = temp // causes crash
// rotation.y += 10.0 * sensitivity // causes crash
// rotation.y += delta.x * sensitivity // causes crash
rotation.x += delta.y * sensitivity // does not cause crash
print(rotation) // does not cause crash
print(rotation.x) // does not cause crash
rotation.x += delta.y * sensitivity // does not cause crash
// temp = rotation.x; print(temp)
// rotation.x = max(-Float.pi/2, min(rotation.x, Float.pi/2)) // causes crash
_viewMatrix = updateViewMatrix()
}
I also tried:
rotation += float3(delta,0) * sensitivity // causes crash
Oh interesting! now the question is if this is a SIMD alignment issue or if the didSet closure is doing some weirdness. I wonder if the ‘didSet’ events are getting tangled?
Unfortunately that method needs to be there to update the view matrix if the code changes the rotation of the camera (rather than the user through gestures).
For example, if you comment out that rotation method and in draw(in:), add a rotation:
timer += 0.005
camera.rotation.y = sin(timer)
Then the camera doesn’t rotate.
If you uncomment that override, that code doesn’t crash until you add
camera.rotation.x = sin(timer)
Then it does crash.
So I think that you’re right, it does seem to be the didSet that’s causing it, but I am loathe to change that method. Setting the entire rotation:
Hello all! I got around it by adding “super.” to the rotation assignments in the rotate function. If anyone has the time and knowhow, I’d appreciate hearing why that’s a better or worse solution than the others referenced here. I’m taking it by the references to this being a bug in Xcode that this should not actually be necessary?
I’ve been thinking about what I meant by “better or worse solution” and I realized what I meant was: I really don’t know what I’m doing and while I can see that my solution works, I’m not certain it doesn’t have side effects. I guess I’m just asking if there’s something I should be aware of that makes it a bad solution - any guidance is appreciated.
I would think that super. is a good solution, because ArcballCamera inherits from Camera, which inherits from Node, which is where rotation is defined. So super points more closely to where the property is held in memory. But that’s guesswork.
However, in Xcode 12, it’s now fixed, and should work fine without using super.