[SOLVED] Center of rigid body is being displaced?

I am trying to make any collision with the terrain to remove some inertia from objects, like it is an earth terrain, and I am failing miserably :frowning:

I am trying things like (to completely stop movement):

prb.clearForces(); prb.setLinearVelocity(Vector3f.ZERO); prb.setAngularVelocity(Vector3f.ZERO);
and (to lower the movement a bit each collision with the ground):
prbOther.setLinearVelocity (prbOther.getLinearVelocity() .mult(perc)); prbOther.setAngularVelocity(prbOther.getAngularVelocity().mult(perc));
(perc works by reducing the current velocity a bit like being 0.95f of what it was) I wonder if there is a better way to do this?

but thenā€¦ with bullet debug collision wireframe turned on, I can see the physics go crazyā€¦
the collision shapes become displaced related to the spatial centerā€¦ and they begin spinning without collision around the spatial, and the objects begin spinning non-sense-ly ahhh
I wonder how/where I must apply these settings so the physics wont go crazy?

I made it sure to deal with everything attached to the root node and everything physics related, on the rendering thread, by queuing all collisions and taking care of them on the next frame (I created a class that is a copy of PhysicsCollisionEvent to make that object persistent til the queue can be processed).

it seems that this problems also happens when I

  • remove terrain from physics (and physics from terrain)
  • TerrainQuad.adjustHeight()
  • add terrain to physics

Must be something else, setting the velocities like this directly works fine. If you can make a test case for this I can investigate though.

@normen
mmmā€¦ not that I am doing exactly this but, I found that if we test with this:

bullet.getPhysicsSpace().getGravity(Vector3f.ZERO);

I get the same crazy results (as Vector3f.ZERO gets changed).

So, I think I wrongly coded something similar somewhere else, now to find itā€¦ I think there is some debug way that can catch the line that changes it (or any of the other final ones)

EDIT: thats it! Vector3f.ZERO is getting changed, now to find where it is happeningā€¦ I think I will just Vector3f.ZERO.clone() everywhereā€¦
EDIT: netbeans autofills with these static finals and I overlooked in a few spots! :frowning:

EDIT: I created this validator:

private void dbgMakeSureNothingMessedUp() {
	if(Vector3f.ZERO.length() != 0){
		Problem("Vector3f.ZERO="+Vector3f.ZERO);
	}
	if(!Vector3f.UNIT_X.equals(new Vector3f(1,0,0))){
		Problem("Vector3f.UNIT_X="+Vector3f.UNIT_X);
	}
	if(!Vector3f.UNIT_Y.equals(new Vector3f(0,1,0))){
		Problem("Vector3f.UNIT_Y="+Vector3f.UNIT_Y);
	}
	if(!Vector3f.UNIT_Z.equals(new Vector3f(0,0,1))){
		Problem("Vector3f.UNIT_Z="+Vector3f.UNIT_Z);
	}
	if(!Vector3f.UNIT_XYZ.equals(new Vector3f(1,1,1))){
		Problem("Vector3f.UNIT_XYZ="+Vector3f.UNIT_XYZ);
	}
}

that is to be run only when enabled in debug mode,
just to scare me promptly!
I wonder what other things we could put there to prevent getting scared later? :slight_smile:

Well the gravity direction defines the character up direction so setting it to zero is obviously going to cause issues. Using a character with zero gravity doesnā€™t make sense anyway though, just use a RigidBody if you want to move an object in zero gravity.

Oh, I just got what you saidā€¦ Obviously you shouldnā€™t change Vector3f.ZEROā€¦ Which you do if you get the current gravity value into itā€¦ I think thats obvious?

but that is the problem,
when looking at Vector3f.ZERO, we see it is static final,
butā€¦ we can acutally change its object values x,y,z
I think that is a java limitationā€¦

EDIT: it is obvious, but I did that by mistake and there was no warning and no clue at allā€¦

I was thinking if some check could be made better than the one I created, to make it sure user didnt mess with any important variable out thereā€¦

basically, any variable that is set as final, shouldnt have its inner values changed, may be some reflex could be made to check them all dynamicallyā€¦

Thatā€™s how Java final works. You canā€™t alter the ZERO variable (ie Vector3f.ZERO = new Vector3f) but you can alter its attributes.
So yeah Vector3f.ZERO.x = 3.0f; compile and works fineā€¦but youā€™ll get a lot of issues later.
As a rule of thumb donā€™t alter the constants.

