Havok initialization question

Havok initialization question

f_aichele's picture

Hello!

I'm running into a problem when trying to initialize multi-threading (code taken directly from the standalone console demo).

When my program reaches the line
multithreadingUtil = new hkpMultithreadingUtil(info);

an assertion occurs at
DebugUtilMultithreadingCheckhkMultiThreadCheck.cpp, line 177

saying

MarkForRead MarkForWrite missing. Make sure HK_DEBUG_MULTI_THREADING is defined if mixing release and debug libs. See hkMultiThreadingCheck.h for more info.

I'm linking against the libraries from the "debug_multithreaded_dll" directory under "Libs..." (Visual Studio 2005 SP1 under Vista SP1).

When I try to set the simulation type to SIMULATION_TYPE_DISCRETE (single-threaded; would suffice for me for testing Havok), commenting out the initialization for the hkpMultithreadingUtil instance, the program starts correctly, but as soon as I start a simulation (calling stepAdvance(), the only function from hkpWorld that I found for advancing the simulation step apart from the multithreading variety with startStepWorld et al.), I get another assertion in the style "you can't call this function if the simulation type isn't SIMULATION_TYPE_MULTI_THREADED").

I'm obviously missing something here:

  • What would I have to do to advance the time step under SIMULATION_TYPE_DISCRET?
  • As the alternative, what am I doing wrong to get a multi-threaded simulation running?

A hint for where to look would be appreciated very much.

Thank you!

Regards,
Fabian Aichele

17 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.
havokdaniel's picture

Hi Fabian,

As in the demo, are you calling markForWrite() on your world before setting up your hkpMultithreadingUtil?

Does the same happen when using fulldebug instead of debug?

Have you tried using stepDeltaTime() on your world in order to step it in when using SIMULATION_TYPE_DISCRETE?

Hope this helps.
Daniel

f_aichele's picture

Thank you very much for the tips and your fast reply!

The markForWrite call was missing, that part now works, I can use SIMULATION_TYPE_MULTI_THREADED successfully.
Movement under gravity influence alone works, but now there's the same assertion popping up if I use applyForce on one of the rigid bodies in the simulation.

What is missing here? I surround the calls to startStepWorld and waitForStepWorldFinished with markForWrite and unmarkForWrite (since I use a simple wrapper class structure to encapsulate rigid body objects, not only from Havok, but also from other physics engines I need to compare). I call applyForce from that wrapper class, but only after markForWrite and before unmarkForWrite.

Fabian

jason.turbin's picture

Hi Fabian,

markForRead / markForWrite are a debug only thread safety mechanism. They are designed to warn the user that physics data is being modified in more than one thread at the same time.

To use them property you need to call markForRead / markForWrite each time you read or write to physics data. So for example, if you were going to apply a force to a rigid body you would need to call:

body->markForWrite();
body->applyForce();
body->unmarkForWrite();

Since they are debug calls they compile away in release (empty definitions) and in cure no runtime cost. That being said they add a lot to your code. If you know for a fact that you will not be modifying physics data from multiple threads (except for Havok worker threads) then you can disable these checks by calling hkpWorld::setMultithreadedAccessChecking(MT_ACCESS_CHECKING_DISABLED). Note however that if you do start operating on physics data in multiple threads you will not get warnings if you accidentally overwrite data.

If you are implementing a wrapper for Havok i highly recommend that you add in the markForRead / markForWrite checks because you can hide them behind the interface.

Does this help?

Thanks,
Jason



f_aichele's picture

Yes, that does help, thanks very much!

I hadn't seen that there's also a per-body read/write locking; I can include these calls in my (simple) wrapper classes, so that's no problem.

The basic object manipulations now work for me (setting position/orientation, applying forces), but there's another question concerning how to set material properties correctly:

I can set the restitution and friction coefficient for each rigid body, but there's also a separate class hkpMaterial. How/where do I use that one? Do I have to set up material interactions between individual pairs of materials separately?

Thank you!

Regards,
Fabian Aichele

havokdaniel's picture

Hey Fabian,

Check out the Mesh Material Demo and let me know if you have any questions:

Physics->Api->Collide->Shapes->Mesh Material

Daniel

f_aichele's picture

Hello!

I looked at the example you mentioned, but there's still a few questions remaining on how exactly I can specify material properties for bodies in Havok. The MeshMaterial sample doesn't exactly do what I was searching for, or I haven't found out how this is done with Havok. It seems that I have to subclass hkpMeshMaterial to do anything useful with it, but I'm not dealing with more sophisticated shapes (meshes) yet.

  • The only places I found so far concerning surface material properties are two members of the hkpRigidBody class, namely m_friction and m_restitution. These can be set per object.
  • There's a hkpMaterial class, which also has these two properties. From other engines I'm currently testing, I know that these also have dedicated material property classes, but in addition there's usually a "central storage" for material properties where I can add/remove material properties and retrieve these (for example, by an integer ID), which in turn is set as material index for a rigid body. How does Havok handle this? Or can I only set friction and restitution coefficients per body? What is the purpose of the hkpMaterial class in that case?

