# How do I make a cog in Havok?

## How do I make a cog in Havok?

Im trying to find an efficient way to simulate cogs and belts in Havok.

Obviously Im not going to make the individual teeth of each cog collide so what I need is a way to constraint an object to rotate in the opposite direction as another one.

Ideally the final solution would allow a parameter (positive or negative) that defines the amount of rotation of one object relative to the other one so I can create gear ratios. Of course forces need to be propagated through the cogs and the proper power/speed ratio transferred. A bit like what the pulley constraint does for translations.

There is no way I can think of to achieve this with the constraint kit. Ive considered several other schemes but I couldnt find one that would work.

Does anybody have any clue on how this could be done?

7 posts / 0 new
For more complete information about compiler optimizations, see our Optimization Notice.

Hi laurent_coulon,

How you attack this is really going to be based on what your use case is. Are you looking for a physically accurate representation of this kind of system or are you looking for one that kind of looks or acts like this kind of system? I mean there are a few ways to do this. The machine demos under Physics->Use Case->Machine are pretty interesting. They show one way to do these, especially the PinionDemo.

If you want not so physically accurate representations, then you could just use motors and filter out contacts between the gears. Or you could use keyframed objects.

These should be a good starting point.

Let me know what you come up with.

Thanks,
Sean

Developer Support Engineer
Havok
www.havok.com

Actually, the Pinion demo is pretty much an example of what Im trying to avoid. A giant compound shape with all teeth meshed out. The overhead would be way too large for my use, especially if the number of cogs in the level is significant. Ideally the 2 cogs I constrain would not even need to touch physically. They would just turn at a constrained ratio from each other. This way I could simulate very long cog chains by simply constraining both end cogs by the appropriate total ratio of the chain. The intermediate cogs wouldnt even need to be part of the simulation.

Using keyframed objects is not an option either. There is no notion of a master cog that would drive the other one in my application. Both cogs can have torques applied to them, often at the same time. I need forces to propagate through the system in both directions. Anything that would break the symmetry of the system would not work.

A motor sounds like the most promising way to achieve what I have in mind but even after digging deeper in the motor code I dont see any way to get the result I want. Even if I created an angular motor between the 2 cogs there seems to be no way to define what position or velocity it should try to enforce. In 1D angular constraint space, all relative angles for the 2 cogs are valid, the same goes for any relative angular velocity.

Setting a motor target position for the cogs would achieve the opposite result from what I need. It would make both cogs rotate in the same direction. Correcting the target after each step wouldnt work either since there would be no way to know which of the 2 cogs orientation is the valid one, if any.

Setting a motor target velocity would yield the same problem. It would try to force the 2 cogs to keep spinning at the same relative speed, so once again if one cog is set in motion, the motor would make the other cog spin in the same direction instead of the reverse one.

Am I missing something here?

Hi laurent_coulon,

Okay, I think the best option here might be for you to just apply the velocities/forces directly to the cogs.

Ideally the 2 cogs I constrain would not even need to touch physically. They would just turn at a constrained ratio from each other. This way I could simulate very long cog chains by simply constraining both end cogs by the appropriate total ratio of the chain. The intermediate cogs wouldnt even need to be part of the simulation.

Filter out any collisions between the cogs in your system. Probably best to just represent the cogs as discs in the physics simulation and then have better render geometry. Then you can use motors, if you want, to provide the initial velocities for you to grab, but then just apply the forces manually to all the cogs in your system using your gear ratio. This way you can do whatever you like in terms of having the cogs physically interact with objects outside the system or applying gear ratios to the individual cogs.You can do the above pretty easily by doing it this way.

That's probably your best bet. Hope that helps.

Thanks,
Sean

Developer Support Engineer
Havok
www.havok.com

Hi Sean,

Thanks for the info. Being able to pass forces between cogs myself sounds just like what I need, but unless there is a way I can do that at solve time its not going to work. Is there a way I can retrieve forces/impulses applied on an object at solve time and set them on another object?

Here is a simple example of the problem otherwise.

Lets say I have a simple system of 2 cogs with platforms hanging from them by a hinge constraint. As you suggest the cogs are only graphics objects and do not really collide with each other. Because of the static object on the left preventing the left platform from going down, the desired behavior when the dynamic cube lands on the platform on the right would be for the system to remain static. The red circular arrows represent the impulses exchanged by the cogs.

The system is initially stable. During the simulation pass the blue cube on the right collides with the platform and generates a rotational velocity on the right cog. If the forces cannot propagate between cogs during the simulation then the left cog would know nothing of this until after the simulation. I would then transmit the rotational impulse of the right cog to the cog on the left. Notice that the cogs are now already off synch.

During the next simulation pass the left cog attempts to rotate due to the previously received impulse but is blocked by the static object. It therefore receives a counter-impulse to zero out the one given to it by the right cog. Meanwhile the right cog keeps spinning since it knows nothing of the left cogs state.

After the simulation is done the left cog sends an impulse to the right cog to negate the rotation it had generated 2 frames ago. By now not only are the 2 cogs off by 2 frames of motion but the impulse passed by the left cog to the right one is not even enough to stop the motion of the right cog since it has had one more frame of acceleration by now. So the right keep will continue moving down.

The only way I can think of to get a working solution out of this scenario is to have the forces be transmitted at solve time. Thats why I have been looking at constraints or motors for solutions since those act iteratively during the solver.

Is there a way I canderive my own Constraint Atom? What I am trying to do here is very similar to what the pulley Atom does. I just need to do it in rotation instead of translation. I just dont know if the SDK will allow me to create my own Atom and what needs to go in there.

Hi laurent_coulon,

That's a good explanation of what you are trying to do. You seem to have a good grasp of what you need to do.

You can write your own constraint Atom. There is a demo that does this, the CustomAtomConstraintDemo. It shows how to set up a hinge constriaint. You should be able to use a similar technique to build your constraint. You are already pretty familar with the docs in Havok Physics->Havok Dynamics->Constraints.

For the apply your own forces method, you could use collision listeners to determine when and how much force to apply. When the box collides with the platform the force can then be propagated through the system.

You are probably going to write your own Atom. Let me know how that goes.

Thanks,
Sean

Developer Support Engineer
Havok
www.havok.com

Unfortunately there are no Havok demos that show how to create a custom Constraint Atom. The demos only show how to create a constraint using the existing pre-defined atoms.

The pre-defined Atoms do not let me do anything more than the constraint kit did so unless I can create my own atom, I doubta cogcan be achieved this way.

After looking a bit deeper into the Atoms in the SDK it doesnt seem possible to create a custom Constraint Atom. The Atom type is defined by an enum in the hkpConstraintAtom structure so adding a new one is not possible.

I stumbled at some point on the suggestion that the Bridge Atom could be used to create a custom Atom but there is not a single line about it in the docs. Is that actually possible? If so do you have an example of how to define a custom atom?

Im running out of ideas on how to do this.