[SOLVED] Applying Forces to BetterCharacterControl

Hey Guys,
Propably a beginner mistake but I am trying to apply an impulse to the BCC.
For this I overrode the Class to have access to the underlying RigidBody.

myCharacterControl.getRigidBody().applyImpulse(
res.getContactNormal().setY(0f).mult(1000f), 
res.getContactPoint().subtract(spatial.getLocalTranslation())
);

Here res is the result of a raycast (A shot should push the body slightly backwards), but applyForce(getJumpForce) had no success either.

I tried googling but they talk about the old CharacterControl (being kinematic, which the new one isn’t).
What Do I need to do?

Problem b: I manipulate the view/walk direction (ofcourse) and this sometimes leads to warnings like this:

Okt 06, 2015 3:08:43 PM com.jme3.bullet.control.BetterCharacterControl calculateNewForward
Information: Zero left for left (0.0, 0.0, -0.0), up (-0.0, 1.0, -0.0)

Sometimes it’s Zero forward for (…) but since I removed setGravity(0, -9.81, 0) it seems to be only this one.

The BetterCharacter sets the velocity of the rigidbody directly (apart from the up/down forces) hence all forces are basically reset each cycle. There is a damping parameter that somewhat changes that but it also affects how the steering of the character works in general. I’d suggest integrating the forces you want to apply into the walkdirection.

Well I want a one-time impact, that would be increasing the walkdirection for one frame which seems bad to me.
I can’t use setPhysicsLocation though incase I would set it to something invalid, I guess? (Being thrown against a wall).

The same applies for explosions and such. Could I apply them after the velocity is set maybe? (Directly in BCC?)

Again, forces do affect the character somewhat (try shooting balls at the TestBetterCharacter example character). Just make sure you apply forces on the actual physics tick and not in some random frame. You could also set the damping to zero for some frames.

Setting the location can result in invalid physics, yes, its basically like “beaming” the character - maybe even into a wall as you suggest.

I used to apply them after being called by the inputManager basically. Where would be the correct place to do it? by “hooking” the prePhysicsTick? (Can’t I even use an PhysicsTickListener for that?)

Damping to zero would make the character subject to forces?
mh, I will have to check the Test and maybe wrap my head around the walkDirection thing.

And the other thing? I tried to look into the code but I couldn’t understand where I would destroy the forward/left vector, as I basically only call the setViewDirection.

btw: Switching to native bullet wont improve my performance as the multithread support isn’t used yet (Only the PARALLEL ThreadingType is)?

Edit: I tried it like in BombControl but it simply has no effect :open_mouth:

  1. Yes, PhysicsTick(Listener)
  2. Basically, yes
  3. setWalkDirection sets the velocity that the character moves with
  4. Parallel runs the physics update in parallel to the rendering of the game, syncing the update call so that you can still read (and write) physics on the main runloop thread. You can use physics on a completely separate thread no problem but you won’t be able to use the Control implementations and have to use the PhysicsRigidBody etc. classes directly as well as make your own update loop for the Physics Space.

Great, I could solve it (impulses don’t work however forces do. I don’t really care since an impulse is just the integral of the applied forces).

As for the following:

Okt 07, 2015 4:55:38 PM com.jme3.bullet.control.BetterCharacterControl calculateNewForward
Information: Zero left for left (0.0, 0.0, -0.0), up (-0.0, 1.0, -0.0)

How could I destroy the left vector? It feels like overwriting a read-only vector.
Funny thing is this only happens to my NPCs but their code is nearly identical to the Players’ one.

As for 4) My Problem currently is that in a particular case the physicsFuture.get() takes so long that I have 2 FPS (500ms hence). I will create another thread with a picture in debug mode but basically it’s only a few houses (It’s the static world, not the capsules of the players which drop the fps oddly).

So I was thinking about the future with nice explosives, extended Ragdolls and such. Those being multithreaded (like the physics update itself using multiple threads) would be a great advantage but I guess it will take quite some time until we take on that challenge :slight_smile:

You can make multiple physics spaces for stuff that doesn’t have to collide (e.g. for physics effects, far away places, tops of vehicles, insides of house etc). If you have that long of a physics update lag it looks like you basically overload the physics anyway - threading won’t help much there. If you have multiple physics spaces in parallel mode they’ll all run in parallel as the name suggests.

As for you issue, idk. Maybe check if you indeed didn’t overwrite any of the static Vectors (if Vector3f.UNIT_Y.equals(new Vector3f(0,1,0)) etc.)

1 Like

I also had that error log quite often but I did not notice any misbehavior… These lines are causing it in BetterCharacterControl:

if (newLeft.equals(Vector3f.ZERO)) {
                    if (direction.x != 0) {
                        newLeft.set(direction.y, -direction.x, 0f).normalizeLoca
                    } else {
                        newLeft.set(0f, direction.z, -direction.y).normalizeLocal();
                    }
                    logger.log(Level.INFO, "Zero left for direction {0}, up {1}", new Object[]{direction, worldUpVector});
                }
               newLeftNegate.set(newLeft).negateLocal();
                direction.set(worldUpVector).crossLocal(newLeftNegate).normalizeLocal();
                if (direction.equals(Vector3f.ZERO)) {
                    direction.set(Vector3f.UNIT_Z);
                    logger.log(Level.INFO, "Zero left for left {0}, up {1}", new Object[]{newLeft, worldUpVector});
                }

Shouldn’t these two logs be swapped? If the direction equals Vector3f.ZERO, it logs Zero left for left and if left equals Vector3f.ZERO it logs Zero left for direction? I could be wrong though I just had a quick glance.

Ah. I guess the gravitation direction gets directly changed by 180° at some point in your code - instead of gradually as the doc suggests, resulting in impossible math and this workaround. Should be nothing to worry about.

You are wrong, it says “left is zero for the values direction blah” and “left is zero for the values blah” :smiley: That’s why.
You forgot the most important part though, this only happens if the cross-product of direction and up is zero, which I couldn’t imagine.

left isn’t valid but left isn’t recalculated by Workaround #1 either, because (0, 0, -0) != Vector3f.ZERO (at least I read something like that on the forums, that float comparisons are sign sensitive on the zero).

TBH I didn’t want to change the gravity, it’s also wierd that it only happens for the NPCs (I need to edit something, sometimes I have a positive y coord in setWalkDirection)

Which can happen if one of those vectors is also 0… like if walk direction is 0 I guess.

Yeah that’s what I thought, too. I always do that when I want a NPC to stop for example.

1 Like

JESUS!!

You two are the men! :smiley:
That’s fucking it :slight_smile: Sometimes you need someone from the outside to look at your code :monkey_face:

Now @normen, how are we supposed to stop our character?

if (direction == null) { return; }   

This implies setting it to null but this leads to a NPE because setWalkDirection uses Vector3f.Set.

I guess the BCC is missing some if (direction.equals(Vector3f.ZERO)) check?

And could you guys please look into the “Vector3f.ZERO.equals(new Vector3f(0f, -0f, 0f))” being false?
Atleast on SDK 3.0 this is the case.

You guys in the forums are what makes jme more worth than the commercial ones :smile:

Just set walkDirection to Vector3f(0,0,0) or Vector3f.ZERO to stop the character.

1 Like

0 != -0

…that’s just a fact.