So yeah using a clone of this variable seems safer if you want to modify it.
Also, instead of doing Vector3f.ZERO.clone(), youā€™d better go new Vector3f() because the default value is 0,0,0.

I long wanted to add a small assertion check to the update loop that checks if Vector3f.ZERO is still 0,0,0 Vector3f.UNIT_Z is still 0,0,1 etc. In this case its absolutely unnecessary to use a predefined variable anyway, what did you expect to happen from doing this :?

You mean unnecessary in a sense that, if someone, for any reason, really wants to change the Vector3f.ZERO to something else? Even then, to type it thru auto-completion IDEs feature is actually very useful, and also, we are sure that value is what we want by its variable name.

Also, if an extensive list of critical asserts was added, by you ppl that create the engine, this could be an optionally, dynamically enable-able code. User could set it to check every N seconds also, so it would not cause any encumbering.

And we end users, not completely aware of all intricacies, wouldnt be clueless for like 2 weeks or a month (I cant even remember when that problem beginā€¦). I remember having this same problem long ago too, crazy physics, and years later I fall on the same trap hehe :], now I imagine new comers not understanding that and putting away this cool engine because of this kind of ā€œobviousā€ problems (another case I did was to initialize like: private Vector3f v = Vector3f.ZERO; you see, to me it was easy to mistake like that, I wonder how many ppl fall on this, may be not many that take their time to come to the forum and ask about it).

And If someone still complains it could be encumbering, the asserts could be divided, so each check step would assert only a percent of all critical requirements.

Please? :]

if they actually were constants :> (in the full sense of the word)

for now I will just track all public ā€œfinal variablesā€ (contradiction feeling), and put them all on my assert function so I can keep creative ā€œeffortā€ greater than bug tracking one :slight_smile:

I understand your point of view, but thatā€™s not a JME issue actually.
Itā€™s more a Java coding mistake. Using a constant as an initializer for an object is wrong, not only in JME.
If we take the route of preventing the user to make common programming mistake, Iā€™m afraid itā€™ll be an endless process and will in the end clutter the engine code.

Now assertion is not really invasive and can be disabled/enabled at will, but Iā€™m not sure it will help much the end user. the error might be raised in the render loop, in a complete other part of where the mistake was done.
Even with a clear message Iā€™m not sure if users would get it right away.
Also the user would have to enable assertion, on his own to get the error.

@normen maybe we could re-think the read only object approach but only applied to constants.

1 Like

Weā€™ve been through this, theres still the skeleton code checkers in the svn repo that could check even more things that could go wrong.

Theres literally 1000s of things that you can do as a user to mess up your code, its less than you can do in C++, granted (define TRUE FALSE), we simply canā€™t avoid all of these. You could go getLocalTranslation.set() for example, or call updateGeometricState yourself. All these kinds of things.

As I mention above, theres ways to add code checkers (some things are actually checked by the IDE and get underlined, like getLocalTranslation().set()) to make sure that readonly variables donā€™t get overwritten. The assertion I mentioned is also a possibility. You donā€™t seem to know what they are though, they donā€™t get processed in production code, only when you pass the -ea (enable assertions) parameter to the Java runtime. Assertions are used to avoid exactly this, problems that can crop up during coding but not later when the application is run.

1 Like

cool, I will try the -ea, also the ā€œskeleton code checkersā€ require something to work?

but I just found this: Failed startup - #12 by glaucomardano, they seem actually be a plugin, but may be not updated and may crash; also I guess effort on it may help newcomers to java and to JME but will make no diff to skilled users; therefore other priorities may come before updating it I guess :>, but would be interesting to see it working as my approach is just target public final fields, and I will miss everything I have absolutely no idea that may break (for ex.: despite I use quaternions a lot, I still dont really understand how they work; and so onā€¦)

anyway, I just did a simple list with object references and cloned ones, and I was checking (one object per frame) the ref against the cloned one with equals(), fun to code and relieving to see it working :), I will keep it active as I can use for my own final fields and with other libs too :smile:

Youā€™re mixing up several things here.

The code checkers I am talking about are just skeletons, theyā€™re not working code (yet). They would plug into the compiler and run over the code to check if you overwrote read-only stuff (among other things) and have to be specifically coded for jME.

The code checkers they are talking about are basically things like ā€œfindbugsā€ that check your code for common bugs (like trying to do a == comparison on strings).

Assertions work like this: you put a line assert(checkMyStuff()); in your code and if checkMyStuff doesnā€™t return ā€œtrueā€ it will fail in runtime. The whole line wonā€™t be executed at all if you donā€™t pass -ea to the runtime.

1 Like