Thexter, have you tried this simplified code?
Does it work the same as the fixed-math code?
Yes, I'm using this code in the electronics for my sixth saber and it seems to be working the same.
This is not actually a rotation. A rotation would be something like:
rotate_x = x * cos - y * sin
rotate_y = x * sin + y * cos
Apologies if this is too detailed. I'm fairly certain that you only need two sentences out of this, but for anyone else reading, and just to have it written out somewhere:
Remember, you're not rotating the actual gyro values. You're rotating the axis against which they're compared. Let's take the case of only looking at gz. Let's create an imaginary basis where positive z points in the direction the saber would rotate if gz were increasing, positive y orthogonal to both positive z and the midline of the saber... or we could just say y is up. Therefore increasing gz rotates us towards this point, and decreasing gz rotates us away from this point. Also, this point is unit length away. It should be noted that this basis is local to the saber, and not global. You never actually get nearer to the point, you just see if you're swinging in that direction.
In this case, our imaginary axis is fixed. We have a small value of let's say 0.3 for the gyro-z, and that's what we use for our hum selection. Gyro-y is basically has no influence. Remember our gyro-total still influences the total volume.
In this next example, we have a large negative gyro-z, so we have around -0.8 for the hum selection.
Now let's rotate this imaginary axis around x. You are correct, the new axis is a rotation of the original:
axis_new_z = z * cos( t ) - y * sin( t )
axis_new_y = z * sin( t ) + y * cos( t )
But remember, our original z and y coordinates were 1 and 0 respectively. So, plugging these back into the equation yields:
axis_new_z = cos( t )
axis_new_y = sin( t )
I thought two of the hums were supposed to be controlled independently by the rotated x/z axis?
I may have been unclear on this, and it's probably also where the confusion in the rotation comes from. I should really have said that I'm making a single non-normalized vector of the two independent axes and comparing them to the swing basis (the newly rotated axis). Each gyro axis still contributes, and it's not an orthonormal contribution because it's not unit length, but I can't really say they're independent.
So, I create a swing vector for the gyro < gz, gy > and see how this vector projects onto the rotated axis. So:
projection = dot( gyrovector, axis_new )
projection = gz * axis_new_z + gy * axis_new_y
In this case, the projection of gyro-total onto the rotated axis is almost the full length of the gyro-total vector.
In this case, the projection of gyro-total is largely onto the negative rotated axis, yielding a large negative value.
In my code, I've actually scaled and clamped the gz and gy, so it's flNormalizedZ and flNormalizedY, but this doesn't mean the vector is normalized, only each individual is within some scaled and clamped range.
Shouldn't this be / 2.0 ? As is, m_flMultiHumAmount can be greater than 1 or less than -1.
You would think so, but you can't actually get values of 2 with the code as written because flAmountY and flAmountZ are 90 degrees out of phase. Remember that our total gyro vector can be greater than 1 in magnitude? Well, the maximum magnitude it can have is sqrt( 2 ), since each component can be a maximum of 1 and you peak when you're swinging 45 degrees between the two gyro axes. To keep the total influence below 1, I divide by this. Think of it as a clipping protection.