# My Quaternion based Camera Zooms by itself?

## Recommended Posts

Waaayoff    952
It rotates fine around the y axis, but when rotated around the x axis, while the rotation is successful, the camera moves in on the scene "zooms". Eventually it stops zooming and rotates fine. Here's the Code: Vector Math Operations:
namespace _Math
{
Quaternion VectorToQuat(D3DXVECTOR3* v)
{
Quaternion Quat;
Quat.x = v->x;
Quat.y = v->y;
Quat.z = v->z;
Quat.w = 0;

return Quat;
}

D3DXVECTOR3 NormalizeVector(D3DXVECTOR3* Vector)
{
double Length = (Vector->x*Vector->x + Vector->y*Vector->y + Vector->z*Vector->z);

Vector->x /= Length;
Vector->y /= Length;
Vector->z /= Length;

return *Vector;
}

D3DXVECTOR3 CrossProduct(D3DXVECTOR3* v1, D3DXVECTOR3* v2)
{
D3DXVECTOR3 Result;

Result.x = v1->y * v2->z - v1->z * v2->y;
Result.y = v1->z * v2->x - v1->x * v2->z;
Result.z = v1->x * v2->y - v1->y * v2->x;

return Result;
}
}

The Camera Class:
class Camera
{
public:
D3DXVECTOR3 v_LookAt, v_Position, v_Up;

Camera();
void UpdateCamera(D3DXVECTOR3 *MouseDir);
void RotateCamera(double Angle, D3DXVECTOR3* v);
};

Camera::Camera()
{
v_LookAt = D3DXVECTOR3(-2.5,-7.5,2.5);
v_Position = D3DXVECTOR3(-20.0, 20.0, 20.0);
v_Up = D3DXVECTOR3(0.0, 1.0, 0.0);
}

void Camera::UpdateCamera(D3DXVECTOR3 *MouseDir)
{
D3DXVECTOR3 Up = v_Up;
D3DXVECTOR3 v = v_LookAt - v_Position;
D3DXVECTOR3 axis = _Math::CrossProduct(&v, &Up);

axis = _Math::NormalizeVector(&axis);

RotateCamera(MouseDir->y, &axis);
RotateCamera(MouseDir->x, &Up);

}

void Camera::RotateCamera(double Angle, D3DXVECTOR3 *Axis)
{
D3DXVECTOR3 View = v_LookAt - v_Position;
D3DXVECTOR3 Up = v_Up;
Quaternion R, Result;

R.x = Axis->x * sin(Angle/2.0);
R.y = Axis->y * sin(Angle/2.0);
R.z = Axis->z * sin(Angle/2.0);
R.w = cos(Angle/2.0);

Quaternion ConjR = R.ConjugateQuat();

Quaternion qView = _Math::VectorToQuat(&View);

Quaternion FirstMulti = qView * ConjR;

Result = R * FirstMulti;

v_Position.x = v_LookAt.x + Result.x;
v_Position.y = v_LookAt.y + Result.y;
v_Position.z = v_LookAt.z + Result.z;

Quaternion qUp = _Math::VectorToQuat(&Up);
FirstMulti = qUp * ConjR;
Result = R * FirstMulti;

v_Up.x = Result.x;
v_Up.y = Result.y;
v_Up.z = Result.z;
}


And finally the Quaternion Class:
class Quaternion
{
public:
double x, y, z, w;

Quaternion() { x = 0; y = 0; z = 0; w = 0;}

void NormalizeQuat()
{
double Length = sqrt( x * x + y * y + z * z + w * w);

x /= Length;
y /= Length;
z /= Length;
w /= Length;
}

Quaternion ConjugateQuat()
{
Quaternion ConjR;

ConjR.w = w;
ConjR.x = -x;
ConjR.y = -y;
ConjR.z = -z;

return ConjR;
}

Quaternion operator * (Quaternion B)
{
Quaternion Temp;

Temp.x = w*B.x + x*B.w + y*B.z - z*B.y;
Temp.y = w*B.y - x*B.z + y*B.w + z*B.x;
Temp.z = w*B.z + x*B.y - y*B.x + z*B.w;
Temp.w = w*B.w - x*B.x - y*B.y - z*B.z;

return Temp;
}
};


##### Share on other sites
karwosts    840
D3DXVECTOR3 NormalizeVector(D3DXVECTOR3* Vector)	{		double Length = (Vector->x*Vector->x + Vector->y*Vector->y + Vector->z*Vector->z);		Vector->x /= Length;		Vector->y /= Length;		Vector->z /= Length;		return *Vector;	}

Are you missing a sqrt() here? Improperly normalized vector could cause your issue I think.

##### Share on other sites
Waaayoff    952
Woah. Can't believe i forgot to do that! Good find :)

Thanks!!

##### Share on other sites
Molle85    172
Is there a reason why make your own math functions instead of using the D3DX functions ?

##### Share on other sites
YES Molle85! Because he wants to! Programmers should, by nature, be curious creatures. Are you not blessed with the most blessed of traits called curiosity, to dig and delve into the inner workings of the machine, to conquor with code, and to feel the thrill of achievement over coding challenges - whether those are self-imposed and often times "re-invent" the wheel? Surely you have felt this, and like everyone else here, you have probably wrote a routine or two in your past that was "already out there" and could be lifted from a library. I have wrote many, and continue to develop many that could easily be solved by simply adopting D3DX or Boost. Whether or not that makes a better programmer is debatable, but I firmly believe better programmers come from discovery.

"Rolling your own" is at the very heart of this trade, and its important to not stifle, critisize, question, or attempting to put down this worthiest of goals. We might, by way of virtue or experience, point others in alternative directions, but *only* after we have offered advice and answered to the best of our abilities, and offered others the benefit of our experience, otherwise simply, to coin a phrase, STFU!

Now, if he was working for me in a commercial environment where productivity reigns, then I would of course slap him around the head and tell him to stop re-inventing the wheel and us a library :)

F451

##### Share on other sites
Waaayoff    952
Quote:
 Original post by Molle85Is there a reason why make your own math functions instead of using the D3DX functions ?

I have a rule. If i don't know how a thing works, i learn about it, code it and then use it. Once i know how it works, i can either use my code, or if it was not very optimized, use a library.

@Fahrenheit451:
LOL.. Just LOL..

##### Share on other sites
Molle85    172
Thank you F451 for explaining that in such a well expressed manor.
Altho the purpose of the question was to see if it was intensional.
But again, thank you for spending time answering questions directed to other people.