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.