I see people have problems with understanding, how applyTorque works and how to use it, so I decided to make this tutorial with short explanation of these things.
What is torque?
Torque is a physical quantity that tells us how a force will rotate an object. When a force is applied to an object and its origin is not the mass center of the object, usually it will rotate this object. Torque means about which axis the object will rotate, in which direction, and how powerful the rotating force is, see this picture:

To tell in which direction given torque will rotate the object, you can use the right-hand rule. If you orient your right hand in such a way, that your thumb points in the direction of the torque vector, then the rest of your fingers show the direction of movement.

It is really convenient to think of torque like of a force, but for rotational movement. Just like force and acceleration are connected in linear movement by the formula F = m*a, torque and angular acceleration are connected by the formula:
tau = I*epsilon
where tau is the torque, epsilon is the angular acceleration (a quantity that tells you how fast the angular velocity changes), and I is the object's inertia. Inertia tells you how the object "resists" to torque - the bigger the inertia, the greater torque is needed to achieve the same angular acceleration, just like you need more force to accelerate a heavier object in the same way as a lighter object.
There is one subtlety though. The mass is always one number, inertia in the general case is a 3x3 matrix. It can always be expressed by 3 numbers though, which are called the principal moments of inertia, which tell you the inertia for rotating about 3 principal axes - which in GMod are just the object's X, Y and Z local axes. The E:inertia() function returns the principal moments of inertia in a vector (it's in some weird units though, so be careful when trying to use it for some more precise formulas - see Tolyzor's GMod physics guide).
What can it be useful for?
There are a lot of possible applications, I'll present two of them. A simple one - how to make a wheel, and a more complex one - partial angular stabilization without applyAngForce.
Simple example - a wheel

Ok, we have a wheel prop and we want it to rotate like a wheel. The image shows the desired axis of rotation (light grey), the desired direction of rotation (dark grey) and torque needed to get these results (red). Let's say the direction in which torque vector points is the wheel's up direction.
Torque works in local coordinates, so we would need something like:
Code:
Torque = some_number #amount of torque - for example 100
Wheel:applyTorque(Wheel:toLocalAxis(Torque*Wheel:up()))
But this can be simplified a lot. Up direction of a prop is it's local Z axis, so Wheel:toLocalAxis(Torque*Wheel:up()) is the same, as vec(0,0,Torque):
Code:
Torque = some_number #amount of torque - for example 100
Wheel:applyTorque(vec(0,0,Torque))
That's all! The wheel will spin as we wanted it to. But what if we want it to spin in the opposite direction? Well, we just apply the torque in the opposite direction:
Code:
Wheel:applyTorque(-vec(0,0,Torque)) #or vec(0,0,-Torque)
Ok, now something more advanced.
Advanced example - partial stabilization
Well, let's say you have a prop (E:entity) and you want it to face certain direction. Let's say you have target direction TarDir and you want prop's forward vector to point in that direction. That's why I called it partial stabilization too - it only fixes one direction, so the prop will still be able to rotate about one axis.
First, since applyTorque works in local coordinate system, you need to convert desired direction from global to local. Since it is a directional vector, not a position, we will use toLocalAxis:
Code:
TarDirL = E:toLocalAxis(TarDir)
Ok, now you have two vectors: TarDirL and vec(1,0,0) (it's prop's forward vector in local coordinates). Now you want to apply such torque, that will rotate the prop so that its forward direction will point in the same direction as TarDirL. See picture:

Fortunately, there is a function, that takes two vectors and gives a vector perpendicular to both of them. It's the cross product. We want the torque to be proportional to the angle between the two vectors. To get this angle, we will use dot product:
Code:
Angle = acos(TarDirL:dot(vec(1,0,0))/TarDirL:length())
In our case, this can be simplified to:
Code:
Angle = acos(TarDirL:x()/TarDirL:length())
But it's not always true. The general formula is Angle = acos(V1:dot(V2)/(V1:length()*V2:length())).
So, the torque we need, will be:
Code:
Angle = acos(TarDirL:x()/TarDirL:length())
Torque = vec(1,0,0):cross(TarDirL):normalized()*Angle*20*E:inertia()
To get rotation in desired direction we need to get cross product of (current direction X target direction) - do it the other way round, and it will rotate to face the exactly opposite direction. We also normalize it, so that its length is 1, and then multiply by the angle - this way we get a vector perpendicular to both current and target directions, with its length equal to the angle between these vectors.
I also multiplied the torque by inertia, because it is rotational equivalent of mass, and by 20 to make it a bit stronger anyway. If it goes too slow, try increasing this number, if it spazzes - decrease it.
Ok, but if we calculate force for position stabilization, we use roughly Force = TargetPos - Pos - $Pos. The equation I gave is rotational equivalent to Force = TargetPos - Pos. What about the delta term?
Well, we can use angular velocity as the delta term. The function that gives it is E:angVelVector(). So, our torque will look like this:
Code:
Torque = (vec(1,0,0):cross(TarDirL):normalized()*Angle*20 - E:angVelVector()*2)*E:inertia()
Again, 2 is an arbitrary coefficient that can be adjusted to get the best effects.
Now, the final line of code:
Code:
E:applyTorque(Torque)
Ta-dah! That's how you can make a prop face target direction.
Note: Beware, that this code has conditions only for one vector, that is, the forward vector. There are no conditions for up and right vectors, so the prop can still rotate about its forward axis (it's only partial stabilization)! It will hold still because of the angVelVector() term, but its up and right vectors can face any directions when it stops. If you want them to point in some particular direction, just add another piece of code that will take care of one of those vectors.
For rotational calculations, there is also a very useful tool in E2 - quaternions. Check my sig for a tutorial about them. The tutorial also involves an example combining quaternions and applyTorque.
I hope I made the torque thing a bit clearer
Bookmarks