Bonjour, dans le cadre de mon projet de recreer un 3dEngine basic, je me suis donne pour objectif de pouvoir deplacer mes objets rendus en les selectionnant, puis en faisant apparaitre les axes correspondant a mon objet representes sous forme de fleches.
J'ai compris la (ou une des) maniere(s) de proceder, qui est de projetter mes coordonees de ma souris dans mon espace 3d, puis de recuperer le point d'intersection avec le plan selon lequel je vais travailler (deplacer mon objet selon son axe X -> plan XY).
Je repete l'operation "2 fois" avec les coordonees precedentes de ma souris et celle actuelles pour obtenir un delta et avoir un deplacement a peu pres proportionnel avec celui de ma souris.
Mon probleme etant que meme en sachant cela (si c'est la bonne methode) je n'arrive pas a arriver a un resultat coherent.
Quelques specificite de mes parametres :
- j'ai une camera fixe, avec un lookAt = eye = {0, 0, 0}, center = {0, 0, -1} et up = {0, 1, 0}, ce qui veux dire que mon monde translate et tourne,
- je n'utilise aucune lib externe autre que <GLFW/glfw3.h> qui est nécessaire pour avoir un opengl minimal.
Le deroulement de mon code :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
 
void Render::moveGizmo(double &lastX, double &lastY)
{
    double mouseX, mouseY;
    Entity *obj = Gizmo::getObj();
    auto pos = obj->getMesh().getPos();
    auto vert = Gizmo::getGizmo()[3].getMesh().getVertices();
    std::array<double,3> axis = {0, 0, 0}, plane = {0, 0, 0}, axisWorld, planeWorld;
    int index = Gizmo::getArrPos()[3];
 
    if (index-- == 0)
        return ;
    axis[index] = 1.0;
    if (axis[0] == 1.0) plane = {0,0,1}; // X → plan XY
    if (axis[1] == 1.0) plane = {0,0,1}; // Y → plan XY
    if (axis[2] == 1.0) plane = {0,1,0}; // Z → plan XZ
    obj->turnAxis(axis, axisWorld);
    obj->turnAxis(plane, planeWorld);
    glfwGetCursorPos(Opengl::getWindow(), &mouseX, &mouseY);
    std::array<double, 3> dirLast, originLast, dirM, originM, interLast, interMouse;
 
    if (!unprojectMouse(lastX, lastY, dirLast[0], dirLast[1], dirLast[2], originLast))
        return ;
    if (!unprojectMouse(mouseX, mouseY, dirM[0], dirM[1], dirM[2], originM))
        return ;
    if (!getIntersection(planeWorld, originLast, dirLast, interLast))
        return ;
    if (!getIntersection(planeWorld, originM, dirM, interMouse))
        return ;
    std::array<double, 3> delta = {interMouse[0] - interLast[0], interMouse[1] - interLast[1], interMouse[2] - interLast[2]};
    double dot = delta[0]*axisWorld[0] + delta[1]*axisWorld[1] + delta[2]*axisWorld[2];
    std::array<double, 3> deltaAxis = {dot * axisWorld[0], dot * axisWorld[1], dot * axisWorld[2]};
    obj->setPos(pos[0] + deltaAxis[0],
                pos[1] + deltaAxis[1],
                pos[2] + deltaAxis[2]);
 
    lastX = mouseX;
    lastY = mouseY;
}
avec turnAxis qui prends l'origine de base et qui applique les matrices de rotations de mon objet pour bien tourner pour correspondre a mon objet selectionne,
avec unprojectMouse qui va projeter selon le sens inverse les coordonees de ma souris (fait pixel -> ndc, avec z = -1 puis z = 1 pour near/far) puis multiplie ces coordonees par l'inverse de cette matrice: projection * view * wTranslate * wRotZ * wRotY * wRotX, puis divise par w fait le vecteur far - near et normalise,
avec getIntersection qui renvoit le point d'intersection de mon rayon souris et mon plan.
C'est a peu pres tout, si vous avez des idees du pourquoi cela ne fonctionne pas je suis prenneur !
Merci d'avance