На главную
ПРАВИЛА FAQ Помощь Участники Календарь Избранное DigiMania RSS
msm.ru
! Правила раздела "Программирование графики"
1) Данный раздел предназначен для обсуждения проблем, возникающих при программировании задач, связанных с чтением, сохранением, обработкой, созданием, отрисовкой графической информации (в том числе - 3D [OpenGL, Direct3D] и анимации [в т.ч. VFW, DirectShow, OpenDML]).
Флэш обсуждают здесь!.

2) Если вы хотите получить совет для конкретной платформы/языка программирования, обязательно укажите их в вопросе.

3) Уважаемые новички! Мы приветствуем Ваше желание научить всех посетителей раздела правильному программированию. Но огромная просьба, перед тем, как писать поучения в старых (последний ответ - "старее" месяца, а особенно, если вопрошавший не появляется на форуме уже не первый месяц, в чем можно убедиться в его профиле) темах, хорошо подумать, будет ли кому-нибудь, кроме Вас cамих, это интересно.



Ваше мнение о модераторах: user posted imageBarazuk, user posted imageOpenGL, user posted imageMikle
Модераторы: OpenGL, barazuk, Mikle
  
> Сферическая система координат. DirectX 9, С++
    Здравствуйте. у меня вопрос по сферической системе координат. что-то никак не могу понять как сделать перемещение камеры вокруг объекта.

    т.е. в функцию в параметре dir - приходят смещения мыши по х и у.
    ExpandedWrap disabled
      void CDirectCamera::RotateAroundTarget(D3DXVECTOR3 dir)
      {
          if(!m_bIsObjectState)
              return;
          D3DXVECTOR3 vToCamera = m_pos - m_Target;
       
          float fDistToCamera = D3DXVec3Length(&vToCamera);
       
          if (fDistToCamera == 0.0f)
              return;
       
          float latitude  = asinf(- m_look.y / D3DXVec3Length(&m_look));//asinf(vToCamera.y / fDistToCamera);
          float fDistToCamera2D = fDistToCamera*cosf(latitude);
       
          if (fDistToCamera2D < 0.1f)
              return;
       
          float longitude = acosf(vToCamera.x/fDistToCamera2D);
       
          if (vToCamera.z < 0)
          {
              longitude = 2 * D3DX_PI - longitude;
          }
          longitude += dir.x;
          latitude += dir.y;
       
          Clamp(latitude, - D3DX_PI / 2 + 0.01f, D3DX_PI / 2 - 0.01f);
       
          m_pos.y = m_Target.y + fDistToCamera*sinf(latitude);
          m_pos.x = m_Target.x + fDistToCamera*cosf(longitude)*cosf(latitude);
          m_pos.z = m_Target.z + fDistToCamera*sinf(longitude)*cosf(latitude);
      }


    этот метод я нашел в интернете(называется "режим слежения за объектом").
    но в данном методе привязка именно к исходным осям координат. а вот как перемещать камеру в плоскостях, заданных векторами up, right и look и при этом оставаться на том же расстоянии от m_Target (двигаться по сфере) - понять не могу.не получается никак отвязаться от исходных осей, чтобы вычислить новое положение камеры.
      drontng
      Вычитаешь из позиции камеры позицию объекта - получаешь вектор V.
      Вычисляешь матрицу M1 поворота вокруг оси Z на угол MouseX. (MatrixRotatuonZ)
      Находишь вектор "вправо" - кросспродукт вектора At и оси 0Z.
      Вычисляешь матрицу M2 поворота вокруг этой оси на угол MouseY. (MatrixRotatuonAxis)
      Умножаешь вектор V на эти две матрицы М1 и М2 (Vec3TransformCoord), прибавляешь к результату координаты объекта - получаешь новую позицию камеры.
        не совсем понял привязку к оси OZ. ведь Z у нас направлена в "даль". если так, то нужно скорее привязаться к оси У, которая идет вверх.
        и насколько я понимаю при вращении "вокруг оси Z" будет происходить движение в плоскости параллельной XOY (Z-координата камеры меняться не будет.)

        вобщем сделал следующим образом:

        ExpandedWrap disabled
              D3DXVECTOR3 vToCamera = m_pos - m_Target; // вектор на камеру
           
              D3DXVec3Cross( &m_right, &vToCamera, &D3DXVECTOR3(0.0f,1.0f,0.0f) ); // находим right
           
              D3DXVec3Normalize(&m_right, &m_right);
           
              D3DXMATRIX M2;
              D3DXMatrixRotationAxis(&M2, &m_right, dir.y); // вращаем вокруг right
           
              D3DXVec3Cross(&m_up, &m_look, &m_right); // находим up
              D3DXVec3Normalize(&m_up, &m_up);
           
              D3DXMATRIX M1;
              D3DXMatrixRotationAxis(&M1, &m_up, dir.x); // вращаем вокруг up
              
              D3DXVec3TransformCoord(&vToCamera, &vToCamera, &M1);
              D3DXVec3TransformCoord(&vToCamera, &vToCamera, &M2);
           
              m_pos = vToCamera + m_Target;


        правильно ли я сделал? =)

        и еще вопрос: как быть когда камера находится прямо над объектом(целью) ? векторы OY(вверх) и направление на камеру - параллельны. и поэтому векторное произведение этих векторов возвращает "плохую штуку" и камеру воротит. как это исправить? хотелось бы нормально перемещаться через эту точку.

        и кстати в этом варианте перемещения камеры при движении мыши по оси х заметно некоторое дергание сцены по Y.
        Сообщение отредактировано: drontng -
          Да! Я именно ось Y имел ввиду, а написал Z.
          Цитата
          в этом варианте перемещения камеры при движении мыши по оси х заметно некоторое дергание сцены по Y.

          Посмотрю.
            drontng
            Так ты находишь вертикаль относительно направления камеры, и вращаешь вокруг неё, а я имел ввиду вокруг оси Y.
            Я на бейсике прототип накидал - работает:

            При перемещении мыши накапливаю в переменные dx, dy смещение:
            ExpandedWrap disabled
              Private Sub Form_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
                If Button <> 1 Then Exit Sub
                dx = dx + (oldX - X) * -0.01
                dy = dy + (oldY - Y) * -0.01
                oldX = X
                oldY = Y
              End Sub


            Перед рендером рассчитываю:
            ExpandedWrap disabled
              Private Sub Driv()
                Dim M1 As D3DMATRIX, M2 As D3DMATRIX
                Dim vR As D3DVECTOR, vAt As D3DVECTOR, vToCam As D3DVECTOR
                  Vec3Subtract vToCam, CamPos, ObjPos
               
                  Vec3Cross vR, vToCam, Vec3(0, 1, 0)
               
                  Vec3Normalize vR, vR
               
                  MatrixRotationAxis M2, vR, dy
                  dy = 0
               
                  MatrixRotationY M1, dx
                  dx = 0
               
                  Vec3TransformCoord vToCam, vToCam, M1
                  Vec3TransformCoord vToCam, vToCam, M2
               
                  Vec3Add CamPos, ObjPos, vToCam
                  MatrixLookAtLH Mtrx, CamPos, ObjPos, Vec3(0, 1, 0)
                  d3dDevice.SetTransform D3DTS_VIEW, Mtrx
              End Sub


            То есть после применения я обнуляю dx и dy.
            Только максимальный угол вверх-вниз нужно ограничить, чтобы не достигал вертикали.
              у меня в функцию кручения приходили также смещения относительно последней точки мыши. использую директ инпут.

              в этом варианте получается вращение вокруг вектора вправо и оси У.
              может я неправильно выразился вначале?

              хочется реализовать камеру как при кручении мешей в DXSamples. т.е. при движении мыши влево мы перемещались в плоскости векторов vToCam и vRight и вектор vUp был не всегда 0, 1, 0. я нахожу вектор up векторным произведением этих векторов.и вращаю вокруг него. но получается сложно предсказуемое движение)

              посмотрел как в и семплах крутят тигренка - крутят и мировую матрицу. может такое вращение только видовой матрицей вообще нельзя реализовать? ) что-то в теории все правильно а на деле как-то вращается не туда.
              Сообщение отредактировано: drontng -
                разобрался наконец-то)))) нужно было еще при вращении вокруг up вращать и векторы look и right. а потом так же и при вращении вокруг right.
                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                0 пользователей:


                [ Script Execution time: 0,0844 ]   [ 15 queries used ]   [ Generated: 19.12.14, 15:07 GMT ]  

                Rambler's Top100