Jump to content
  • Advertisement
Sign in to follow this  
polar01

Arcball problem

This topic is 2869 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi,

I'm trying to add an "arc ball" but I have a strange behaviour.
I surely do something wrong, but what :-P So, if someone has an idea of the problem ?

How to reproduce it :
1 - With my arcball, I do an horizontal rotation of 180 degree (all is fine)
2 - I try to do a vertical rotation and the scene rotate in the INVERSE direction

Here is what I do :


void TrackballOperator::OnMouseMove(MouseEventArgs* e)
{
if (e->LeftButtonStatus == Down)
{
Drag(e->x, e->y);

// Update the camera
VNCamera* camera = _surface->GetScene()->GetActiveCamera();
Vector3 at = camera->GetEyeAt();

// eye
Vector3 eye = _startVector - at;
GlobalRotation.Rotate(&eye);
camera->SetEye(eye + at);

// eye up
Vector3 eyeUp = _startVectorUp;
GlobalRotation.Rotate(&eyeUp);
camera->SetEyeUp(eyeUp);
}
}

void TrackballOperator::OnMouseButtonDown(MouseButtonEventArgs* e)
{
if (e->Button == Left)
{
SetBounds(_surface->GetWidth(), _surface->GetHeight());

//---- Reset some datas...
VNCamera* camera = _surface->GetScene()->GetActiveCamera();
_startVector = camera->GetEye();
_startVectorUp = camera->GetEyeUp();

startMouse.x = e->x;
startMouse.y = e->y;

GlobalRotation.AsIdentity();
}
}
void TrackballOperator::MapToSphere(const Vector2* NewPt, Vector3* NewVec) const
{
Vector2 TempPt;
float length;

// Copy paramter into temp point
TempPt = *NewPt;

// Adjust point coords and scale down to range of [-1 ... 1]
TempPt.x = (TempPt.x * this->AdjustWidth) - 1.0f;
TempPt.y = 1.0f - (TempPt.y * this->AdjustHeight);

// Compute the square of the length of the vector to the point from the center
length = (TempPt.x * TempPt.x) + (TempPt.y * TempPt.y);

// If the point is mapped outside of the sphere... (length > radius squared)
if (length > 1.0f)
{
float norm;

// Compute a normalizing factor (radius / sqrt(length))
norm = 1.0f / sqrtf(length);

// Return the "normalized" vector, a point on the sphere
NewVec->x = TempPt.x * norm;
NewVec->y = TempPt.y * norm;
NewVec->z = 0.0f;
}
else //Else it's on the inside
{
//Return a vector to a point mapped inside the sphere sqrt(radius squared - length)
NewVec->x = TempPt.x;
NewVec->y = TempPt.y;
NewVec->z = sqrtf(1.0f - length);
}
}


void TrackballOperator::Drag(float newX, float newY)
{
endMouse.x = newX;
endMouse.y = newY;

// Map the point to the sphere
Vector3 startPoint;
Vector3 endPoint;
MapToSphere(&startMouse, &startPoint);
MapToSphere(&endMouse, &endPoint);

// Return the quaternion equivalent to the rotation
// Compute the vector perpendicular to the begin and end vectors
Vector3 Perp = Cross(endPoint, startPoint);

startMouse = endMouse;

// Compute the length of the perpendicular vector
Quaternion NewRot;
if (Perp.Length() < EPSILON)
return;

// We're ok, so return the perpendicular vector as the transform after all
NewRot.x = Perp.x;
NewRot.y = Perp.y;
NewRot.z = Perp.z;

// In the quaternion values, w is cosine (theta / 2), where theta is rotation angle
NewRot.w = Dot(startPoint, endPoint);

GlobalRotation = GlobalRotation * NewRot;
}



About the quaternion class :


// Conjugate it
void Conjugate()
{
x = -x;
y = -y;
z = -z;
}

// Calculates the effect of this rotation on a point
// the new point is given by = q * P1 * q'
void Rotate(Vector3* point)
{
//---- Compute the conjugate
Quaternion conj = *this;
conj.Conjugate();

//---- q * P * q'
Quaternion qNode(point->x, point->y, point->z, 0.f);
qNode = *this * qNode * conj;

//---- Set the result
point->x = qNode.x;
point->y = qNode.y;
point->z = qNode.z;
}

Share this post


Link to post
Share on other sites
Advertisement
I think I have found the problem.

I need to set-up my initial quaternion with the camera axis.

So, do you know how to convert 3 Axis (AxisX, AxisY, AxisZ) into a quaternion ?

Thanks for your help

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!