Sattuiskohan täällä olemaan ketään matikka neroa joka taitaisi kvaterniot ja osaisi kertoa mitä minä teen väärin?
Videolla liikkuvan pallon pitäisi pysyä aluksen keulan edessä mutta pyörii ihan omiaan.
http://youtu.be/UUmwFnLktjg
Piirto koodi
[&](std::shared_ptr<SimulationObject> obj) { const vec3_dim & op = obj->getPosition(); const quat_dim & or = obj->getAttitude(); //object glm::mat4 modelMatrix(1.0f); modelMatrix = glm::translate((float)op.X(), (float)op.Y(), (float)op.Z()) * buildMatrix(or); testModel->draw(modelMatrix, viewMatrix, projectionMatrix, glm::normalize(glm::vec3(-1,1,0))); //1 small sphere in front of object; vec3_dim op2 = op + or.rotateVector(vec3_dim(10.0, 0.0, 0.0)); modelMatrix = glm::translate((float)op2.X(), (float)op2.Y(), (float)op2.Z()); sphereModel->draw(modelMatrix, viewMatrix, projectionMatrix, glm::normalize(glm::vec3(-1,1,0))); //4 small spheres around the object, static op2 = op + vec3_dim(12.0, 0.0, 0.0); modelMatrix = glm::translate((float)op2.X(), (float)op2.Y(), (float)op2.Z()); sphereModel->draw(modelMatrix, viewMatrix, projectionMatrix, glm::normalize(glm::vec3(-1,1,0))); op2 = op + vec3_dim(-12.0, 0.0, 0.0); modelMatrix = glm::translate((float)op2.X(), (float)op2.Y(), (float)op2.Z()); sphereModel->draw(modelMatrix, viewMatrix, projectionMatrix, glm::normalize(glm::vec3(-1,1,0))); op2 = op + vec3_dim(0.0, 0.0, 12.0); modelMatrix = glm::translate((float)op2.X(), (float)op2.Y(), (float)op2.Z()); sphereModel->draw(modelMatrix, viewMatrix, projectionMatrix, glm::normalize(glm::vec3(-1,1,0))); op2 = op + vec3_dim(0.0, 0.0, -12.0); modelMatrix = glm::translate((float)op2.X(), (float)op2.Y(), (float)op2.Z()); sphereModel->draw(modelMatrix, viewMatrix, projectionMatrix, glm::normalize(glm::vec3(-1,1,0))); }
Vektorin pyöritys. Koitin myös tuolla annettua koodia: http://content.gpwiki.org/index.php/OpenGL:Tutorials:Using_Quaternions_to_represent_rotation mutta tulos oli aivan sama.
template <typename Tv> Vec3<Tv> Quaternion::rotateVector(const Vec3<Tv>& vec) const { Vec3<Tv> tmp = Vec3<Tv>(x, y, z).cross(vec) * 2.0; return vec + tmp * w + Vec3<Tv>(x, y, z).cross(tmp); }
Matriisi piirtämistä varten
template <typename T> glm::mat4 buildMatrix(const Quaternion<T>& v) { glm::mat4 result; const T & x = v.X(); const T & y = v.Y(); const T & z = v.Z(); const T & w = v.W(); T x2 = x * x; T y2 = y * y; T z2 = z * z; T w2 = w * w; result[0][0] = 1.0 - 2.0 * (y2 + z2); result[0][1] = 2.0 * (x * y - w * z); result[0][2] = 2.0 * (x * z + w * y); result[0][3] = 0.0; result[1][0] = 2.0 * (x * y + w * z); result[1][1] = 1.0 - 2.0 * (x2 + z2); result[1][2] = 2.0 * (y * z - w * x); result[1][3] = 0.0; result[2][0] = 2.0 * (x * z - w * y); result[2][1] = 2.0 * (y * z + w * x); result[2][2] = 1.0 - 2.0 * (x2 + y2); result[2][3] = 0.0; result[3][0] = 0.0; result[3][1] = 0.0; result[3][2] = 0.0; result[3][3] = 1.0; return result; }
Tein itsekin 3D-demon yks päivä.
http://www.youtube.com/watch?v=IKoE-JL7OXg
Tuolla videolla taidan käyttää vaan matriiseja mutta kokeilin quaternioiden toimivuuden tällä demolla monta kertaa.
Lähdekoodia 3D-matikkaan löytyy tuolta, esim vastaava funktio (pascal:lla):
http://code.google.com/p/nxpascal/source/browse/
Hitusen työlästä verrata noita, en kerkeä nyt.
Muokkaus: Näyttäis kyllä + ja - merkit menevän ihan eri tavalla. Liekö DirectX-koodia tvs? He käyttää toispuoleisia matriiseja.
User137 kirjoitti:
Muokkaus: Näyttäis kyllä + ja - merkit menevän ihan eri tavalla. Liekö DirectX-koodia tvs? He käyttää toispuoleisia matriiseja.
+ ja - merkkejä vaihtelemallahan se selvisi. Tälläinen järjestys näyttäisi toimivan oikein. Jännää tämä matikka kun piti vielä käydä vaihtamassa fysiikka koodista kvaternioiden kertomis järjestys että pyöritykset toimivat oikein muutoksen jälkeen.
result[0][0] = 1.0 - 2.0 * (y2 + z2); result[0][1] = 2.0 * (x * y + w * z); result[0][2] = 2.0 * (x * z - w * y); result[0][3] = 0.0; result[1][0] = 2.0 * (x * y - w * z); result[1][1] = 1.0 - 2.0 * (x2 + z2); result[1][2] = 2.0 * (y * z + w * x); result[1][3] = 0.0; result[2][0] = 2.0 * (x * z + w * y); result[2][1] = 2.0 * (y * z - w * x); result[2][2] = 1.0 - 2.0 * (x2 + y2); result[2][3] = 0.0; result[3][0] = 0.0; result[3][1] = 0.0; result[3][2] = 0.0; result[3][3] = 1.0;
Sulla on kyllä paremmin optimoitu tuo funktio, taidan muuttaa omaakin.
Aihe on jo aika vanha, joten et voi enää vastata siihen.