Some questions about physics integration/usage

Some questions about physics integration/usage

1. What's the best way to synchronize visual objects with physics? I haven't been able to find anything specific in the docs about this.
Currently I'm doing this just after stepping the physics world:

const hkArray& activeIslands = mPhysicsWorld->getActiveSimulationIslands();
for (int i = 0; i < activeIslands.getSize(); ++i)
{
	const hkArray& entities = activeIslands[i]->getEntities();
	for (int j = 0; j < entities.getSize(); ++j)
	{
		hkpRigidBody* rigidBody = hkpGetRigidBody(entities[j]->getCollidable());
		if (rigidBody != nullptr)
		{
			//sync code here
		}
	}
}

This seems to work flawlessly, but I figured it wouldn't hurt to know if there's a better way.

2. Is there a way to get information about the current state of a world, such as number of active rigid bodies, number of contact points, and so on?

3. I've tried to create some wireframe versions of collision shapes for debugging purposes, but it doesn't seem to work very well. For boxes it works perfectly, but for any other shape it simply does nothing.
I've tried doing the following:

hkSphere sphere(hkVector4::getZero(), 0.5f);
hkDisplaySphere displaySphere(sphere, 10, 10);
displaySphere.buildGeometry();
hkArray lines;
displaySphere.getWireframeGeometry(lines, hkContainerHeapAllocator().get(&lines));
//lines is empty

hkVector4 halfExtents; halfExtents.setAll(0.5f);
hkDisplayBox displayBox(halfExtents);
displayBox.buildGeometry();
hkArray lines;
displayBox.getWireframeGeometry(lines, hkContainerHeapAllocator().get(&lines));
//lines contains a wireframe box

After calling build, the display objects do contain seemingly valid hkGeometry objects (with a bunch of vertices and triangles), but wireframe is not generated (except for by hkDisplayBox).
I've tried removing every HK_EXCLUDE_LIBRARY_... define, but that made no difference.
Am I doing something wrong, or do these functions simply not work?

4. Is it possible to be alerted when new versions of Havok is available for download? Checking the Try Havok page every couple of weeks seems like the only solution, but it's not exactly perfect.

5. Is there any particular reason as to why SIMD is disabled by default?
I realize that I cannot enable it without possibly breaking something without recompiling Havok (which I obviously can't do), but I really would like to take advantage of SIMD if at all possible.

PS: Physics/Utilities/CharacterControl/hkpCharacterControl.h (and some other character controller headers) do not compile when HK_DISABLE_OLD_VECTOR4_INTERFACE is defined, as they're using old function names (ie isOk3 instead of isOk<3> in hkpCharacterControl.h, line 81, from hk2011_2_0_r1).

Thanks.

9 posts / novo 0
Último post
Para obter mais informações sobre otimizações de compiladores, consulte Aviso sobre otimizações.

Hi,

1. That's a good approach, although you can just cast the entity to hkpRigidBody* and don't need to check for NULL. Things can get more involved if you do asynchronous stepping though, meaning that you step the physics simulation at a different frequency than you update the display. The docs do have information about that at "Havok Physics/Hello World!/Simulating a Physics World/Stepping the Simulation/Asynchronous Stepping."

2. There aren't any APIs that expose those statistics, but it's possible to find them. You can get the number of active rigid bodies by looping through the active simulation islands, as you do when updating your display. You could track the number of contact points using hkpContactListener (see "Havok Physics/Interacting with the Simulation/Collision Listeners").

3. The others aren't implemented. In case it helps, you can make objects in the demo framework see-through like this:

HK_SET_OBJECT_COLOR( (hkUlong)myCollidablePtr, hkColor::rgbFromChars( r, g, b, a ) );

Where 0 <= r, g, b, a <= 255.

4. There is no mailing list for new releases, sorry.

5. SIMD is reserved for the commercial version of Havok.

Hope that helps!

Max

1. I'm currently using fixed time steps of 16.7 ms, every frame, which starts to look really weird when the frame rate is not at 60 FPS.
Would it make any sense to accumulate real frame time, and only step the physics world once 16.7 or more actual ms has passed rather than stepping it every frame? One problem I can see with this is when a single frame takes longer than 16.7 ms, I'd have to step physics multiple times per frame (on average), which could result in further slowdowns.
I'm guessing this is something asynchronous stepping can help with, but what if the physics step is taking a long time?
If I want to implement a slow-motion effect, is this something which should be done with scaling of timestep size, or is there a better way? I've noticed setTimeFactor for rigid bodies, which works, but I want that applied on the entire world.

2. This is great, thanks! Exactly what I wanted.

3. The reason I wanted to use those functions was to visualize physics directly in my engine, so VDB colors isn't the solution for this problem.
Are all the hkDisplayGeometry subclasses able to generate valid hkGeometry triangles and vertices? If so, I could try using that instead with transparent meshes.

6. What's the best way to create a shape for an object like a bowl, inverted sphere or a half-pipe?
Using a bunch of convex objects as a compoud shape would probably work, but I'm guessing you'd need a lot of them to make it feel smooth. How does a compound shape with something like 10-20 boxes/spheres perform compared to a mesh shape in terms of CPU usage and accuracy?

Hi,

1. a) Yes, it works to accumulate time if you're rendering at a higher frequency than you step physics at. You can also interpolate between physics steps to make it look smoother, the docs page "Havok Physics/Hello World!/Simulating a Physics World/Stepping the Simulation/Asynchronous Stepping" discusses that.

b) If physics starts taking too long to update, you can limit the number of physics steps per frame while maintaining the same step length. This means that the simulation will slow down, since for every 1s of real time the simulation will progress by less than 1s, but you'll have a better framerate than if the number of steps was unlimited. Generally you want to keep the step length constant for stability.

