- Home /
Quaternion, Smooth cube rotation using "wheel"
I have this piece of code:
private float curDifference = 0;
private float curApplyDifference = 1;
void onMouseRotateDrag (GameObject curPlanche)
{
float posInitX = initMousePosX;//position du curseur au moment du clic
float posInitY = initMousePosY;
float posCurX = Input.mousePosition.x;//position du curseur pendant le drag
float posCurY = Input.mousePosition.y;
if(posInitX-posCurX<0 || posInitY-posCurY<0){//floor() valeur inf et ceil() valeur sup
curDifference = Mathf.Floor((posCurX-posInitX)/100);
if(curDifference <= 0){
curDifference = Mathf.Floor((posCurY-posInitY)/100);
}
if(curTarget.name == "Red"){ // axe X
if(curDifference != curApplyDifference && curDifference>0){
Quaternion curPlanchInitRot = curPlanche.transform.localRotation;//pos d'origine
Quaternion curPlanchTargetRot = curPlanche.transform.localRotation;//pos d'origine puis modifiée
curPlanchTargetRot[0] += (45*curDifference);
curPlanche.transform.localRotation = Quaternion.Lerp(curPlanchInitRot, curPlanchTargetRot, 1.5f);
Debug.Log(curPlanchInitRot+" "+curPlanchTargetRot);
curApplyDifference = curDifference;
}
}
if(curTarget.name == "Green"){ // axe Y
}
if(curTarget.name == "Blue"){ // axe Z
}
}
}
The function executes when the mouse moves .. (after a click on one of the "wheels" of rotation)
I use a set of three rollers to apply the rotations to the cube (on the model of the tool rotation 3DS Max). I made "debug.log" to the right, left, and the results seems correct but the cube does not move. I continued to search ..
Answer by aldonaletto · Nov 15, 2011 at 08:31 PM
This is wrong:
curPlanchTargetRot[0] += (45*curDifference);
The quaternion components have nothing to do with the familiar x, y and z degree angles we see in the Inspector - these are the eulerAngles:
curPlanchTargetRot.eulerAngles.x += (45*curDifference);
float x = (45*curDifference); curPlanchTargetRot.eulerAngles += new Vector3(x, 0, 0);
thx for eulerAngles, but not yet "smooth" rotation, any idea?
edit: sorry i use C#
The Lerp/Slerp functions are the usual way to smooth things. Change the Lerp line to:
curPlanche.transform.localRotation = Quaternion.Slerp(curPlanche.transform.localRotation, curPlanchTargetRot, 1.5f*Time.deltaTime);
This will work if on$$anonymous$$ouseRotateDrag() is called in Update or in a coroutine.
NOTE: I'm supposing the rest of your script is ok.
I move a piece of code like this in the Update:
if (switchControl == true) {//rotation controler & one of the axe's selectionned if (curTarget.name == "Red" | | curTarget.name == "Green" | | curTarget.name == "Blue") { curPlanche.transform.localRotation Quaternion.Slerp = (curPlanche.transform.localRotation curPlanchTargetRot, 1.5f * Time.deltaTime); } }
In order to rotate the enterFrame, changing variables in a function remained running as soon as the mouse moves (after you click on one of the axes) But all I get is a slight tremor that (emphasis) ended up gently rotate the cube, the function does not run properly. It is one way then the other ..
Using Update is easier - coroutines give a lot of headaches. I think you could change your logic to this:
1- have the current angles in a Vector3 variable:
Vector3 angles = Vector3.zero;
2- change angles.x, angles.y or angles.z according to the mouse:
angles.x = (angles.x + variation) % 360; // keep angle in modulo 360
3- let Slerp follow the angles smoothly in Update:
void Update(){
curPlanchTargetRot = Quaternion.Euler(angles);
curPlanche.transform.localRotation = Quaternion.Slerp(curPlanche.transform.localRotation, curPlanchTargetRot, 1.5f*Time.deltaTime);
}
Answer by Kalu · Nov 18, 2011 at 05:08 PM
I have this code wich rotate a cube:
private float curDifference = 0;
private float differenceY = 0;
private float differenceX = 0;
private float curApplyDifference = 1;
void onMouseRotateDrag (GameObject curPlanche)
{
float posInitX = initMousePosX;//position du curseur au moment du clic
float posInitY = initMousePosY;
float posCurX = Input.mousePosition.x;//position du curseur pendant le drag
float posCurY = Input.mousePosition.y;
differenceX = Mathf.Floor((posCurX-posInitX)/150);
differenceY = Mathf.Floor((posCurY-posInitY)/150);
curDifference = differenceX;
if(Mathf.Abs(curDifference)<Mathf.Abs(differenceY)){//floor() valeur inf et ceil() valeur sup
// curDifference = differenceY;
}
if(curDifference != curApplyDifference){
if(curTarget.name == "RedR"){ // axe X
angles.x = ((-curDifference*90) % 360);
curApplyDifference = curDifference;
}else if(curTarget.name == "GreenR"){ // axe Y
angles.y = ((-curDifference*90) % 360);
curApplyDifference = curDifference;
}else if(curTarget.name == "BlueR"){ // axe Z
angles.z = ((-curDifference*90) % 360);
curApplyDifference = curDifference;
}
posInitX = Input.mousePosition.x;
posInitY = Input.mousePosition.y;
}
}
void Update () {
if(switchControl == true && curTarget != null){
if(curTarget.name == "RedR" || curTarget.name == "GreenR" || curTarget.name == "BlueR"){
Quaternion curPlanchTargetRot = Quaternion.Euler(angles);
curPlanche.transform.rotation = Quaternion.Slerp(curPlanche.transform.rotation, curPlanchTargetRot, 10f*Time.deltaTime);
repereRotation.transform.rotation = Quaternion.Slerp(repereRotation.transform.rotation, curPlanchTargetRot, 10f*Time.deltaTime);
}
}
}
but when I apply a series of rotation, they end up not match with the selected axis. So I run the code by selecting the cube and rotation values in x, y and z exchange in strange ways. While I can see visually a rotation only along the X axis, the values X, Y and Z of rotation are changing ... I don't really understand why ... (i also try with localRotation..) or rather how to fix this problem..
Your answer
Follow this Question
Related Questions
Smooth reset rotation problem 1 Answer
Choppy rotation of character around y-axis 1 Answer
Rotation - Simple Question 0 Answers
smooth look at with offset 0 Answers
Quaternion Rotation Smooth 1 Answer