[Solved] Dyn4j physics integration, and Zay-ES

I don’t have the code in front of me right now but I think when I did my dyn4j integration, I extended Body so that I could add the entity reference. So once a frame in my physics system, I just iterated over the list of Body objects and published to their entities.

1 Like

Clever, I guess by extending Body I could dismiss the whole index list I have from entity to Body… But what did you publish (and how) - that’s more my question :slight_smile:

1 Like

Continuing in the same spirit:

In Dyn4j on a Body, I can both do applyImpulse as well as applyForce. I can however, also do setLinear/setAngularVelocity. Any idea how the setLinear/setAngularVelocity

My intuition says that it completely overrides accumulated forces/impulses. Is this also your understanding?

1 Like

How did you get Dyn4j to work with the extended Body class instead of its own ?

1 Like

Body body = new MyBody();
space.add(body)

…or something of that sort. As I recall, it’s your code that instantiates the bodies… not dyn4j. Or at least there is a way to instantiate them.

As to the other… I’ve posted examples already how I publish physics stuff in general. I’ll stop repeating it at this point. Just look at the sim-eth examples.

1 Like

Yes and no.

First: You know the difference between linear and angular velocities?
A force can trigger both, linear and angular velocities. The first one is what you understand as velocity and the latter is rotational speed. Every off-center force leads to an angular velocity.

And with the formular p = m * v it is also obvious what setting the velocity does.

I guess internally they only keep the velocity and then do calculations based on the apply methods, so yes: SetVelocity might override that value, however applyXYZ might increase/decrease that velocity.

1 Like

Ah. I have a stupid question:

If I extend Body to MyBody and set attribute MyBody.EntityId, then pass MyBody to Dyn4j, what happens to the attribute EntityId? Can I simply cast Body to MyBody and then the attribute will be there again ?

You’re right about the instantiating part.

1 Like

If it’s regular java, then sure.
You can always cast a subclass to a superclass.

What you can’t do is the opposite: Body → MyBody.
I said regular java since Attribute sounds like a dyn4j internal thing.

1 Like

If I create class B extending class A, that Dyn4j accepts. On class B I set a field, then pass this class instance to Dyn4j (that only accepts class A), when I then retrieve the same class instance, can I cast it to class B and then have the field value as it was before?

1 Like

No, I guess that would end in a class cast exception.

1 Like

Well you could try that with regular java code, like:

A a = new B();
((B)a).setMyField(0f);

void myMethod(A a) {
((B)a).setMyField(1f);
}

I don’t see a reason why that shouldn’t work. However you can’t call ((B)A), when A is = new A(); , which means you have to ensure that you don’t get a regular Body but only MyBodys.

if a instanceof B can help here.

Just experiment with it.

2 Likes

Typo … SimplePhysics.

You understand incorrectly. I did what pspeed did. I extended body.

I renamed the body class in the simeth-es example to PhysicsBody and had it extend dyn4j body. Then just plugged in the rest of the stuff into the framework in the rest of the example. In the adding and removing portions I put world.add and world.remove, in update I put world.update. In the create body factory I added in the body fixture information.

the only ‘data’ I push to dyn4j is the location of my controller object which I deal with in the ‘shipdriver’ class. I get from dyn4j positions and rotations. I don’t directly do anything else to the physics other than detecting collisions and removing/adding objects based on that.

Mithrin

1 Like

ClassCastException happens when you try to cast an object to something it isn’t.

The only point of casting any object ever is to cast it to some subclass… whether it’s a subclass of Object, or of Spatial, or of Body… as long as it actually IS the class to which you are casting (or a subclass) then it will work just fine.

That’s really basic Java stuff.

Edit: also note that to avoid the constant iterator creation and casting, I probably keep my own SafeArrayList to iterate over the array of MyBody directly… which also bypasses this whole conversation. But knowing how and when to use casting is important.

1 Like

It’s the same I’m doing

Thanks, both of you.

1 Like

Feel free to check

But please note that it’s basically only for collision… physics is sort of disabled.

1 Like

Since we’re talking about 2d, I’d rather use Vector2f and rotateAroundOrigin… there’s no need of Quaternions, and it also saves a few CPU cycles.

1 Like

I would too, but Quaternions is used in the sim-eth-es publishing systems, and once I got down into the bit-level information, I stopped trying to extend with a 2d-version of the sim-eth-es classes, so I chose the easy way out and just added the Quaternion information here, so that hte publishing system works as it would.

I dont mind it, because my 2d game works on different x,y planes in the scene so to speak.

1 Like

Here is how I got dyn4j to work.

    public void syncronizeBody() {
        
        Transform position = this.getTransform();
        
        // setting 3d position based on internal physics 2d position
        pos.set(position.getTranslationX()*GameConstants.PHYSICS_SCALE, position.getTranslationY()*GameConstants.PHYSICS_SCALE, 1.0f);        
        orientation.fromAngles(0, 0, this.getTransform().getRotation());
        
        velocity3d.set(velocity.x, velocity.y, 0.0d);
        
        // Update the bounds since it's easy to do here and helps
        // other things know where the object is for real
        bounds.setCenter(pos);
    }

just for a comparison.

Mithrin

1 Like

I got it working now.

Extended Dyn4j Body in the Sim-eth-es Body, used Mithrins synchronize body instead of integrate, implemented the following instead of update on the ShipDriver:

public void updatePhysicsBody(double stepTime, Body body) {
    Vector3f vec = thrust;
    Vector2 linVel = new Vector2(0, vec.y);
    //Angular since we want the ship to stop rotating right away if player releases the rotate keys        
    body.setAngularVelocity(thrust.x);                  
    double rotation = body.getTransform().getRotation(); //Is the rotation from last frame
    linVel.rotate(rotation);
    body.applyForce(linVel);
}

Thanks for your help.

1 Like