Thank you!

Regards,
Fabian Aichele

havokdaniel's picture

Hi Fabian,

What exactly is it that you'd like to do with materials?

Thanks,
Daniel

f_aichele's picture

Hello!

Currently, I'm only experimenting with common primitive rigid body shapes supported by most (if not all) physics engines commonly available, that is box, sphere and capsule shapes.
My current problem is that I don't know if I need a specialized material class to manipulate the material properties of objects simulated by Havok.
I have seen each hkpRigidBody has a friction and restitution coefficient that I can set before adding it via addEntity to the active simulation.
So: Are there any other possibilities apart from the friction and restitution coefficient to influence material properties directly via the hkpRigidBody class; and what exactly can/could I achieve with the hkpMaterial class?

Thank you!

Fabian Aichele

havokdaniel's picture

Hi Fabian,

hkpRigidBody has a hkpMaterial so when you directly set the friction/restitution of an hkpRigidBody, you're actually using the hkpMaterial class.

That's it's primary use and you're already using it :-)

Daniel

f_aichele's picture

Hello!

OK, I see the material management with Havok is simpler than I thought it to be ;-).

Yet another question arising: When I step my simulations for over more than about 90 seconds, the visualization animation suddenly "freezes", indicating that there are no more position/orientation updates are received from Havok itself; Havok is the only engine I experience that with. What could be a possible cause?

I want to say thank you a lot again for your patient and precise answers to my (probably sometimes trivial) questions concerning Havok; you helped me understand quite few things a lot better.

With best regards,
Fabian Aichele

havokdaniel's picture

Hi Fabian,

Does this mean that the transforms of all rigid bodies before and after stepWorld() are the same?

Daniel

f_aichele's picture

Hello!

That is the case; I use OpenSceneGraph for visualizing the simulation results, and in some simulation runs with Havok (interestingly by far not all runs end with "freezing"), after about 60-90 seconds, movements of rigid bodies that haven't come to a rest by then suddenly stop.

I use the multithreaded simulation type for Havok, stepping the simulation by calling
resetThreadTokens, startStepWorld and waitForStepWorldFinished.

Thank you!

Fabian Aichele

havokdaniel's picture

Hi Fabian,

Could you connect to your simulation with the VDB, turn on the Simulation Islands viewer, and double-check that they are still active for rigid bodies which have stopped moving?

Thanks,
Daniel

f_aichele's picture

Hello!

I haven't looked at the VDB at all yet, so I can't even tell if I could use it to connect to my own program. Anyway, this problem has disappeared, and even longer runs (several minutes) don't freeze any more; though I don't know what is the exact cause for that either.

But yet another question arose: Applying forces to rigid bodies that are connected via a prismatic, limited hinge or ragdoll constraint makes movements of the connected bodies extremely "unstable", and the whole structure starts to shake uncontrollably, even at very small amounts for force components in x/y/z direction and time duration.
Also, for rigid bodies moving without being connected to another body via one of the constraint types named above, the movement resulting from applying a force to them is a lot more "drastic" that with other physics engines I try.
For example, the trajectory of an object accelerated at 45 degree angle upward from the ground matches a parabola, but the distance the object travels is considerably larger than with the engine of a "large graphics card manufacturer".

Is there anything I adjusted the wrong way concerning global engine parameters, dampening factors or anything like that?

Thanks very much!

Fabian


sean.thurston's picture

Hi Fabian,

For the first part of your question about unstable constraints, the first thing to try would be to increase the inertia around any axis that seems a little low. Low inertia means high angular velocity, which increase instability. Another thing to try, depending on the differences in mass between the constrained objects, would be to increase the mass of some of the objects. Tweaking those values should make the constraints more stable. You can see some more tips in the docs at Havok Dynamics/Constraints/About Constraints/Tuning and tweaking constraints/Getting Stable Constraints.

As for the second question, what are the values for your mass, force applied, gravity, etc?

Thanks,
Sean

Developer Support Engineer Havok www.havok.com
f_aichele's picture

Hello!

I reviewed the Havok documentation one more time, reading up on the applyForce/applyTorque functions of the hkRigidBody class, and I found what I most likely did wrong here: The documentation states that I need to pass the

"correct step time-delta related to the simulation's hkStepInfo".



I presume that is the same amount of time that I pass to the startStepWorld function when using the multithread utility?

I failed to do so in my first attempts, instead passing the amount of milliseconds that a force/torque was to remain in effect.
Now the movement of bodies under the influence of applied forces looks a lot more reasonable already.
Concerning values for gravity and masses of rigid bodies: I use the default earth gravity value of -9.81, and calculate the mass of rigid bodies (since I only use boxes, spheres and capsules for the time being) based on their volume and the density of the material assigned to them, passing the value obtained into the computeVolumeMassProperties function in hkInertiaTensorComputer, in turn assigning the results from there to the rigid bodies I create.

Thank you!

Fabian

Login to leave a comment.