Autor Beitrag
goose
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 93



BeitragVerfasst: So 23.03.08 23:43 
Hallo,

ich versuche die 3D Mauskoordinaten in OGL herauszufinden, hab damit aber meine Probleme:

Ich hab also ganz normal das simpleOpenGlControl auf der Form mit m_OglControl.InitializeContexts();
In Setview hab ich die Frustums so gesetzt :
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
            int width = m_OglControl.Width;
            int height = m_OglControl.Height;

            Gl.glEnable(Gl.GL_DEPTH_TEST);

            // Scenengröße anpassen
            Gl.glViewport(00, width, height);

            // Reset Matrix Stack
            Gl.glMatrixMode(Gl.GL_PROJECTION);
            Gl.glLoadIdentity();
            
            if (width <= height)
                Glu.gluPerspective(persp, height / width, 11000.0);
            else
                Glu.gluPerspective(persp, width / height, 11000.0);
            Gl.glMatrixMode(Gl.GL_MODELVIEW);
            Gl.glLoadIdentity();

        }


Ok, auf der Scene ist nur ein GitterNetz
von -180:90 bis +180:-90
Nun ist das Ziel das ich wenn ich mit der Maus über den Punkt -180:90 zb. fahre soll auch -180:90 angezeigt werden.
Das ganze funktioniert auch solange bis ich den Mittelpunkt der Scene mit glTransLatef(xxx,yyy,zzz) verschiebe.

So frage ich die Mausposition ab :
ausblenden volle Höhe C#-Quelltext
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:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
        void m_OglControl_MouseMove(object sender, MouseEventArgs e)
        {
            //Gl.glPushMatrix();
            //Gl.glLoadIdentity();
            //Gl.glTranslatef(0, 0, 0);

            double[] d = UnProject(e.X, e.Y, 1);
            Console.WriteLine("{0}:{1}:{2}",d[0], d[1], d[2]);

            int [] viewport = new int[4];
            double [] mvmatrix = new double[16];
            double[] projmatrix = new double[16];
                    
            double [] wcoord = new double[4];// wx, wy, wz;// returned xyz coords 
            double [] wcoord1 = new double[4];// wx, wy, wz;// returned xyz coords 
            double [] vector = new double[4];// wx, wy, wz;// returned xyz coords 

            int x = e.X; 
            int y = e.Y;


            Gl.glGetIntegerv(Gl.GL_VIEWPORT, viewport);
            Gl.glGetDoublev(Gl.GL_MODELVIEW_MATRIX, mvmatrix);
            Gl.glGetDoublev(Gl.GL_PROJECTION_MATRIX, projmatrix);

            /* note viewport[3] is height of window in pixels */
            double realy = viewport[3] - (int) y - 1;
            //Console.WriteLine("Coordinates at cursor are (" + x + ", " + realy);

            double objX, objY, objZ;
            double objX1, objY1, objZ1;
                   

            Glu.gluUnProject(
                (double) x,
                realy,//(double) y,
                0.0f,
                mvmatrix,
                projmatrix,
                viewport,
                out objX,
                out objY,
                out objZ);

            Glu.gluUnProject(
                (double)x,
                realy,//(double)y,
                1.0f,
                mvmatrix,
                projmatrix,
                viewport,
                out objX1,
                out objY1,
                out objZ1);

            glVector3F near = new glVector3F(objX, objY, objZ);
            glVector3F far = new glVector3F(objX1, objY1, objZ1);

            glVector3F direction = far - near;

            float zFactor = -near.Z / direction.Z;

            float resX = (far.X * zFactor) - m_AktCenter.X;
            float resY = (far.Y * zFactor) - m_AktCenter.Y;

            Console.WriteLine("zFactor: {0}", zFactor);
            Console.WriteLine("m_AktCenter.X: {0}", m_AktCenter.X);
            Console.WriteLine("near: {0}", near.X);
            Console.WriteLine("far: {0}", far.X);
            Console.WriteLine("Object: {0}:{1}:{2}", objX, objY, objZ);
            Console.WriteLine("Object1: {0}:{1}:{2}", objX1, objY1, objZ1);
            Console.WriteLine();
            Console.WriteLine("Result: {0}", resX);
            Console.WriteLine();

            Glu.gluUnProject(
                (double)x,
                (double)y,
                zFactor,
                mvmatrix,
                projmatrix,
                viewport,
                out objX1,
                out objY1,
                out objZ1);

            Console.WriteLine("Object1+1: {0}:{1}:{2}", objX1, objY1, objZ1);
            Console.WriteLine();
}


