forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   Общие вопросы (http://forum.boolean.name/forumdisplay.php?f=166)
-   -   Кватернион. Как определить угол вращения. (http://forum.boolean.name/showthread.php?t=18226)

dsd 31.05.2013 23:26

Кватернион. Как определить угол вращения.
 
В общем есть у меня вектор который совпадает с осью игрек и есть вектор к которому я хочу повернуть некоторое количество точек чьи координаты при направляющем векторе по оси игрек мне известны.
PHP код:

Vector3 axis = new Vector3(1,1,1); //нужная ось
axis.Normalize();
Vector3 curAxis = new Vector3(0,1,0);//текущая ось
float angle Vector3.Angle(axis,curAxis);//угол между векторами
Vector3 newAxis Vector3.Cross(axis,curAxis);//ось вращения для квартерниона
newAxis*=Mathf.Sin(angle);
Quaternion magic = new Quaternion(newAxis.x,newAxis.y,newAxis.z,Mathf.Cos(angle));
...
vert[i*(width+1)+j] = magic pos

И в общем вращение происходит в нужной плоскости, но не на тот угол что мне нужен. От какого вектора в плоскости с нормалью совпадающей с осью вращения этот угол считать?

pax 31.05.2013 23:29

Ответ: Кватернион. Как определить угол вращения.
 
А это не подойдет? http://docs.unity3d.com/Documentatio...oRotation.html Умножить все точки на него.

Ну и вращение происходит относительно нуля координат. Попробуй вычесть центр вращения из точки, повернуть, потом прибавить центр вращения.

dsd 31.05.2013 23:38

Ответ: Кватернион. Как определить угол вращения.
 
Подошло идеально. Выходит зря википедию по кватернионам читал :))

dsd 01.06.2013 03:14

Ответ: Кватернион. Как определить угол вращения.
 
Вложений: 1
Ну и собственно то зачем мне это понадобилось.

Что-то типа плоскости прикидывающейся планетой у которой плавно растет детализация при приближении.

в архиве сам проект и собранное приложение.

pax 01.06.2013 03:28

Ответ: Кватернион. Как определить угол вращения.
 
Интересно, перенести бы этот алгоритм в шейдер, жрет многовато сейчас. 20 ms на обновление. Правда с нормалями надо что-то заранее сделать... кубмэпу или что-то еще... Нойз бы тоже запечь...

dsd 01.06.2013 03:34

Ответ: Кватернион. Как определить угол вращения.
 
Так этож перестроение поверхности идет каждый кадр, а в реальности оно понадобится редко, не каждую секунду точно. И там же как я понимаю куча лишних операций в кватернионе, оно ж собирает матрицу из него для каждой вершины отдельно, плюс сам алгоритм шума довольно жрущий. По идее все это можно упростить по вычислениям проецируя каждую точку на куб, где на каждую грань идет своя сохраненная карта высот и прочая полезная информация типа тестурных координат.
А пихать это в шейдер зря наверно. Усложнит на порядок же внесение модификаций в алгоритм генерации поверхности.

pax 01.06.2013 03:45

Ответ: Кватернион. Как определить угол вращения.
 
С матрицей не быстрее, У кватерниона свое умножение на вектор нормальное. Можешь сравнить
PHP код:

var matrix Matrix4x4.TRS(Vector3.zeromagicVector3.one);
pos matrix.MultiplyVector(pos) ; 


dsd 01.06.2013 03:51

Ответ: Кватернион. Как определить угол вращения.
 
А я думал оно вот эту хреновину собирает чтобы повернуть:

Выражение матрицы поворота через кватернион
Если задан кватернион q = (w,x,y,z), то соответствующая матрица поворота имеет вид:

pax 01.06.2013 03:52

Ответ: Кватернион. Как определить угол вращения.
 
Где-то около трех миллисекунд сокращает:

PHP код:

void Update () {
            
setVertices();    
            
Mesh mesh GetComponent<MeshFilter>().mesh;
            
//mesh.Clear(true);  - незачем
            
mesh.vertices vert;
            
mesh.uv uv;
            
//mesh.triangles = trians;   - незачем
            
mesh.RecalculateNormals();
    } 

Ну и Mesh закэшируй, искать объекты каждый кадр типа GameObject.Find или GetComponent не стоит, это медленно.


Кстати еще можно это сократить
PHP код:

gameObject.AddComponent("MeshFilter");
Mesh mesh GetComponent<MeshFilter>().mesh

так
PHP код:

Mesh mesh gameObject.AddComponent<MeshFilter>().mesh


dsd 05.06.2013 02:16

Ответ: Кватернион. Как определить угол вращения.
 
pax, а вот захотел я допустим к этой хрени вращение сделать.

Vector3 angle = gameObject.transform.eulerAngles;
angle.y+=0.1f;
gameObject.transform.eulerAngles = angle;

вот так этот планетоид вращаться начинает

Как мне потом позицию камеры перевестив локальные координаты?

Vector3 campos = gameObject.transform.rotation * cam.transform.position ;
Vector3 campos = gameObject.transform.localToWorldMatrix * cam.transform.position ;
Vector3 campos = gameObject.transform.worldToLocalMatrix * cam.transform.position ;

Ничто из этого не сработало. Может я вращаю не правильно... Как?

pax 05.06.2013 07:38

Ответ: Кватернион. Как определить угол вращения.
 
Так наверное

Vector3 campos = transform.worldToLocalMatrix.MultiplyPoint(cam.tra nsform.position);

либо так
Vector3 campos = transform.InverseTransformPoint(cam.transform.posi tion);

dsd 18.06.2013 19:14

Ответ: Кватернион. Как определить угол вращения.
 
Вложений: 1


Сочинил что-то типа кубомапы и вроде бы побыстрей стало.

HolyDel 19.06.2013 18:50

Ответ: Кватернион. Как определить угол вращения.
 
а исполнимый файл?

dsd 20.06.2013 00:05

Ответ: Кватернион. Как определить угол вращения.
 
Цитата:

Сообщение от HolyDel (Сообщение 261683)
а исполнимый файл?

да там особо не на что смотреть, на вид почти тоже самое что и раньше.

вот файл

dsd 28.07.2013 03:11

Ответ: Кватернион. Как определить угол вращения.
 
Вложений: 1


архив с ехе 10 мб

Добавил твердости планете и систему частиц кое-как прикидывающуюся облачками.

Кто-нить делал вменяемый моуслук на поверхности сферы? Чтобы камера вела себя как при обычном моуслуке но считала что ось(0,1,0) была направлена от центра сферы к позиции камеры. Как это сделать?

PHP код:

float sensitivity 1.5F;
        
        
        
Vector3 rotation =  cam.transform.eulerAngles;
        
// получаем значение оси ввода "Horizontal" и прибавляем его к значению вращения
        
rotation.-= sensitivity Input.GetAxis ("Mouse Y");
        
rotation.+= sensitivity Input.GetAxis ("Mouse X");
        
// устанавливаем вращение объекта
        
cam.transform.eulerAngles rotation;
        
        
//движение камеры
        
float speed 0.5f;
        
        
Vector3 move = new Vector3(0,0,0);    
        if(
Input.GetKey(KeyCode.A))move-= cam.transform.right;
        if(
Input.GetKey(KeyCode.D))move+= cam.transform.right;
        if(
Input.GetKey(KeyCode.S))move-= cam.transform.forward;
        if(
Input.GetKey(KeyCode.W))move+= cam.transform.forward;
        
        
cam.transform.position += move*speed



Часовой пояс GMT +4, время: 10:57.

vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot