Skip to main content
formatting
Source Link
ErnieDingo
  • 1.2k
  • 8
  • 15

Im going to quickly describe this, as I have to do similar for billboarding of my particles.

Simply, you have your desired target vector (target - viewer), and you have your viewer direction vector. You want your target vector to have no "Z" component effectively (as you are rotating around the Z axis). I eliminate the Z component and normalise the vector. You then cross the 2 vectors to get your rotation axis, Dot the vectors to be able to determine angle of rotation (Acos if i recall). Create a matrix with the axis and the angle.

vecb here would be your previous direction vector.

 void CalculateBillboardMatrix(Vector3 a_targetDirection, ref Matrix a_billboardMatrix) { Vector3 veca = a_targetDirection; Vector3 vecb = new Vector3(1, 0, 0); // this is always the direction the particle is initially created in. veca.Normalize(); Vector3 axis = Vector3.Cross(veca, vecb); axis.Normalize(); float angle = VectorExt.AngleBetweenVectors(vecb, veca, axis); a_billboardMatrix = Matrix.RotationAxis(axis, angle); } 

This piece works out which direction to rotate the angle.

 static public float AngleBetweenVectors(Vector3 a_direction1, Vector3 a_direction2, Vector3 a_planeNormal) { a_direction1Debug.NormalizeAssert(a_direction1.IsNormalized); a_direction2Debug.NormalizeAssert(a_direction2.IsNormalized); float angle = Vector3.Dot(a_direction1, a_direction2);   angle = (float)Math.Acos(angle); Vector3 cross = Vector3.Cross(a_direction1, a_direction2); cross.Normalize(); if (Vector3.Dot(a_planeNormal, cross) < 0) { // Or > 0 angle = -angle; } return angle; } 

The trick with the second item is to work out the winding, to this, you need to cross prod the axis with the vectors axis. The ordering changes the axis vector, you then Dot this to find out if its positive or negative which tells you the direction you need to rotate.

Im going to quickly describe this, as I have to do similar for billboarding of my particles.

Simply, you have your desired target vector (target - viewer), and you have your viewer direction vector. You want your target vector to have no "Z" component effectively (as you are rotating around the Z axis). I eliminate the Z component and normalise the vector. You then cross the 2 vectors to get your rotation axis, Dot the vectors to be able to determine angle of rotation (Acos if i recall). Create a matrix with the axis and the angle.

vecb here would be your previous direction vector.

 void CalculateBillboardMatrix(Vector3 a_targetDirection, ref Matrix a_billboardMatrix) { Vector3 veca = a_targetDirection; Vector3 vecb = new Vector3(1, 0, 0); // this is always the direction the particle is initially created in. veca.Normalize(); Vector3 axis = Vector3.Cross(veca, vecb); axis.Normalize(); float angle = VectorExt.AngleBetweenVectors(vecb, veca, axis); a_billboardMatrix = Matrix.RotationAxis(axis, angle); } 

This piece works out which direction to rotate the angle.

 static public float AngleBetweenVectors(Vector3 a_direction1, Vector3 a_direction2, Vector3 a_planeNormal) { a_direction1.Normalize(); a_direction2.Normalize(); float angle = Vector3.Dot(a_direction1, a_direction2);   angle = (float)Math.Acos(angle); Vector3 cross = Vector3.Cross(a_direction1, a_direction2); cross.Normalize(); if (Vector3.Dot(a_planeNormal, cross) < 0) { // Or > 0 angle = -angle; } return angle; } 

The trick with the second item is to work out the winding, to this, you need to cross prod the axis with the vectors axis. The ordering changes the axis vector, you then Dot this to find out if its positive or negative which tells you the direction you need to rotate.

Im going to quickly describe this, as I have to do similar for billboarding of my particles.

Simply, you have your desired target vector (target - viewer), and you have your viewer direction vector. You want your target vector to have no "Z" component effectively (as you are rotating around the Z axis). I eliminate the Z component and normalise the vector. You then cross the 2 vectors to get your rotation axis, Dot the vectors to be able to determine angle of rotation (Acos if i recall). Create a matrix with the axis and the angle.

vecb here would be your previous direction vector.

 void CalculateBillboardMatrix(Vector3 a_targetDirection, ref Matrix a_billboardMatrix) { Vector3 veca = a_targetDirection; Vector3 vecb = new Vector3(1, 0, 0); // this is always the direction the particle is initially created in. veca.Normalize(); Vector3 axis = Vector3.Cross(veca, vecb); axis.Normalize(); float angle = VectorExt.AngleBetweenVectors(vecb, veca, axis); a_billboardMatrix = Matrix.RotationAxis(axis, angle); } 

This piece works out which direction to rotate the angle.

 static public float AngleBetweenVectors(Vector3 a_direction1, Vector3 a_direction2, Vector3 a_planeNormal) { Debug.Assert(a_direction1.IsNormalized); Debug.Assert(a_direction2.IsNormalized); float angle = Vector3.Dot(a_direction1, a_direction2); angle = (float)Math.Acos(angle); Vector3 cross = Vector3.Cross(a_direction1, a_direction2); cross.Normalize(); if (Vector3.Dot(a_planeNormal, cross) < 0) { // Or > 0 angle = -angle; } return angle; } 

The trick with the second item is to work out the winding, to this, you need to cross prod the axis with the vectors axis. The ordering changes the axis vector, you then Dot this to find out if its positive or negative which tells you the direction you need to rotate.

Added code samples.
Source Link
ErnieDingo
  • 1.2k
  • 8
  • 15

Im going to quickly describe this, as I have to do similar for billboarding of my particles.

Simply, you have your desired target vector (target - viewer), and you have your viewer direction vector. You want your target vector to have no "Z" component effectively (as you are rotating around the Z axis). I eliminate the Z component and normalise the vector. You then cross the 2 vectors to get your rotation axis, Dot the vectors to be able to determine angle of rotation (Acos if i recall). Create a matrix with the axis and the angle. Hope this is what you are after! Let me know

vecb here would be your previous direction vector.

 void CalculateBillboardMatrix(Vector3 a_targetDirection, ref Matrix a_billboardMatrix) { Vector3 veca = a_targetDirection; Vector3 vecb = new Vector3(1, 0, 0); // this is always the direction the particle is initially created in. veca.Normalize(); Vector3 axis = Vector3.Cross(veca, vecb); axis.Normalize(); float angle = VectorExt.AngleBetweenVectors(vecb, veca, axis); a_billboardMatrix = Matrix.RotationAxis(axis, angle); } 

If itThis piece works out which direction to rotate the angle.

 static public float AngleBetweenVectors(Vector3 a_direction1, Vector3 a_direction2, Vector3 a_planeNormal) { a_direction1.Normalize(); a_direction2.Normalize(); float angle = Vector3.Dot(a_direction1, a_direction2); angle = (float)Math.Acos(angle); Vector3 cross = Vector3.Cross(a_direction1, a_direction2); cross.Normalize(); if (Vector3.Dot(a_planeNormal, cross) < 0) { // Or > 0 angle = -angle; } return angle; } 

The trick with the second item is to work out the winding, I will post my method in c# codeto this, you need to cross prod the axis with the vectors axis. The ordering changes the axis vector, you then Dot this to find out if its positive or negative which tells you the direction you need to rotate.

Im going to quickly describe this, as I have to do similar for billboarding of my particles.

Simply, you have your desired target vector (target - viewer), and you have your viewer direction vector. You want your target vector to have no "Z" component effectively (as you are rotating around the Z axis). I eliminate the Z component and normalise the vector. You then cross the 2 vectors to get your rotation axis, Dot the vectors to be able to determine angle of rotation (Acos if i recall). Create a matrix with the axis and the angle. Hope this is what you are after! Let me know.

If it is, I will post my method in c# code.

Im going to quickly describe this, as I have to do similar for billboarding of my particles.

Simply, you have your desired target vector (target - viewer), and you have your viewer direction vector. You want your target vector to have no "Z" component effectively (as you are rotating around the Z axis). I eliminate the Z component and normalise the vector. You then cross the 2 vectors to get your rotation axis, Dot the vectors to be able to determine angle of rotation (Acos if i recall). Create a matrix with the axis and the angle.

vecb here would be your previous direction vector.

 void CalculateBillboardMatrix(Vector3 a_targetDirection, ref Matrix a_billboardMatrix) { Vector3 veca = a_targetDirection; Vector3 vecb = new Vector3(1, 0, 0); // this is always the direction the particle is initially created in. veca.Normalize(); Vector3 axis = Vector3.Cross(veca, vecb); axis.Normalize(); float angle = VectorExt.AngleBetweenVectors(vecb, veca, axis); a_billboardMatrix = Matrix.RotationAxis(axis, angle); } 

This piece works out which direction to rotate the angle.

 static public float AngleBetweenVectors(Vector3 a_direction1, Vector3 a_direction2, Vector3 a_planeNormal) { a_direction1.Normalize(); a_direction2.Normalize(); float angle = Vector3.Dot(a_direction1, a_direction2); angle = (float)Math.Acos(angle); Vector3 cross = Vector3.Cross(a_direction1, a_direction2); cross.Normalize(); if (Vector3.Dot(a_planeNormal, cross) < 0) { // Or > 0 angle = -angle; } return angle; } 

The trick with the second item is to work out the winding, to this, you need to cross prod the axis with the vectors axis. The ordering changes the axis vector, you then Dot this to find out if its positive or negative which tells you the direction you need to rotate.

Source Link
ErnieDingo
  • 1.2k
  • 8
  • 15

Im going to quickly describe this, as I have to do similar for billboarding of my particles.

Simply, you have your desired target vector (target - viewer), and you have your viewer direction vector. You want your target vector to have no "Z" component effectively (as you are rotating around the Z axis). I eliminate the Z component and normalise the vector. You then cross the 2 vectors to get your rotation axis, Dot the vectors to be able to determine angle of rotation (Acos if i recall). Create a matrix with the axis and the angle. Hope this is what you are after! Let me know.

If it is, I will post my method in c# code.