5
\$\begingroup\$

I'm trying to implement my camera class for a simulation. But I cant figure out how to zoom into my world based on the mouse position. I mean the object under the mouse cursor should remain at the same screen position. My zooming looks like this:

VOID ZoomIn(D3DXMATRIX& WorldMatrix, FLOAT const& MouseX, FLOAT const& MouseY) {      
    this->Position.z = this->Position.z * 0.9f;
    D3DXMatrixLookAtLH(&this->ViewMatrix, &this->Position, &this->Target, &this->UpDirection);
}

I passed the world matrix to the function because I had the idea to move my drawing origin according to the mouse position. But I cant find out how to calculate the offset in to move my drawing origin. Anyone got an idea how to calculate this?

Thanks in advance.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Add your SOLVED section as an answer. After enough time passes, you can select it as the answer unless somebody gives you a better one. \$\endgroup\$ Commented Nov 25, 2012 at 1:58
  • \$\begingroup\$ A simpler way of implementing zoom is simply to change the scale parameters. Multiply the first three diagonal components of the world matrix by whatever zoom factor you want and then set them back to one once you're finished. \$\endgroup\$
    – Tristan
    Commented Nov 25, 2012 at 10:41

1 Answer 1

1
\$\begingroup\$

SOLVED

Ok I solved my problem. Here is the code if anyone is interested:

VOID CAMERA2D::ZoomIn(FLOAT const& MouseX, FLOAT const& MouseY) {
    // Get the setting of the current view port.
    D3DVIEWPORT9 ViewPort;
    this->Direct3DDevice->GetViewport(&ViewPort);

    // Convert the screen coordinates of the mouse to world space coordinates.
    D3DXVECTOR3 VectorOne;
    D3DXVECTOR3 VectorTwo;

    D3DXVec3Unproject(&VectorOne, &D3DXVECTOR3(MouseX, MouseY, 0.0f), &ViewPort, 
        &this->ProjectionMatrix, &this->ViewMatrix, &WorldMatrix);
    D3DXVec3Unproject(&VectorTwo, &D3DXVECTOR3(MouseX, MouseY, 1.0f), &ViewPort, 
        &this->ProjectionMatrix, &this->ViewMatrix, &WorldMatrix);

    // Calculate the resulting vector components.
    float WorldZ = 0.0f;
    float WorldX = ((WorldZ - VectorOne.z) * (VectorTwo.x - VectorOne.x)) /
        (VectorTwo.z - VectorOne.z) + VectorOne.x;
    float WorldY = ((WorldZ - VectorOne.z) * (VectorTwo.y - VectorOne.y)) /
        (VectorTwo.z - VectorOne.z) + VectorOne.y;

    // Move the camera into the screen.
    this->Position.z = this->Position.z * 0.9f;
    D3DXMatrixLookAtLH(&this->ViewMatrix, &this->Position, &this->Target, &this->UpDirection);

    // Calculate the world space vector again based on the new view matrix,
    D3DXVec3Unproject(&VectorOne, &D3DXVECTOR3(MouseX, MouseY, 0.0f), &ViewPort, 
        &this->ProjectionMatrix, &this->ViewMatrix, &WorldMatrix);
    D3DXVec3Unproject(&VectorTwo, &D3DXVECTOR3(MouseX, MouseY, 1.0f), &ViewPort, 
        &this->ProjectionMatrix, &this->ViewMatrix, &WorldMatrix);

    // Calculate the resulting vector components.
    float WorldZ2 = 0.0f;
    float WorldX2 = ((WorldZ2 - VectorOne.z) * (VectorTwo.x - VectorOne.x)) / 
        (VectorTwo.z - VectorOne.z) + VectorOne.x;
    float WorldY2 = ((WorldZ2 - VectorOne.z) * (VectorTwo.y - VectorOne.y)) /
        (VectorTwo.z - VectorOne.z) + VectorOne.y;

    // Create a temporary translation matrix for calculating the origin offset.
    D3DXMATRIX TranslationMatrix;
    D3DXMatrixIdentity(&TranslationMatrix);

    // Calculate the origin offset.
    D3DXMatrixTranslation(&TranslationMatrix, WorldX2 - WorldX, WorldY2 - WorldY, 0.0f);

    // At the offset to the cameras world matrix.
    this->WorldMatrix = this->WorldMatrix * TranslationMatrix;
}

Maybe someone has even a better solution than mine.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .