Суббота, 20 Апреля 2024, 15:13

Приветствую Вас Гость

[ Новые сообщения · Игроделы · Правила · Поиск ]
  • Страница 1 из 1
  • 1
Форум игроделов » Записи участника » Alerr [6]
Результаты поиска
AlerrДата: Воскресенье, 28 Августа 2016, 18:54 | Сообщение # 1 | Тема: Помогите со сложным вращением (кватернионы)
был не раз
Сейчас нет на сайте
Спасибо большое за внимание!
Но услоие Вы не до конца поняли.
1) Смотрите, куб физический, есть rigidBody.
Это значит что его могут толкать окружающие предметы и во время вращения тоже.
2) Куб должен "прилипать"(выравнивться) по углам кратным 90 градусам по тем осям, по которым его не вращают.
Если посмотрите видео по ссылкам из вопроса, то увидите как прилипает к углам кратным 90. Ну смотрите, например вращаем по OY. Значит по OZ и OZ он должен пытаться пристать к ближайшему углу, который кратен 90 градусам.

Задачка вообщем-то почти решена, если будет интересно, то когда доделаю покажу исходник. А так, если хотите ради спортивного интереса, то предлагайте варианты) Всегда интерсно посмотреть еще варианты решения)
AlerrДата: Суббота, 27 Августа 2016, 20:00 | Сообщение # 2 | Тема: Помогите со сложным вращением (кватернионы)
был не раз
Сейчас нет на сайте
Да, спасибо) Я уже видел эти статьи. Вообщем-то что там написано понял, но это мне не помогло. Пытаюсь доворачивать куб до ближайшего угла, который кратен 90 градусам, но ничего не выходит :( ...

Добавлено (27 августа 2016, 20:00)
---------------------------------------------
Вот мне подсказали как это можно сделать, буквально за меня написали, я сделал, но не работает:

Код
Quaternion[] rot = new Quaternion[] {
    new Quaternion(0,0,0,1),
    new Quaternion(0,0,0.707f,-0.707f),
    new Quaternion(0,0,0.707f,0.707f),

    new Quaternion(0,0,1,0),
    new Quaternion(0,0.707f,-0.707f,0),
    new Quaternion(0,0.707f,0,-0.707f),
    new Quaternion(0,0.707f,0,0.707f),
    new Quaternion(0,0.707f,0.707f,0),

    new Quaternion(0,1,0,0),
    new Quaternion(0.5f,-0.5f,-0.5f,-0.5f),
    new Quaternion(0.5f,-0.5f,-0.5f,0.5f),
    new Quaternion(0.5f,-0.5f,0.5f,-0.5f),
    new Quaternion(0.5f,-0.5f,0.5f,0.5f),

    new Quaternion(0.5f,0.5f,-0.5f,-0.5f),
    new Quaternion(0.5f,0.5f,-0.5f,0.5f),
    new Quaternion(0.5f,0.5f,0.5f,-0.5f),
    new Quaternion(0.5f,0.5f,0.5f,0.5f),

    new Quaternion(0.707f,-0.707f,0,0),
    new Quaternion(0.707f,0,-0.707f,0),
    new Quaternion(0.707f,0,0,-0.707f),
    new Quaternion(0.707f,0,0,0.707f),

    new Quaternion(0.707f,0,0.707f,0),
    new Quaternion(0.707f,0.707f,0,0),
    new Quaternion(1,0,0,0)
  };

int NearestRot(Quaternion cubeRot){
    int nearestIndex = 0;

    for (int i = 0; i < 24; ++i) {
      float maxDot = -10000.0f; //NEG INF
      float dot = Mathf.Abs(Quaternion.Dot(
        cubeRot, rot[i]));
      if (dot > maxDot) {
        maxDot = dot;
        nearestIndex = i;
      }
    }
    return nearestIndex;
  }

void FixedUpdate() {
  cubeRigid.rotation = Quaternion.Slerp(cubeRigid.rotation, rot[NearestRot(cubeRigid.rotation)], 10f*Time.fixedDeltaTime);
}
AlerrДата: Пятница, 26 Августа 2016, 14:36 | Сообщение # 3 | Тема: Помогите со сложным вращением (кватернионы)
был не раз
Сейчас нет на сайте
Спасибо! Обязательно посмотрю. Я уже кучу времени потратил на эту штуку и у меня толкового ничего не вышло. Так что предложение мое в силе.
AlerrДата: Пятница, 26 Августа 2016, 14:07 | Сообщение # 4 | Тема: Помогите со сложным вращением (кватернионы)
был не раз
Сейчас нет на сайте
Можете посоветовать альтернативное рещение?
AlerrДата: Пятница, 26 Августа 2016, 12:17 | Сообщение # 5 | Тема: Помогите со сложным вращением (кватернионы)
был не раз
Сейчас нет на сайте
Привет всем, долго бился с кватернионами и безуспешно :crazy:
Надеюсь кто-то поможет. Вот формулировка задачи:
Есть куб и игрок.
Игрок может брать и вращать куб по 1-й из 3-х осей относительно себя.
Куб должен свободно вращаться колесиком мыши по оси, которая в данный момент выбрана как ось вращения. По остальным осям куб должен “выравниваться”. Оси вращения считаются относительно игрока.
Во время вращения куб могут толкать другие предметы, куб физический и может взаимодействовать с окружающими предметами.
Нефизическое поведение куба недопустимо.

Что значит “выровнять” куб:
Если игрок вращает куб по OY, то это значит, что нижняя грань куба должна быть паралельна полу.
Если игрок вращает куб по оси OZ (forward , вращение от нас и к нам(да, у меня камера свернутна на 90 градусов и right соответствует forward)), то по оси OX он выравнивается относительно пола. По оси OY докручивается к нам так, что плоскость OYZ становится паралельна плоскости экрана.
Если игрок вращает куб по оси OX (right), то куб вращается перед нами по/прочив часовой стрелки. Ближайшая к нам грань должна быть паралельна плоскости экрана. По оси OZ куб становится на угол кратный 90 градусам (Пытается выровняться “по полу”).

Итого получается что куб вращается сам (самостоятельно докручивается) и под действием игрока (игрок вращает по заданной оси).
——————————
Теперь по коду:
Вот что я имею ввиду под выравниванием:
Код
myTransform - player
rigidBody/rigidTransform - куб
rotStep = Mathf.Sqrt (0.5f);// 90 degree
Этот код “выравнивает” куб.
void FixedUpdate(){
  Quaternion qq = rigidBody.rotation;
  qq.x = Mathf.Round (qq.x / rotStep) * rotStep;
  qq.y = Mathf.Round (qq.y / rotStep) * rotStep;
  qq.z = Mathf.Round (qq.z / rotStep) * rotStep;
  qq.w = Mathf.Round (qq.w / rotStep) * rotStep;

  rigidBody.rotation = Quaternion.Lerp (rigidBody.rotation, qq, 5f*Time.fixedDeltaTime);
}

————
Этот код позволяет крутить куб по выбранной оси:
Код
delta - сюда поступает displacement с колесика мыши
void FixedUpdate(){
  if (axisIndex==0) {         
    localAxis = rigidTransform.InverseTransformPoint (Vector3.up + rigidTransform.position);     
    Debug.Log ("OY");       
  }  else {
          if (axisIndex==1) {// z axis
            localAxis = rigidTransform.InverseTransformPoint(myTransform.TransformPoint (Vector3.forward)+(rigidBody.position-myTransform.position));     
            Debug.Log ("OZ");         
    }  else {           
      if (axisIndex == 2) {            
         localAxis = rigidTransform.InverseTransformPoint (myTransform.TransformPoint (Vector3.right) + (rigidBody.position - myTransform.position));                         
         Debug.Log ("OX");           
      }  else {             
         eulerAngleVelocity = Vector3.zero;          
      }
     }
  }
    Quaternion deltaRotation = Quaternion.AngleAxis(delta * 400f * Time.fixedDeltaTime, localAxis);
    rigidBody.rotation *= deltaRotation;
}

Теперь какие стоят проблемы:
1) Ось по которой вращают куб не свободна, куб постоянно пытается выровнять себя по той оси, по которой его крутят.
2) Ближайшая к игроку грань куба (при axisIndex == 1 || axisIndex == 2) не паралельна плоскости экрана.
Вот ссылк на видео того что получилось добиться через углы эйлера и что “почти” работает (вообщем-то так и должен выглядеть результат):
YandexDisk Video1
YandexDisk Video2
Cсылка на проект с вращением куба: ProjectSource (все делал через кватернионы и куб передергивает при вращении)
По тем видео можно понять как все должно работать. Что скажете?

Задачка для меня сложновата, обычно кватернионами вообще не занимался.
Ассы кватернионов, помогите, в долгу не останусь :)

Добавлено (26 августа 2016, 12:17)
---------------------------------------------
Неужели это на самом деле сложная задача? Я думал, что для профи это как 2 вектора сложить. За помощь отблагодарю денежно.

Сообщение отредактировал Alerr - Четверг, 25 Августа 2016, 19:56
AlerrДата: Четверг, 25 Августа 2016, 18:58 | Сообщение # 6 | Тема: Ищу доброго человека по вопросам мультиплеера
был не раз
Сейчас нет на сайте
Я, конечно, не асс. С Unity набил шишки. Что-то могу подсказать, совсем немного...
Форум игроделов » Записи участника » Alerr [6]
  • Страница 1 из 1
  • 1
Поиск:

Все права сохранены. GcUp.ru © 2008-2024 Рейтинг