Weiß jemand wie ich das machen könnte ?

danke
Matthias
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: Mo 24.03.08 14:01 
Kannst du ein Testprojekt hochladen? Hab noch nie Tao benutzt, interessieren würde es mich aber.
goose Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 93



BeitragVerfasst: Di 25.03.08 00:56 
Hallo,

sorry hat ein bischen gedauert.
Hab ein neues Projekt dafür gemacht und allen schnick schnack weggelassen.

In der MouseOver Methode liegt der Hund begraben.

Ich hatte das auch schon mal mit DirectX versucht und dort ging es ein bischen besser. allerdings sind da wieder einige Dinge recht schwierig umzusetzen für das was ich machen will. In OGL hab ich das ganze schonmal mit Delphi gemacht, allerdings hatte ich das mit der Maus Position dort leider auch noch nicht hinbekommen.

In Direcct X ging es so :
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
            glVector3F near = new glVector3F(objX, objY, objZ);
            glVector3F far = new glVector3F(objX1, objY1, objZ1);
            float zFactor = -near.Z / direction.Z;

            float resX = (far.X * zFactor) - m_AktCenter.X;
            float resY = (far.Y * zFactor) - m_AktCenter.Y;


obj ist das gleiche wie in dem Beispiel.
glVector3F ist einfach eine Vector Klasse die ich als hilfsklasse gemacht habe weil es das in OGL nicht zu geben scheint, also nix besonderes.
m_AktCenter.X und Y ist halt die derzeitige Position die bei glTranslateF gesetzt wird.
resX und resY sind die Ergebnisse, die bei DirectX sogar stimmen nur bei OGL leider nicht.

Das Projekt ist in VS2008 gemahct. hoffe das geht bei Dir / Euch.

Zum Problem nochmal:

Das gitter geht von -180 bis +180 waagerecht und +90 bis -90 senkrecht und ist in 10er Schritten aufgeteilt.
Wenn man mit der Maus dann über das Gitter fährt, meinetwegen bei X:50 Y:30, sollte dies auch angezeigt werden können.
Das ganze müß natürlich auch noch fuinktionieren wenn glTranslateF verschoben wird.

Bsp: glTransLatef(10,10, -200) dann sollte trotzdem wenn man über den GitterPunkt x20:y10 fährt 20 und 10 ausgegeben werden !

Hoffe das ganze ist verständlich beschrieben ?

Hier das Projekt : www.starflight-va.de...TAO_Mouse_Test_1.rar

Ich danke Euch für die Hilfe !!

Matthias
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: Di 25.03.08 12:06 
Wenn ich das richtig sehe, war das Problem doch der "winZ"-Parameter in gluUnProject. Dann schreib das doch auch bitte so hin ;) .
Jedenfalls habe ich in Google das gefunden:
www.opengl.org/resou...aq/technical/glu.htm hat folgendes geschrieben:
4.070 How do I use gluProject() and gluUnProject()?

Both routines take a ModelView matrix, Projection matrix, and OpenGL Viewport as parameters.

gluProject() also takes an XYZ-object space coordinate. It returns the transformed XYZ window (or device) coordinate equivalent.

gluUnProject() does the opposite. It takes an XYZ window coordinate and returns the back-transformed XYZ object coordinate equivalent.

The concept of window space Z is often confusing. It's the depth buffer value expressed as a GLdouble in the range 0.0 to 1.0. Assuming a default glDepthRange(), a window coordinate with a Z value of 0.0 corresponds to an eye coordinate located on the zNear clipping plane. Similarly, a window space Z value of 1.0 corresponds to an eye space coordinate located on the zFar plane. You can obtain any window space Z value by reading the depth buffer with glReadPixels().

Du kannst also entweder den Depth-Buffer benutzen:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
        object winZ = 0f;
      Gl.glReadPixels(x, y, 11, Gl.GL_DEPTH_COMPONENT, Gl.GL_FLOAT, winZ);

            Glu.gluUnProject(
                (double)x,
                realy,//(double) y,
                (float)winZ,
                mvmatrix,
                projmatrix,
                viewport,
                out objX,
                out objY,
                out objZ);

