I’m not sure you fully understand the difference between velocity, acceleration and force. If the object doesn’t have any angular drag, once the object has a certain angular velocity it keeps rotating at this speed forever (same with linear velocity and drag). You only need to constantly apply a force if there is any kind of counter force. So if you just want the object to rotate freely, don’t set any drag. For example objects in space would have 0 drag and 0 angular drag. You kick them off and they keep moving / rotating until the end of time (or some external force might hit them, like a collision)
If you do use any angular drag you have an actual counter force which depends on the current velocity. So you would have to constantly accelerate the object to keep it moving. In this case the object will always reach some final angular velocity as long as you apply a constant torque to it. However you will always approach that final angular velocity slowly. The closer you get to that velocity the smaller the change will get. At some point the drag and the acceleration cancel each other so the net force is 0 and the object will keep it’s current speed.
Actually calculating which torque is needed to reach a certain final velocity is a bit tricky as the torque that is required depends not only on the inertia tensor of the object but also on the way how the drag is actually applied.
Here’s basically the solution:
First you have to calculate the required acceleration or velocity change that has to be applied each (physics) frame. How to do that, see my answer over here. The question over there was about linear motion but the same formula applies to angular velocity.
Note that unlike when dealing with linear velocity you can not just multiply the acceleration with the mass of the object to get the actual torque. For this you have to use the inertia tensor. I haven’t checked the answer you already linked in your question but something like that would be required if you really want to use a torque.
Note that the smaller the angular drag value is the slower you will approach the final velocity. If the drag is 0 you can’t apply any force to keep a constant velocity. That’s why using a PID controller would probably be the better choice.
Also keep in mind if the angular drag value is set to a value equal or greater than the physics framerate you can’t rotate the object at all as the drag would cancel 100% of the angular velocity each frame.
If you still want to go the “force route” I’ll explain a bit about the inertia tensor.
A Tensor can be seen as a generalisation of most other mathematical structures. A tensor of order 0 is basically just a single value or scalar. A tensor of order 1 represents a vector. Note that the order doesn’t specify the dimension. A 4D vector or a 100D vector is still a tensor of order 1. A tensor of order 2 is a matrix. Again the dimensions are not specified here. So a 2x2 and a 20x42 matrix are both tensors of order 2.
A rigidbody actually has a 3x3 matrix of inertia to specify the moment of inertia for all 3 primary axis at an arbitrary rotation. However instead of using a 3x3 matrix we actually specify a single Vector3 which specifies the moment of inertia for each principal axis.
However this becomes a problem when the object isn’t nicely aligned with the local coordinate axis. This is where the tensor rotation comes into play. It actually rotates the local coordinate system so the local axis are aligned with the actual object. This is especially necessary when you have compound colliders which are arranged in a not symmetrical way. The physics system has to combine the moments of inertia for all child objects which may also be rotated arbitrarily. The resulting moment of inertia is probably not aligned with the local coordinate axis of the rigidbody.
Now have a look at the two lines:
Quaternion q = transform.rotation * rigidbody.inertiaTensorRotation;
T = q * Vector3.Scale(rigidbody.inertiaTensor, (Quaternion.Inverse(q) * w));
“q” is a rotation that rotates from local “tensor space” to worldspace. If the actual inertia tensor is aligned with the local axis the intertiaTensorRotation would be Quaternion.identity. So in this case “q” just transfers from local to worldspace.
This is what happens in order in the second line:
- we transform “w” from worldspace into “tensor space”. So each axis of our acceleration will be aligned with the principal axes of the inertia tensor. This is done by multiplying the inverse of “q” with “w”
- Now we scale the resulting vector by the inertia tensor component wise using Vector3.Scale
- Finally we just convert the acceleration vector back into worldspace by multiplying q with our scaled vector.