-
Notifications
You must be signed in to change notification settings - Fork 93
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Quaternions go over value #3
Comments
Hi JesseLeeuwen, thanks for posting this issue! Does normalizing the value of the quaternion before use fix this issue? |
I tried it but the rotation will vary in speed because of the normalization |
Thanks for the update! I'll start looking into this more closely - can you please give me some information on which tutorial you found the issue in? Is there a particular line in that tutorial you can trace the issue to? Do you have a minimum set of code the exhibits the issue? |
oh it's not from the tutorials its, oeps wrong github project uhm it's about the quaternions in general sorry |
Hey no worries - we'll get it sorted out still. Can you please link to some example code or provide a method to reproduce this? Thanks! |
sure, to test this just call the rotate and Render Func In the beginning there will be not much deformation but it'll slowly increase the more the object rotates. class testObject
{
private Vector3 position;
private Quaternion rotation;
private ShaderProgram shader;
private Texture texture;
private VBO<Vector3> vertices;
private VBO<Vector3> normals;
private VBO<Vector2> uvs;
private VBO<int> indices;
public TestObject(ShaderProgram shader, Texture texture)
{
this.position = Vector3.Zero;
this.rotation = Quaternion.identity;
this.shader = shader;
this.texture = texture;
Vector3[] verts = new Vector3[] {
new Vector3(1, 1, -1), new Vector3(-1, 1, -1), new Vector3(-1, 1, 1), new Vector3(1, 1, 1),
new Vector3(1, -1, 1), new Vector3(-1, -1, 1), new Vector3(-1, -1, -1), new Vector3(1, -1, -1),
new Vector3(1, 1, 1), new Vector3(-1, 1, 1), new Vector3(-1, -1, 1), new Vector3(1, -1, 1),
new Vector3(1, -1, -1), new Vector3(-1, -1, -1), new Vector3(-1, 1, -1), new Vector3(1, 1, -1),
new Vector3(-1, 1, 1), new Vector3(-1, 1, -1), new Vector3(-1, -1, -1), new Vector3(-1, -1, 1),
new Vector3(1, 1, -1), new Vector3(1, 1, 1), new Vector3(1, -1, 1), new Vector3(1, -1, -1)
};
Vector2[] uvs = new Vector2[] {
new Vector2(0.55, 0.55), new Vector2(0.95, 0.55), new Vector2(0.95, 0.95), new Vector2(0.55, 0.95),
new Vector2(0.55, 0.55), new Vector2(0.95, 0.55), new Vector2(0.95, 0.95), new Vector2(0.55, 0.95),
new Vector2(0.55, 0.55), new Vector2(0.95, 0.55), new Vector2(0.95, 0.95), new Vector2(0.55, 0.95),
new Vector2(0.55, 0.55), new Vector2(0.95, 0.55), new Vector2(0.95, 0.95), new Vector2(0.55, 0.95),
new Vector2(0.55, 0.55), new Vector2(0.95, 0.55), new Vector2(0.95, 0.95), new Vector2(0.55, 0.95),
new Vector2(0.55, 0.55), new Vector2(0.95, 0.55), new Vector2(0.95, 0.95), new Vector2(0.55, 0.95)
};
Vector3[] normals = new Vector3[] {
new Vector3(0, 1, 0), new Vector3(0, 1, 0), new Vector3(0, 1, 0), new Vector3(0, 1, 0),
new Vector3(0, -1, 0), new Vector3(0, -1, 0), new Vector3(0, -1, 0), new Vector3(0, -1, 0),
new Vector3(0, 0, 1), new Vector3(0, 0, 1), new Vector3(0, 0, 1), new Vector3(0, 0, 1),
new Vector3(0, 0, -1), new Vector3(0, 0, -1), new Vector3(0, 0, -1), new Vector3(0, 0, -1),
new Vector3(-1, 0, 0), new Vector3(-1, 0, 0), new Vector3(-1, 0, 0), new Vector3(-1, 0, 0),
new Vector3(1, 0, 0), new Vector3(1, 0, 0), new Vector3(1, 0, 0), new Vector3(1, 0, 0)
};
int[] indices = new int[] {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23
};
this.vertices = new VBO<Vector3>(verts);
this.normals = new VBO<Vector3>(normals);
this.uvs = new VBO<Vector2>(uvs);
this.indices = new VBO<int>(indices);
}
public void Rotate(Quaternion )
{
// make rotation quaternion
Quaternion rotate = new Quaternion(rotateAmount.x / 360.0f, rotateAmount.y / 360.0f, rotateAmount.z / 360.0f, 1);
rotation = rotate * rotation;
}
public void Render()
{
Gl.UseProgram(shader.ProgramID);
Gl.BindTexture(texture);
shader["model_matrix"].SetValue(GetModelMatrix());
shader["Color"].SetValue(new Vector3(1,1,1));
shader["enable_lighting"].SetValue(true);
Gl.BindBufferToShaderAttribute(vertices, shader, "vPosition"); // sets vertex position in "vPosition in shader input (vertexPosition in tutorial shader)"
Gl.BindBufferToShaderAttribute(normals, shader, "vNormal"); // sets Normals in "vNormal" in shader input
Gl.BindBufferToShaderAttribute(uvs, shader, "UV"); // sets uvs in "UV" in shader input
Gl.BindBuffer(BufferTarget.ElementArrayBuffer, indices.vboID);
Gl.DrawElements(BeginMode.Quads, indices.Count, DrawElementsType.UnsignedInt, IntPtr.Zero);
Gl.UseProgram(0);
}
private Matrix4 GetModelMatrix()
{
Matrix4 transform = new Matrix4();
// make rotation matrix
Vector3[] mat3 = new Vector3[3] ={
rotation * Vector3.Right,
rotation * Vector3.Up,
rotation * Vector3.Backward
};
transform[0] = new Vector4(mat3[0].x * scale.x, mat3[0].y * scale.y, mat3[0].z * scale.z, 0.0f);
transform[1] = new Vector4(mat3[1].x * scale.x, mat3[1].y * scale.y, mat3[1].z * scale.z, 0.0f);
transform[2] = new Vector4(mat3[2].x * scale.x, mat3[2].y * scale.y, mat3[2].z * scale.z, 0.0f);
transform[3] = new Vector4(position.x, position.y, position.z, 1.0f);
return transform;
}
} |
The quaternion values are calculated a bit differently than you are using in your demo code. x, y, z are not the x, y, z rotation angles. Instead you must calculate the x, y, z and w components using a conversion from axis/angle into quaternion space. /// <summary>
/// Creates an orientation Quaternion using an angle and arbitrary axis.
/// </summary>
public static Quaternion FromAngleAxis(float Angle, Vector3 Axis)
{
if (Axis.SquaredLength == 0.0f)
return Identity;
return new Quaternion(new Vector4(Axis.Normalize() * (float)Math.Sin(Angle * 0.5f), (float)Math.Cos(Angle * 0.5f)));
} The opengl4csharp library builds a lot of this functionality in (it also has methods to convert a Quaternion to a Matrix4 automatically). Here's an example replacement for your rotate method. Simply increase 'angle': public void Rotate(float dt)
{
angle += 1f * dt;
rotation = Quaternion.FromAngleAxis(angle, new Vector3(0.5, 0.2, 0.8).Normalize());
} Here's an example of using the built-in method for converting a Quaternion to a Matrix4: private Matrix4 GetModelMatrix()
{
Matrix4 transform = rotation.Matrix4;
transform[0] = transform[0] * new Vector4(scale, 0);
transform[1] = transform[1] * new Vector4(scale, 0);
transform[2] = transform[2] * new Vector4(scale, 0);
transform[3] = new Vector4(position.x, position.y, position.z, 1.0f);
return transform;
} Let me know if this helps! You can read more about conversion between axis/angle and quaterion here: http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/ Cheers, Giawa |
thanks!!! Giawa, it works !!!!!! |
Glad to hear it! I'm closing the issue now as resolved, but please feel free to open another issue if you run into a problem. Happy coding! |
the values in Quaternion class go over the max value resulting in scaling of the object
The text was updated successfully, but these errors were encountered: