I have a question regarding the Havok physics engine. I am trying to create a rope which is hanging on a movable object. You can think of a crane. But I have the problem that the rope doesnt stop straight down from the object above. There is alway someking of angle. I tried changing frictions, etc. and using different constraints (6DoF, BallAndSocket, Distant). Is there someway to tune the precision or something like that?
Thanks for the quick answer. Unfortunately it seems that it still behaves the same way. I tested your adjusted playground. Down below is the result after waiting till nothing moves. Are there maybe other options that could be tweaked?
I used two methods of bypassing object sleep, but also had to apply gravity with applyForce().
Two methods from the forums are: 1) ActivationControl and 2) apply zero force.
You may want to play around to see which method(s) are really necessary. When I did so, only applyForce() gravity seemed necessary.
My biggest find is that these methods donāt seem to apply to the physics engineās gravity (is this a bug in the engine?). So I set the engine gravity to 0.01 (didnāt want to use zero in case that was interpreted as special) and then apply the equivalent force of gravity to the objects and had to do so each physics frame.
Lastly, I applied a linear damping factor so I could test more quickly. You should be able to remove the damping to more closely match your original, but it takes a really long time to settle (5-10 minutes, but it doesnāt REALLY settle completely).
Itās hard to tell if ActivationControl actually makes a difference since it doesnāt appear to work for gravity which means we then applyForce() gravity, which happens to be the other method that the forums suggest will bypass sleep.
I tried implementing the logic into the project. It did not really work out. I created a small version of the part where I tried to make it work in this playground: https://playground.babylonjs.com/#IG2RTD#2
It seems that the applyForce has no effect here. It only uses the engines gravity which is set to -0.01. When I set the engines gravity to -9.81 the box hanging on the āropeā sometimes jumps. Where does this come from?
Could you please have a look on it?
Maybe you can figger out what I am missing.
You can apply an impluse to the box moving along the long box with āaā and ādā on the keyboard.
At a glance, I see the rod/cylinder here has a physics aggregate, whereas the rods in the pendulum example do not. I think that involving the rod in the physics system might be contributing to the unexpected results.
Also, why not use a DistanceConstraint between the box and the box on top of the rod?
It appears to be something with the PrismaticConstraint. Comment that out and things seem to move as expected, but obviously without the constraint. Are there other constraints you can substitute, just to see?
I think I found the problem. The mass of the box seems to have a big influence. I broke down the playground to one fixed box with mass 0 and one swinging box, like the pendulum example. https://playground.babylonjs.com/#IG2RTD#8
At the moment the swinging box has a mass of 200 and it behaves like the -0.01 engines gravity. If you change the mass of the box to 1, it behaves like the pendulum example. I am not sure how to use this information. Might it be a solution to multiply the gravity with the mass?
This is strange. A pendulumās period should be independent of mass, yet your PG shows clearly that in Havok, it is. I canāt figure out how your model of a pendulum differs from a real pendulum. I wrote up a whole thing about you should switch to shape and body instead of aggregates, but the result is the same.
Multiplying the applied force by the objectās mass does indeed make the period independent of mass. It would be interesting to calculate the factor necessary to make the model act like a real pendulum: for angles less than 15 degrees, a āseconds pendulumā is about 1 meter long.
Edit: period = 2 * PI * sqrt (length/g), where g = 9.81 and length is in meters.
I think I misinterpreted the apply force function. I thought it applies gravity/acceleration and not a force (Newton) to the object. To implement our own gravity, we have to apply the same force that the gravity applies to the object. And thats gravity multiplied by the mass(F = m*a). N = kg * m / s^2. That should be 9,81 N per kg. So I think it makes sense that it works out. But I am not sure if the manually force gets applied the same way as from the gravity.
It also appears that setLinearVelocity may not be an equivalent alternative because it canāt apply to a specific point such as center of mass. So to your point, perhaps a generalized applied acceleration equivalent to gravity would be:
// can numInstances be zero?
// either way, handle it with low runtime cost
// It may be prudent to extract mass and CoM into an array of arrays to avoid repeated getMassProperties
// use remainder of gravity not handled by the engine.
// here, engine would be -0.01 so the remainder is -9.8
const num = mesh.physicsBody.numInstances;
if (num == 0) {
var mp = mesh.physicsBody.getMassProperties();
mesh.physicsBody.applyForce( -9.8*mp.mass, mp.centerOfMass)
} else for(var i = 0; i < num; i+=1) {
var mp = mesh.physicsBody.getMassProperties(i);
mesh.physicsBody.applyForce(-9.8*mp.mass, mp.centerOfMass,i)
}
Edit: if CoM is local space and force is world space, will need to convert CoM from local to world coordinates.
Edit2: updated code per first edit and use supplied instance iterate function:
For good measure, here is my attempt to use setLinearVelocity() instead of applyForce(). However, I donāt know if setting velocity directly will override constraints, or if the natural physics (versus using a force) is identical. Currently untested.
Thank you for all your effort. I am testing the approach of setting the gravity manually with applyForce() at the moment. For me it behaves pretty naturally in different use cases.
The approach with the setLinearVelocity() also deserves some testing. I will try to implement and compare it and see if I can spot some differences.
Note the applyFoce code calls getMassProperties() every frame, while the setLinearVelocity code creates a (temporary) Vector3 on every frame. It might be better to create a permanent Vector3 for this so itās not repeatedly creating and garbage collecting that temporary Vector3. Doing that and I think the velocity code is much more efficient, which only matters if it works!
Iām not sure if getMassProperties() returns a new object every call or if it returns the same object each time. Hopefully the same object.
Iāve implemented a ādvyā function and used it in physics observable. It seems to work very well.
However, Iāve set all damping and material friction to zero but the pendulums still slow down. Some constraints have friction options (e.g. 6dof), but distance constraint doesnāt.
I tried both variants. The applyForce() variant works best for me. I have set ā_useDeltaForWorldStepā in the HavokPlugin constructor to false. If I set it to true my rope starts to jump/shiver up and down a bit, mostly if it is nearly not moving. Approximately what happend here Havok Precision - #8 by birnie.
When I use setLinearVelocity() I have the jump/shiver problem with and without ā_useDeltaForWorldStepā, but in a smaller scale.
My rope consists of 3 distance constraints with small spheres in between functioning as connectors. Maybe it has something to do with that.
Regarding the friction I have the same result as you. I tried playing with the friction and damping but was also not able to find out where the friciton is coming from