c) The simplest way to implement slow motion is to step the simulation less frequently. For example, if you normally step by 16ms at 60hz, then to slow to half speed step by 16ms at 30hz while continuing to render at the same frequency. The simulation will progress by 1s for every 2s of real time.

Stepping less frequently does make motion appear less smooth, so you might also want to reduce the step length. Changing the step length can reduce stability, but it helps to change it slowly over the course of several frames. So using the same example, you could reduce from 16ms to 8ms over time when entering slow motion, then increase back to 16ms over time when returning to normal speed. setTimeFactor is intended for slow motion on a per-object basis, but it only effectively changes the step length for integration, not for anything else, so it's not as accurate as actually changing the step length.

3. You can get a valid hkGeometry from any of the hkDisplayGeometry subclasses except hkDisplayMesh. It's just the wireframes that are not implemented.

6. I recommend using a mesh. It's simpler, and with boxes you would not be able to do welding, which could cause collision problems. See the docs page "Havok Physics\Hello World!\Creating Physics Objects\Shapes\Landscapes\Welding" for more info about that.

Let me know if you have any other questions.

Max

1. a) I implemented time accumulation, and it seems to work pretty nicely. I'm not sure how to do the interpolation, though.
I'm guessing hkpRigidBody::approxCurrentTransform will not work as I'm not doing asynchronous stepping, and I'm not sure how to get the time for hkpRigidBody::approxTransformAt. Should I use hkpWorld::getCurrentTime and add some number to that value for the frames I do not step physics on, or is there a better way?

b) I don't expect this to become a problem for me, but how is this usually solved if slowdowns absolutely cannot happen (ie in a multiplayer game without server-side physics)?

c) I tried changing the step frequency only, but this lead to very choppy movement when time was scaled down by a lot, as expected.
Changing the step duration, however, seems to have worked very nicely for me. Are there any step sizes that are better than others (like 16.7 ms), or is any non-large fixed step size good?

3. Excellent. This will do just fine.

6. Is using a mesh recommend for dynamic objects too (like a barrel with objects inside)?
I read about welding, very interesting read. Do welding problems occur when tiling box/plane shapes too (with no rotation)?

1. a) Yeah, approxCurrentTransform won't interpolate for you if you aren't using asynchronous stepping, since the world doesn't know what time to interpolate to. approxCurrentTransform() == approxTransformAt(hkpWorld::getCurrentTime). Also beware of using getCurrentTime() because it's reset every 30 seconds for numerical stability. The easiest way to do the interpolation is just to use asynchronous stepping, which lets the world do the time accumulation for you.

b) You would have to be using physics in a way that doesn't affect gameplay and force everything to be synced regardless of how often physics is stepped. So if you have an object that you're representing in the physics world, but its position is determined by info from the server, you would have to set its velocity each frame to move it to the position that the server says it should be in.

c) Any non-larged fixed step size is good. 16.7ms in particular is a good step duration because it gets you one step per display frame at 60hz.

6. a) For dynamic concave objects you should use a collection of hkpConvexVerticesShapes. They're faster than meshes in general, but it's especially important for dynamic objects in order to avoid the possibility of mesh-mesh collisions.

b) Yes, if you make a flat floor out of boxes fixed right next to each other you'll have welding problems.

Max

1. a) I decided to switch to asynchronous stepping, so far everything looks very nice. I tried lowering the physics steps per second all the way down to 10, and even then interpolation was able to make it look smooth, very impressive. Is interpolation so cheap that I should use it for everything I synchronize (only active rigid bodies), or should I only use it on important objects?
If it's expensive, I suppose it could be used with LODing.

d) I'm guessing it's OK to call hkpWorld::setFrameTimeMarker with a variable time step, is this correct?
I'm using a fixed time step for hkpWorld::stepMultithreaded calls, which I'm guessing is mirroring what I was doing before.

e) In the docs, it says that physics data should be transferred to game data in the while loop which is stepping the physics world to the frame time marker.
Are there any benefits from doing this inside the loop rather than after it? Currently I'm synchronizing all physics to game data after the while loop finishes, using hkpRigidBody::approxCurrentTransform, which seems to work just fine. I don't understand the reason for wanting to do this in the loop, which could result in synchronizing physics -> game multiple times per frame.

f) The docs also say that using asynchronous stepping is challenging. If I use callback functions to all physics related code in the game just before stepping the world, would this help reducing the difficulties of using asynchronous stepping?
Are there any common pitfalls or problematic situations that can occur when using asynchronous stepping?

6. Nice to know, thanks!

Hi,1. a) Interpolation is fairly cheap, it's just a couple of vector interpolations and a setRotatedDir. If you have a very large number of objects it might be worth profiling.d) Correct, passing variable lengths into setFrameTimeMarker will not affect stability because it does not change the simulation step length.e) It's not necessary to update the display positions of your objects inside the loop, but you might have other game logic that needs to occur once per simulation step at PSI even if that means multiple times per frame.f) Asynchronous timestepping is just generally more work. You have to do interpolation, deal with more cases (physics running faster than the game, game running faster than physics), possibly accumulate inputs to physics from multiple frames of your game between steps, etc. People do use it though.Max

Back in Havok 710, changing physics step length caused Wheel Constraint to change its Suspension Strength. So I guess there *might* be issues even if step length is being changed smoothly.
Edit: Just as the documentation states.

P.S. a very helpfull topic! And Im happy to see documentation filling with lots of usefull information, Havok is getting better and better! :)

Faça login para deixar um comentário.