Quaternion bug?

Hey guys:

I believe I found a minor bug. When obtaining the static Quaternion identity you are able to modify it. I’m not sure if this is by design or not, but I’m assuming its the latter.

I hadn’t worked with Java in a bit and I’m fairly new to jMe, so when creating a camera control I wrongly initialized the Quaternion I needed as Quaternion quat = Quaternion.Idenitity;. Needless to say any changes I made to the variable ended up changing the static Quaternion.Identity, and I didn’t find out until another module tried to obtain Quaternion.Identity and gave me the wrong values. It is a minor problem that I solved easy in my code, but I can see how others might find that problematic.

Thought I’d point that out in case it was by accident on the developers’ side.

3 Likes

There is no way for us to fix this. It’s just one of those things you have to be aware of as a developer: don’t modify the premade “constants”.

3 Likes

I’ll note that it also applies to many of the others like Vector3f.

I only found out because my Vector3f.UNIT_Y was suddenly not of unit length which caused unusual problems with the camera lookat method. Pretty much pulled the program apart trying to find how that happened.

3 Likes

This is no totally true. There is always the possibility to extent the desired classes overriding the needed methods to create an immutable version (at least for quaternions where members are all private). Am I wrong?

(I’m not saying it worth it)

1 Like

You are wrong, because vector is final class, so this fact helps JIT to make more aggressive optimizations for it

1 Like

Is the solution to duplicate/clone rather than reference?

2 Likes

It depends on what do you want to do with it, but it’s one of many options to solve this problem.

1 Like

In that case the solution isn’t hard (make it not final). The right answer in this case could be that it doesn’t worth the solution.

1 Like

The solution is providing an accessor method and make the constant private or protected. The accessor would either provide a clone or a new instance of the constant since actually providing the object wouldn’t be much better.

Structured Java programmers don’t usually leave variables public unless they absolutely must. Though in all reality most people don’t follow those rules (including myself most of the time).

It’s a minor thing, though I thought I’d point it out in case others get into a similar problem or to be fixed if the devs get the chance.

1 Like

Or just use
Quaternion quaternion=new Quaternion();
The quaternion will equal the Quaternion.IDENTITY.

The proof for this is here:


What’s the point of keeping a reference to a constant with
Quaternion quat = Quaternion.Idenitity;
when the constant itself is the reference.You should not do this,ever.

1 Like

I think all mathematics classes should be final :wink:

2 Likes

This wouldn’t be a geat solution. Currently, accesing those constants doesn’t create new instances each time (depending on the usage and the environment it wouldn’t be the best to create a new one). Additionally, I think that the meaning of constant isn’t only to provide a value that is “equals” but a one that is “==” (if not, it isn’t a “constant”, at least not OO talking).

Anyway, as many others already said, the correct usage if the instance is meant to change is Just creating a new instance (.clone() or new). The proposed solution wasn’t to fix a bug or an issue engine-side but to avoid missusages dev/user-side.

1 Like

The problem with all of the “solutions” is that they present down sides for EVERYONE but upsides for the few that occasionally make the mistake.

A far easier “solution” is to saddle those folks with an app state that checks every frame to see if the values are still what they are supposed to. Then it penalizes no one except the people making the mistakes.

Though it won’t tell you where you’ve misused them… at least you’d know.

4 Likes

Yep, what pspeed said. This discussion is probably older than some of the participants :wink: If you want jME math with immutable constants use Ardour3D :slight_smile:

2 Likes

I just clone them. Colors, vectors, basically static objects with properties.

ColorRGBA color = ColorRGBA.Red.clone()

As long as you understand why, there is no confusion. Its expected behavior.

2 Likes

I think Damie_M is right.

The only thing is wrong here is : Quaternion quat = Quaternion.Idenitity;.
My explanation is (if I am wrong please correct me):
You want use quat as a variable . But in your command line it is a pointer like thing (there is no pointer in java).
Now quat is pointing to the memory address of the CONSTANCE Quaternion.Idenitity.
When you put new value to quat you put new value to the place store the Quaternion.Idenitity hence change the value of Quaternion.Idenitity.
My suggestion : try Quaternion quat = new Quaternion.。。。。。;
Remember quat is a Quaternion class.
BTW:
I think it is something about instantiation in JAVA and you are familiar with C++?

Finally, I am also not a good programmer,If I AM Wrong please correct me . :blush:

1 Like

Yeah I believe that the best solution is the simplest one that works as intended :sweat_smile:
@Massdrive
Good point but read this article by Oracle for a clearer view.
https://docs.oracle.com/javase/tutorial/essential/concurrency/immutable.html

1 Like

I started to use just new Quaternion() a while ago which seems to result in the same thing but in a safe way :slight_smile:

1 Like

You probably meant “Ardor3D”. I like Renanse’s solution to this problem, I find it smart and I don’t think that not driving the Quaternion class final has a huge impact on the performance. It’s really difficult (but not impossible) to modify Quaternion.IDENTITY by mistake in JogAmp’s Ardor3D Continuation; if you used a cast on it, you would violate the interface.

1 Like

How does one drive the Quaternion class?

I haven’t looked at Ardor3D and I don’t plan to. I have trouble seeing how a “solution” to this “problem” could do anything positive without hurting performance at least a little.

JME is not designed to hold every newb developers hand. It’s designed to be efficient and you have to know your ass from your face most of the time.

2 Likes