Mausposition in 3D Raum umberechnen

  • Hi @ all,
    mein Problem: ich versuche in OpenGL ein Würfel parallel zur Maus laufen zu lassen. Es soll also so sein, dass der Würfel immer an der Cursorspitze ist.
    Problematisch dabei ist, dass die Mausposition auf das Fenster bezogen ist, und sich die Würfelposition auf den Raum bezieht. @ alle guten Mathematiker/Physiker:
    Wie kann ich die Mausposition in den 3D Raum umberechnen?

    mfG Developer30

    Edit: Die Würfelhöhe ($z) soll nicht angepasst werden. Nur x und y Position...

    "Je mehr Käse, desto mehr Löcher; je mehr Löcher, desto weniger Käse. Ergo: Je mehr Käse, desto weniger Käse. 8| "
    "Programmers never die: they just GOSUB without RETURN"
    "I tried to change the world but I couldn't find the source code."

    Einmal editiert, zuletzt von Developer30 (14. September 2010 um 18:36)

    • Offizieller Beitrag

    Ich verstehe nicht recht, was du möchtest. Wenn der Würfel sich parallel zur Maus bewegt ändern sich doch nur 2D-Koordinaten, also horizontale und vertikale Wertänderung. Die kannst du doch 1:1 von der Maus übernehmen. Du behältst also z bei und änderst analog zur Änderung der Mauswerte x und y deines Würfels.
    Zeig doch mal dein bisheriges Skript.

  • Du brauchst nichts umzurechnen, wie BugFix schon meint.
    Mausbewegung nach links -> Rotation in diese Richtig. :)

  • das mit den 2D Koordinaten geht nur auf, wenn die Kamera im genau im Zenit steht. Mein eigendliches Skript ist zu lange und enthält zu viele (eigene) Includes um es hier zu posten. Ich habe aber es aber zu einem Beispielskript umgeschrieben, dass ungefähr unter den gleichen Bedingungen läuft.

    Spoiler anzeigen
    [autoit]

    #include "GlPluginUtils.au3"
    #include <WindowsConstants.au3>
    #include <GUIConstantsEx.au3>
    #include <Misc.au3>
    dim $x=0
    dim $y=10
    dim $z=0
    dim $eyex=100
    dim $eyey=100
    dim $eyez=100
    dim $rotation=0
    dim $speed=5
    dim $pi = 3.14159265358979

    [/autoit] [autoit][/autoit] [autoit]

    HotKeySet( "{ESC}", "End" )

    [/autoit] [autoit][/autoit] [autoit]

    $WinTitle = "Meine OpenGL Beispiel Box"
    $hGUI = GUICreate($WinTitle, 800, 600)
    GUISetState(@SW_SHOW)
    EmbedGlWindow($hGUI, 818, 640, 0, 0)
    SetClearColor( 0.5, 0.5, 0.5 )

    [/autoit] [autoit][/autoit] [autoit]

    CreateLight( 0, 300, 300, 300 )
    SetLightAmbient( 0, 0.2, 0.2, 0.2 )
    SetLightDiffuse( 0, 0.7, 0.7, 0.7 )
    SetLightSpecular( 0, 1.0, 1.0, 1.0 )

    [/autoit] [autoit][/autoit] [autoit]

    $Cube1 = ObjectCreate( )
    AddCube( $Cube1, 60, 60, 60, 1, 0, 0, 1 )

    [/autoit] [autoit][/autoit] [autoit]

    $Plane = ObjectCreate( )
    AddCube( $Plane, 300, 300, 10, 0,0,1, 1.0 )

    [/autoit] [autoit][/autoit] [autoit]

    SetCameraUp( 0, 0, 1 )
    SetPrint( $Cube1 )
    SetPrint( $Plane )

    [/autoit] [autoit][/autoit] [autoit]

    While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
    Case $GUI_EVENT_CLOSE
    Exit
    EndSwitch
    $mouse = GUIGetCursorInfo($hGUI)
    ObjectTranslate($Cube1, $mouse[0], $mouse[1], 30)
    SceneDraw()
    _movecam(300)
    SetCamera($x + $eyex, $y + $eyey, $z + 400, $x, $y, $z)
    If WinActive($WinTitle) Then
    If _IsPressed("57") Then _move(-$speed);W
    If _IsPressed("53") Then _move($speed);s
    If _IsPressed("41") Then $rotation += 2;a
    If _IsPressed("44") Then $rotation -= 2;D
    If _IsPressed("11") Then $z = -10;Ctrl
    EndIf
    _CheckExit()
    WEnd
    Func _move($speedgo)
    $movex = -Cos((2 * $pi / 360) * ($rotation + 90)) * $speedgo
    $movey = -Sin((2 * $pi / 360) * ($rotation + 90)) * $speedgo
    $x += $movex
    $y += $movey
    EndFunc ;==>_move

    [/autoit] [autoit][/autoit] [autoit]

    Func _movecam($distance)
    $movex = -Cos((2 * $pi / 360) * ($rotation + 90)) * $distance
    $movey = -Sin((2 * $pi / 360) * ($rotation + 90)) * $distance
    $eyex = $movex
    $eyey = $movey
    EndFunc ;==>_movecam

    [/autoit] [autoit][/autoit] [autoit]

    Func _CheckExit()
    If Not WinExists($WinTitle) Then Exit
    EndFunc ;==>_CheckExit

    [/autoit] [autoit][/autoit] [autoit]

    Func End()
    Exit
    EndFunc ;==>End

    [/autoit]

    "Je mehr Käse, desto mehr Löcher; je mehr Löcher, desto weniger Käse. Ergo: Je mehr Käse, desto weniger Käse. 8| "
    "Programmers never die: they just GOSUB without RETURN"
    "I tried to change the world but I couldn't find the source code."

  • Hi, wenn ich das Problem richtig verstanden habe, funktioniert das nur, wenn du (wie in z.B. einem 3D-Spiel) ein eigenes Koordinatensystem verwendest, dass jeder Mausposition noch eine Z-Koordinate "dazuschreibt" bzw dazuberechnet.
    Wenn du in einem 3D-Raum auf einen (2D) Punkt klickst, dann muss das Programm diese Information der Z-Koordinate haben, ansonsten ist diese Koordinate immer 0 d.h. "Bildschirmoberflächenebene"

  • ein eigenes Koordinatensystem


    hm. ich verstehe nicht ganz, wie ich das machen soll/kann?

    "Je mehr Käse, desto mehr Löcher; je mehr Löcher, desto weniger Käse. Ergo: Je mehr Käse, desto weniger Käse. 8| "
    "Programmers never die: they just GOSUB without RETURN"
    "I tried to change the world but I couldn't find the source code."

  • Jeder Punkt in einem Raum wird durch eine X-, eine Y- und eine Z-Koordinate bestimmt. Deine Mauskoordinaten geben aber nur X und Y her! Damit dein Programm "weiß" welche Position im Raum du mit dem Mauszeiger meinst, musst du das natürlich dem Programm mitteilen. In der Regel werden diese Tiefenpositionen bzw Abstände zum Betrachter im sog. Z-Buffer als Schnittpunkt mit der nächsten sichtbaren Ebene dargestellt.
    Du musst eine Funktion finden bzw. aufrufen, die dir abhängig von deinen Mauskoordinaten die Z-Koordinate des Pixels an der Mausposition zurückgibt, dann hast du auch einen "Anfasser" für das 3D-Objekt.
    Ich habe aber aufgegeben, dein Beispielscript lauffähig zu bekommen, die Dateien u.a. von http://www.autoitscript.com/forum/index.php?showtopic=53575&view=findpost&p=405446 verursachen Fehlermeldungen

  • hm.. ich häng die Datei dann doch mal an. Wenn du x64 hast musst du unter x86 Autoit laufen lassen, weil die DLL Dateien unter x64 wohl nicht laufen.

    Dateien

    "Je mehr Käse, desto mehr Löcher; je mehr Löcher, desto weniger Käse. Ergo: Je mehr Käse, desto weniger Käse. 8| "
    "Programmers never die: they just GOSUB without RETURN"
    "I tried to change the world but I couldn't find the source code."

  • Ich verstehe nicht recht, was du möchtest. Wenn der Würfel sich parallel zur Maus bewegt ändern sich doch nur 2D-Koordinaten, also horizontale und vertikale Wertänderung. Die kannst du doch 1:1 von der Maus übernehmen. Du behältst also z bei und änderst analog zur Änderung der Mauswerte x und y deines Würfels.
    Zeig doch mal dein bisheriges Skript.


    hmmm. ich glaub BuxFix hat recht. Aber da man die Kamera bei mir rotieren kann, muss ich wohl noch die Rotation mitberechnen.

    "Je mehr Käse, desto mehr Löcher; je mehr Löcher, desto weniger Käse. Ergo: Je mehr Käse, desto weniger Käse. 8| "
    "Programmers never die: they just GOSUB without RETURN"
    "I tried to change the world but I couldn't find the source code."