Dann muss man aber natürlich genau auf eine Linie zeigen oder noch eine schwarze Ebene direkt hinter das Gitter einfügen. Daher bin ich eher für diese nette Formel ;) :
ausblenden C#-Quelltext
1:
2:
double zDistance = -m_z; // Abstand von der Eye-Plane => http://www.cs.unc.edu/~hoff/techrep/openglz.html
double winZ = (1 / nearPlane - 1 / zDistance) / (1 / nearPlane - 1 / farPlane);

Dann musst du nur noch deine Translation berücksichtigen:
ausblenden C#-Quelltext
1:
2:
3:
tbOBJ_1_X.Text = (objX - m_x).ToString();
tbOBJ_1_Y.Text = (objY - m_y).ToString();
tbOBJ_1_Z.Text = (objZ - m_z).ToString();


Nett, aber doch etwas low-levelig ;) . Gegen ein wenig Abstraktion wie bei mDX hätte ich nichts einzuwenden, wenn ich aber irgendwann einmal etwas mit 3D machen sollte, wird es wohl trotzdem Tao sein.
goose Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 93



BeitragVerfasst: Di 25.03.08 18:59 
Hallo,

also ich bin mir jetzt nicht ganz sicher ob das so richtig ist, denn so geht es nicht :

ausblenden volle Höhe C#-Quelltext
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:
        private void simpleOpenGlControl1_MouseMove(object sender, MouseEventArgs e)
        {
            double zDistance = -m_z; // Abstand von der Eye-Plane => http://www.cs.unc.edu/~hoff/techrep/openglz.html  
            double winZ = (1 / 0.1 - 1 / zDistance) / (1 / 0.1 - 1 / 1001);

            int[] viewport = new int[4];
            double[] mvmatrix = new double[16];
            double[] projmatrix = new double[16];

            Gl.glGetIntegerv(Gl.GL_VIEWPORT, viewport);
            Gl.glGetDoublev(Gl.GL_MODELVIEW_MATRIX, mvmatrix);
            Gl.glGetDoublev(Gl.GL_PROJECTION_MATRIX, projmatrix);

            int x = e.X;
            int y = e.Y;
            double realy = viewport[3] - y - 1;
            double objX, objY, objZ;

            Glu.gluUnProject(
                (double)x,
                realy,//(double)y,//
                winZ,//1.0f,
                mvmatrix,
                projmatrix,
                viewport,
                out objX,
                out objY,
                out objZ);

            tbOBJ_1_X.Text = (objX - m_x).ToString();
            tbOBJ_1_Y.Text = (objY - m_y).ToString();
            tbOBJ_1_Z.Text = (objZ - m_z).ToString(); 
        }


Hab ich da irgendwas falsch verstanden ?
Hast Du das mal so ausprobiert und ging das bei Dir so ?

Matthias
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: Di 25.03.08 20:55 
user profile icongoose hat folgendes geschrieben:
Hast Du das mal so ausprobiert und ging das bei Dir so ?

Joa :/ .
Einloggen, um Attachments anzusehen!
goose Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 93



BeitragVerfasst: Mi 26.03.08 10:32 
Hallöchen,

dank Dir für die Hilfe, genial !!!

Aus irgendeinem Grund muß ich bei mir das Ergebnis *2 multiplizieren, warum ist mir noch nicht wirklich kla, geht aber !!

Dummerweise stehe ich vor dem nächsten Problem. Auf meiner "Erde" müssen ja nun auch diverse Sachen dargestellt werden. Da es um die Fliegerei geht sind es wegpunkte, Airports usw.
Ich hab das schonmal mit GDI+ versucht, bin da aber auch an den Wegpunkten ( sogenannte ISEC ) gescheitert.
Zum anschauen hab ich Dir das Projekt mal hochgeladen:

www.starflight-va.de.../FlightPlanner_2.rar

Das problem bei OGL ist den Text auszugeben, wie auch bei GDI dummerweise.
Bei GDI ist der GraphicsPath für grafiken recht gut, für text sehr langsam.
Bei OGL is es das gleiche mit den Displaylisten.

Problem ist das die Datei über 177000 Wegpunkte enthält:
www.starflight-va.de/TAO/ISEC.txt

Ich hab schon übelegt die in eine Liste zu packen und dann nur die sichtbaren darzustellen, aber da muß ich ja auch die ganze Liste dürchsuchen was lange dauert, zu lange.

Hast Du ne Idee wie man das machen könnte ?

Matthias