Closed melnikov-s closed 10 years ago
Having trouble figuring this out as the haxe nightlies are having issues with breaking napes code completely in some cases right now, so I can't tell myself if its a probelm in my code, or haxe's :P
Sorry, should have mentioned that I'm using haxe 2.10 release. You should be able to reproduce with that.
With both nape 2.0.3 and 2.0.4
... sadly it seems this issue is effecting even 2.10 release, you can try this yourself and see if you get the same behaviour (haxe 2.10 + nape 2.0.4)
Main.hx:
class Main { static function main() { var b = new nape.phys.Body(); b.shapes.add(new nape.shape.Circle(10)); trace(b.mass *= 10); } }
compiling
haxe -main Main -swf main.swf -lib nape -D NAPE_RELEASE_BUILD
with --no-inline it traces (correctly) pi without --no-inline it traces 0
Yup, traces 0 or pi (with --no-inline) for haxe 2.10 and nape 2.0.4
It'd be great if you could come up with a minimal example (not requiring nape) that shows this behaviour, I've so far failed, and we can pass it to haxe dev team:
I'll see what I can do, but that might be a different issue entirely! I've tried compiling the code in my first post with --no-inline and the bug is still present. Removing the trace fixes the issue.
Now the really weird part is that when I do trace(box.mass *= 2000) (which should be 2048 mass) and compile without --no-inline I get a different outcome, with --no-inline i can reproduce the original bug.
So to clarify, there are 3 cases here:
//Case 1: bug is present with both --no-inline and without.
trace(box.mass);
box.mass = 2048;
//case 2: mass is reported to be 0 and shapes do not appear
trace(box.mass*= 2000);
//Case 3: with --no-inline same as Case 1
trace(box.mass*= 2000);
Okay, I think I've found the bug easily enough now and have made a fix on haxelib for it. Since you're using Haxe I'll not bother with an as3 release for now since no-one else has come across this just now.
On an unrelated note, you'll find that directly setting 'just' the mass like this will make things behave really weirdly anyways since the moment of inertia will still be very small; if you want to set a mass/inertia directly then you're free to do so, but if you simply want to make the object heavier, you should either increase the density of the material, or ensure that you scale up the mass/inertia by the same factor.
I think that the inlining bug in haxe is only in such situations where an implicit call to the getter is supposed to be made, such as in the mass *= _; situation, so hopefully you don't have to use --no-inline !
Thanks for the tip and the quick fix! Cheers.
I figured what haxe is doing wrong and made a test case on the issue page:
Seems this was not a haxe bug after all, haxe does not guarantee order of execution for inlined function parameters.
In this case the problem is that doing body.mass += 10; the 'getter' for mass is invoked after the 'setter' has already began execution and its messing up the invalidation system as the 'setter' is doing something similar to locking a mutex on the body if you will which causes the getter to fail.
There is a workaround that I can make to permit this sort of usage, which is to forcebly assign inline function params to local variables at start of function... which is kind of horrible so I won't implement that 'right' now. I'll likely be using a macro to do it automaticly when the time comes but I must be careful to keep it haxe 2.0 compatible also.
Ehhh, unless someone really needs this done, I'll consider it 'not to be done' task for now.
Seems like the reading of the body.mass value causes side effects in certain situations. In my testing seems to happen only before you set a custom mass value (when the value is pre-computed). From some quick debugging the issue arises because zpp_inner.zip_mass gets set to false when reading the value.
Full code: taken from the simple simulation sample, scroll down to the setUp method and uncomment "scenario 2" to see the bug in action.