Answers for "Eulers from normal into rotation sometimes wrong."
http://answers.unity.com/questions/247041/eulers-from-normal-into-rotation-sometimes-wrong.html
The latest answers for the question "Eulers from normal into rotation sometimes wrong."Answer by Wisearn
http://answers.unity.com/answers/248343/view.html
Thanks @Bunny83 and @syclamoth
It hadnt occured to me that the pivot point was the issue considering my test shape was symmetric but it makes sense now because the pivot point of the model is actually in the center >bottom< of the model (I just had "center" on in the view without realizing it) which explains why it started becoming less and less accurate.
Using temporary parenting with an empty gameobject solved my issue entierly.Fri, 04 May 2012 16:23:12 GMTWisearnAnswer by aldonaletto
http://answers.unity.com/answers/247465/view.html
Opposite to what it may seem (this fooled me at first too), using Rotate is correct: the room is already at some rotation when the collision occurs, thus it should be rotated from that orientation to the new one. The problem is the precision loss in quaternion-euler conversions - and there are two of them each collision. It would be better to just multiply the from-to rotation by the current rotation:
<pre>
function OnCollisionEnter(collisionInfo : Collision) {
newRotation = Quaternion.FromToRotation(collisionInfo.contacts[0].normal, Vector3.up);
Map.transform.rotation *= newRotation;
}
</pre>
But even this approach may accumulate errors, and rotate to weird positions after several collisions. To avoid this, you may try to force the eulerAngles to allowed angles after each rotation.<br>
According to the sapient Wikipedia, this is a rhombi-whatever solid:
<img src="http://upload.wikimedia.org/wikipedia/commons/thumb/1/18/Leonardo_polyhedra.png/220px-Leonardo_polyhedra.png">
From this image (borrowed from wikipedia and Leonardo da Vinci), I suppose the eulerAngles xyz must all be integral multiples of 45 degrees. If this is true, you could try this:
<pre>
function OnCollisionEnter(collisionInfo : Collision) {
var newRot = Quaternion.FromToRotation(collisionInfo.contacts[0].normal, Vector3.up);
newRot = newRot * Map.transform.rotation; // find the new rotation
var euler = newRot.eulerAngles; // get the corresponding euler angles...
euler.x = Mathf.Round(euler.x / 45) * 45; // force them to be multiples of 45
euler.y = Mathf.Round(euler.y / 45) * 45;
euler.z = Mathf.Round(euler.z / 45) * 45;
Map.transform.eulerAngles = euler; // then assign the new absolute rotation
}
</pre>
By the way, this angle fixing could be applied to your approach as well (use Rotate, then fix the eulerAngles).<br>
The room will rotate around its own pivot, as @Bunny83 said, but this may be a desired behaviour in your case. If not, @syclamoth's suggestion is good: place an empty object at the hit point, child the room to it, apply the new rotation to the empty object and assign null to the room's parent.Wed, 02 May 2012 13:55:19 GMTaldonalettoAnswer by Paulius-Liekis
http://answers.unity.com/answers/247417/view.html
Wait, Transform.Rotate is incremental rotation, don't you want to set the rotation instead (transform.localEulerAngles = myQuaternonLook.eulerAngles)?
You don't need conversion to euler angles, you can simply assign quaternions: transform.localRotation = myQuaternonLook;
Having said that I have no opinion about this math in general :) Assuming that ContactPoint.normal is in world space - it makes sense.Wed, 02 May 2012 12:15:46 GMTPaulius-Liekis