久久久久久久av_日韩在线中文_看一级毛片视频_日本精品二区_成人深夜福利视频_武道仙尊动漫在线观看

  • <i id='lbM4a'><tr id='lbM4a'><dt id='lbM4a'><q id='lbM4a'><span id='lbM4a'><b id='lbM4a'><form id='lbM4a'><ins id='lbM4a'></ins><ul id='lbM4a'></ul><sub id='lbM4a'></sub></form><legend id='lbM4a'></legend><bdo id='lbM4a'><pre id='lbM4a'><center id='lbM4a'></center></pre></bdo></b><th id='lbM4a'></th></span></q></dt></tr></i><div class="qwawimqqmiuu" id='lbM4a'><tfoot id='lbM4a'></tfoot><dl id='lbM4a'><fieldset id='lbM4a'></fieldset></dl></div>
  • <tfoot id='lbM4a'></tfoot>

      <bdo id='lbM4a'></bdo><ul id='lbM4a'></ul>

    <small id='lbM4a'></small><noframes id='lbM4a'>

        <legend id='lbM4a'><style id='lbM4a'><dir id='lbM4a'><q id='lbM4a'></q></dir></style></legend>
      1. 計算用箭頭和鼠標移動的對象

        Compute objects moving with arrows and mouse(計算用箭頭和鼠標移動的對象)
        <tfoot id='EPhyB'></tfoot>
        <legend id='EPhyB'><style id='EPhyB'><dir id='EPhyB'><q id='EPhyB'></q></dir></style></legend>
          <tbody id='EPhyB'></tbody>

        <i id='EPhyB'><tr id='EPhyB'><dt id='EPhyB'><q id='EPhyB'><span id='EPhyB'><b id='EPhyB'><form id='EPhyB'><ins id='EPhyB'></ins><ul id='EPhyB'></ul><sub id='EPhyB'></sub></form><legend id='EPhyB'></legend><bdo id='EPhyB'><pre id='EPhyB'><center id='EPhyB'></center></pre></bdo></b><th id='EPhyB'></th></span></q></dt></tr></i><div class="qwawimqqmiuu" id='EPhyB'><tfoot id='EPhyB'></tfoot><dl id='EPhyB'><fieldset id='EPhyB'></fieldset></dl></div>

          • <small id='EPhyB'></small><noframes id='EPhyB'>

                <bdo id='EPhyB'></bdo><ul id='EPhyB'></ul>

                • 本文介紹了計算用箭頭和鼠標移動的對象的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學習吧!

                  問題描述

                  我正在用 openGL 做一個 Maya 模擬器應用程序,一切進展順利.只有一個麻煩,我無法通過鼠標計算移動對象的 100% 準確度.我正在使用 3D 坐標中的箭頭和屏幕坐標中的箭頭的縮放比例,并將其與一些縮放比例相乘以計算屏幕坐標 x 和 y 方向上的運動程度..但是這些計算并沒有給出很高的準確度,鼠標偏離了箭頭.我需要它總是在移動的箭頭上,這意味著準確度幾乎是 100%任何對此問題有想法或意見的人將永遠不勝感激

                  這是我嘗試的一些代碼:

                  gluProject((GLdouble)x3DVertex, (GLdouble)y3DVertex, (GLdouble)z3DVertex, modelMatrix, projectMatrix, viewport, &xScreenVertex, &yScreenVertex, &zScreenVertex);如果(軸 == 0){gluProject((GLdouble)x3DVertex + 1, (GLdouble)y3DVertex, (GLdouble)z3DVertex, modelMatrix, projectMatrix, viewport, &xScreenArrow, &yScreenArrow, &zScreenArrow);}否則如果(軸 == 1){gluProject((GLdouble)x3DVertex, (GLdouble)y3DVertex + 1, (GLdouble)z3DVertex, modelMatrix, projectMatrix, viewport, &xScreenArrow, &yScreenArrow, &zScreenArrow);}別的{gluProject((GLdouble)x3DVertex, (GLdouble)y3DVertex, (GLdouble)z3DVertex + 1, modelMatrix, projectMatrix, viewport, &xScreenArrow, &yScreenArrow, &zScreenArrow);}float totalScaleXY = abs(xScreenArrow - xScreenVertex) + abs(yScreenArrow - yScreenVertex);scaleX = abs(xScreenArrow - xScreenVertex)/totalScaleXY;scaleY = abs(yScreenArrow - yScreenVertex)/totalScaleXY;float lengthArrowOnScreen = sqrt(pow((xScreenArrow - xScreenVertex), 2) + pow((yScreenArrow - yScreenVertex), 2));scale3dAndScreen = 1/lengthArrowOnScreen;

                  這是我正在測試的代碼,不是很準確

                  解決方案

                  這里有一個丑陋但非常簡單的 C++ 示例,說明我對此的想法:

                  //---------------------------------------------------------------------#include #include <math.h>#pragma hdrstop#include "Unit1.h"#include "gl_simple.h"http://---------------------------------------------------------------------------#pragma 包(smart_init)#pragma 資源*.dfm"TForm1 *Form1;//---------------------------------------------------------------------------雙 mview[16],mmodel[16],mproj[16];//OpenGL矩陣//---------------------------------------------------------------------------//向量/矩陣數學//---------------------------------------------------------------------------double vector_len(double *a) { return sqrt((a[0]*a[0])+(a[1]*a[1])+(a[2]*a[2]));}//= |向量[3]|void vector_sub(double *c,double *a,double *b) { for (int i=0;i<3;i++) c[i]=a[i]-b[i];}//c[3] = a[3] - b[3]void matrix_mul(double *c,double *a,double *b)//c[4x4] = a[4x4] * b [4x4]{雙 q[16];q[0]=(a[0]*b[0])+(a[1]*b[4])+(a[2]*b[8])+(a[3]*b[12]]);q[1]=(a[0]*b[1])+(a[1]*b[5])+(a[2]*b[9])+(a[3]*b[13]]);q[2]=(a[0]*b[2])+(a[1]*b[6])+(a[2]*b[10])+(a[3]*b[14]]);q[3]=(a[0]*b[3])+(a[1]*b[7])+(a[2]*b[11])+(a[3]*b[15]]);q[4]=(a[4]*b[0])+(a[5]*b[4])+(a[6]*b[8])+(a[7]*b[12]]);q[5]=(a[4]*b[1])+(a[5]*b[5])+(a[6]*b[9])+(a[7]*b[13]]);q[6]=(a[4]*b[2])+(a[5]*b[6])+(a[6]*b[10])+(a[7]*b[14]]);q[7]=(a[4]*b[3])+(a[5]*b[7])+(a[6]*b[11])+(a[7]*b[15]]);q[8]=(a[8]*b[0])+(a[9]*b[4])+(a[10]*b[8])+(a[11]*b[12]]);q[9]=(a[8]*b[1])+(a[9]*b[5])+(a[10]*b[9])+(a[11]*b[13]]);q[10]=(a[8]*b[2])+(a[9]*b[6])+(a[10]*b[10])+(a[11]*b[14]]);q[11]=(a[8]*b[3])+(a[9]*b[7])+(a[10]*b[11])+(a[11]*b[15]]);q[12]=(a[12]*b[0])+(a[13]*b[4])+(a[14]*b[8])+(a[15]*b[12]]);q[13]=(a[12]*b[1])+(a[13]*b[5])+(a[14]*b[9])+(a[15]*b[13]]);q[14]=(a[12]*b[2])+(a[13]*b[6])+(a[14]*b[10])+(a[15]*b[14]]);q[15]=(a[12]*b[3])+(a[13]*b[7])+(a[14]*b[11])+(a[15]*b[15]]);for(int i=0;i<16;i++) c[i]=q[i];}void matrix_mul_vector(double *c,double *a,double *b)//c[3] = a[4x4] * (b[3],1){雙 q[3];q[0]=(a[0]*b[0])+(a[4]*b[1])+(a[8]*b[2])+(a[12]);q[1]=(a[1]*b[0])+(a[5]*b[1])+(a[9]*b[2])+(a[13]);q[2]=(a[2]*b[0])+(a[6]*b[1])+(a[10]*b[2])+(a[14]);for(int i=0;i<3;i++) c[i]=q[i];}//---------------------------------------------------------------------------class DragDrop3D//箭頭平移控件(每個對象都需要一個){上市:雙*毫米;//模型矩陣雙*mv;//查看矩陣雙*mp;//投影矩陣雙o[3];//起點雙 l[3];//箭頭的長度雙 a, b;//箭頭的大小 a 長 b 寬/2內部選擇;//選擇的軸DragDrop3D(){毫米=空;mv=空;mp=空;o[0]=-1.0;l[0]=3.5;a=0.5;o[1]=-1.0;l[1]=3.5;b=0.25;o[2]=-1.0;l[2]=3.5;sel=-1;}DragDrop3D(DragDrop3D& a) { *this=a;}~DragDrop3D() {}DragDrop3D* operator = (const DragDrop3D *a) { *this=*a;返回這個;}//DragDrop3D* operator = (const DragDrop3D &a) { ...copy... return this;}void project(double *scr,double *mmvp,double *obj)//obj ->可控硅{matrix_mul_vector(scr,mmvp,obj);如果 (fabs(scr[2])>1e-10) scr[2]=1.0/scr[2];否則 scr[2]=0.0;scr[0]*=scr[2];scr[1]*=scr[2];}void draw()//渲染箭頭{國際;雙角,當=2.0*M_PI/36.0,u0,u1,v0,v1,q=1.0/sqrt((a*a)+(b*b));//軸線glBegin(GL_LINES);glColor3f(1.0,0.0,0.0);glVertex3dv(o);glVertex3d(o[0]+l[0],o[1],o[2]);glColor3f(0.0,1.0,0.0);glVertex3dv(o);glVertex3d(o[0],o[1]+l[1],o[2]);glColor3f(0.0,0.0,1.0);glVertex3dv(o);glVertex3d(o[0],o[1],o[2]+l[2]);glEnd();//錐體glBegin(GL_TRIANGLES);u1=b*cos(-dang);v1=b*sin(-dang);對于 (e=1,ang=0.0;e;ang+=dang){如果 (ang>=2.0*M_PI) { ang=2.0*M_PI;e=0;}u0=u1;u1=b*cos(ang);v0=v1;v1=b*sin(ang);//Xif (sel==0) glColor3f(1.0,0.0,0.0);否則 glColor3f(0.5,0.1,0.1);glNormal3f(a*q,(u0+u1)*0.5*q,(v0+v1)*0.5*q);glVertex3d(o[0]+l[0],o[1],o[2]);glVertex3d(o[0]+l[0]-a,o[1]+u0,o[2]+v0);glVertex3d(o[0]+l[0]-a,o[1]+u1,o[2]+v1);glNormal3f(-1.0,0.0,0.0);glVertex3d(o[0]+l[0]-a,o[1],o[2]);glVertex3d(o[0]+l[0]-a,o[1]+u1,o[2]+v1);glVertex3d(o[0]+l[0]-a,o[1]+u0,o[2]+v0);//是if (sel==1) glColor3f(0.0,1.0,0.0);否則 glColor3f(0.1,0.5,0.1);glNormal3f((u0+u1)*0.5*q,a*q,(v0+v1)*0.5*q);glVertex3d(o[0],o[1]+l[1],o[2]);glVertex3d(o[0]+u1,o[1]+l[1]-a,o[2]+v1);glVertex3d(o[0]+u0,o[1]+l[1]-a,o[2]+v0);glNormal3f(0.0,-1.0,0.0);glVertex3d(o[0],o[1]+l[1]-a,o[2]);glVertex3d(o[0]+u0,o[1]+l[1]-a,o[2]+v0);glVertex3d(o[0]+u1,o[1]+l[1]-a,o[2]+v1);//Zif (sel==2) glColor3f(0.0,0.0,1.0);否則 glColor3f(0.1,0.1,0.5);glNormal3f((v0+v1)*0.5*q,(u0+u1)*0.5*q,a*q);glVertex3d(o[0],o[1],o[2]+l[2]);glVertex3d(o[0]+v1,o[1]+u1,o[2]+l[2]-a);glVertex3d(o[0]+v0,o[1]+u0,o[2]+l[2]-a);glNormal3f(0.0,0.0,-1.0);glVertex3d(o[0] ,o[1] ,o[2]+l[2]-a);glVertex3d(o[0]+v0,o[1]+u0,o[2]+l[2]-a);glVertex3d(o[0]+v1,o[1]+u1,o[2]+l[2]-a);}glEnd();}bool mouse(double mx,double my,TShiftState sh)//如果需要重繪則處理鼠標事件返回{if ((mm==NULL)||(mv==NULL)||(mp==NULL)) 返回假;國際ql;雙 p[3],mmvp[16];布爾_重繪=假;//MVP = M*V*Pmatrix_mul(mmvp,mm,mv);matrix_mul(mmvp,mmvp,mp);//將屏幕坐標轉換為<-1,+1>GL 國家數據中心mx= (2.0*mx/double(xs))-1.0;my=1.0-(2.0*my/double(ys)) ;//鼠標左鍵狀態 (last,actual)ql=sh.Contains(ssLeft);//選擇(無鼠標按鈕)如果(!ql){int sel0=sel;sel=-1;//箭頭中心屏幕x,y距離鼠標選擇如果關閉p[0]=o[0]+l[0]-0.5*a;p[1]=o[1];p[2]=o[2];項目(p,mmvp,p);p[0]-=mx;p[1]-=我的;p[2]=0.0;如果 (vector_len(p)<=0.5*b) sel=0;//Xp[1]=o[1]+l[1]-0.5*a;p[0]=o[0];p[2]=o[2];項目(p,mmvp,p);p[0]-=mx;p[1]-=我的;p[2]=0.0;如果 (vector_len(p)<=0.5*b) sel=1;//是p[2]=o[2]+l[2]-0.5*a;p[1]=o[1];p[0]=o[0];項目(p,mmvp,p);p[0]-=mx;p[1]-=我的;p[2]=0.0;如果 (vector_len(p)<=0.5*b) sel=2;//Z_redraw=(sel0!=sel);}//將箭頭中心拖動到鼠標位置(活動按鈕)如果 ((ql)&&(sel>=0)&&(sel<3)){國際我;雙len0,len;雙 p0[3],dp[3]={0.0,0.0,0.0},t,dt,q[3]={mx,my,0.0};//選定的箭頭位置、方向對于 (i=0;i<3;i++) p0[i]=o[i];p0[sel]+=l[sel]-0.5*a;dp[sel]=1.0;//軸/鼠標_射線之間的最近"交點對于 (len0=-1.0,t=0.0,dt=1.0;fabs(dt)>1e-5;t+=dt){//軸上的位置 p(t) = p0 + t*dp對于 (i=0;i<3;i++) p[i]=p0[i]+(t*dp[i]);//len = 到鼠標的距離項目(p,mmvp,p);vector_sub(p,p,q);p[2]=0.0;len=vector_len(p);//處理迭代步驟如果 (len0<-0.5) len0=len;如果 (len>len0) dt=-0.1*dt;len0=len;}//由 t 翻譯雙 m[16]={1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0,};m[12+sel]=t;matrix_mul(mm,m,mm);_重繪=真;}返回_重繪;}};//---------------------------------------------------------------------------DragDrop3D ctrl;//我得到了一個立方體,所以單箭頭拖放控制就足夠了//---------------------------------------------------------------------------void gl_draw()//主要渲染代碼{glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);glEnable(GL_CULL_FACE);glEnable(GL_LIGHTING);glEnable(GL_LIGHT0);glEnable(GL_COLOR_MATERIAL);//在里面靜態布爾_init =真;如果(_init){_init=假;//M,V 初始化矩陣glMatrixMode(GL_MODELVIEW);glPushMatrix();glLoadIdentity();glTranslated(0.0,0.0,-25.0);glGetDoublev(GL_MODELVIEW_MATRIX,mview);glLoadIdentity();glTranslated(-2.0,-1.0,-1.0);glRotated(-35.0,0.0,1.0,0.0);glGetDoublev(GL_MODELVIEW_MATRIX,mmodel);glPopMatrix();//矩陣 ->控制glGetDoublev(GL_PROJECTION_MATRIX,mproj);ctrl.mp=mproj;ctrl.mv=mview;ctrl.mm=mmodel;}//矩陣 ->OpenGLglMatrixMode(GL_MODELVIEW);glLoadMatrixd(mview);glMultMatrixd(mmodel);//繪制 VAO 立方體ctrl.draw();vao_draw();//這里渲染你的對象glFlush();交換緩沖區(hdc);}//---------------------------------------------------------------------------__fastcall TForm1::TForm1(TComponent* Owner):TForm(Owner){//應用初始化gl_init(句柄);vao_init();}//---------------------------------------------------------------------------void __fastcall TForm1::FormDestroy(TObject *Sender){//應用程序退出gl_exit();vao_exit();}//---------------------------------------------------------------------------void __fastcall TForm1::FormResize(TObject *Sender){//調整窗口大小gl_resize(ClientWidth,ClientHeight);}//---------------------------------------------------------------------------void __fastcall TForm1::FormPaint(TObject *Sender){//窗口重繪gl_draw();}//---------------------------------------------------------------------------void __fastcall TForm1::FormMouseWheel(TObject *Sender, TShiftState Shift, int WheelDelta, TPoint &MousePos, bool &Handled){//鼠標滾輪平移相機(如縮放)GLfloat dz=2.0;如果 (WheelDelta<0) dz=-dz;glMatrixMode(GL_MODELVIEW);glPushMatrix();glLoadMatrixd(mview);glTranslatef(0,0,dz);glGetDoublev(GL_MODELVIEW_MATRIX,mview);glPopMatrix();gl_draw();}//---------------------------------------------------------------------------//鼠標事件void __fastcall TForm1::FormMouseDown(TObject *Sender, TMouseButton Button,TShiftState Shift, int X, int Y) { if (ctrl.mouse(X,Y,Shift)) gl_draw();}void __fastcall TForm1::FormMouseUp(TObject *Sender, TMouseButton Button,TShiftState Shift, int X, int Y) { if (ctrl.mouse(X,Y,Shift)) gl_draw();}void __fastcall TForm1::FormMouseMove(TObject *Sender, TShiftState Shift, int X, int Y) { if (ctrl.mouse(X,Y,Shift)) gl_draw();}//---------------------------------------------------------------------------

                  它基于此:

                  遺憾的是我的 GIF 捕獲 SW 沒有捕獲鼠標光標,但它完全匹配移動.

                  我懶得直接計算軸之間的交集,而是迭代以找到最接近的匹配(那個 for 循環和 dt).那部分可以用相交方程代替.

                  軸以對象坐標系 (mm,mmodel) 的 x、y、z 軸為界.

                  對于更多的對象,您還應該添加鎖,以便只能選擇一個對象...

                  PS. 見相關:- OpenGL 射線 OBB 交集

                  I am doing a maya simulator application with openGL, everything is progressing pretty well. Just have only one trouble, i can not calculate 100% accuracy of moving object by mouse. I'm using the scaling of arrows in 3D coordinates and arrows in the screen coordinates and multiplying it with some scaling to calculate the degree of motion in the x and y direction of the screen coordinates. . But these calculations do not give high accuracy, the mouse is deviated from the arrow. I need it always on the moving arrows, meaning that the accuracy is almost 100% Anyone who has ideas or comments on this issue will always be appreciated

                  This is some code i try:

                  gluProject((GLdouble)x3DVertex, (GLdouble)y3DVertex, (GLdouble)z3DVertex, modelMatrix, projectMatrix, viewport, &xScreenVertex, &yScreenVertex, &zScreenVertex);
                  
                  if (axis == 0)
                  {
                  gluProject((GLdouble)x3DVertex + 1, (GLdouble)y3DVertex, (GLdouble)z3DVertex, modelMatrix, projectMatrix, viewport, &xScreenArrow, &yScreenArrow, &zScreenArrow);
                  }
                  else if (axis == 1)
                  {
                  gluProject((GLdouble)x3DVertex, (GLdouble)y3DVertex + 1, (GLdouble)z3DVertex, modelMatrix, projectMatrix, viewport, &xScreenArrow, &yScreenArrow, &zScreenArrow);
                  }
                  else
                  {
                  gluProject((GLdouble)x3DVertex, (GLdouble)y3DVertex, (GLdouble)z3DVertex + 1, modelMatrix, projectMatrix, viewport, &xScreenArrow, &yScreenArrow, &zScreenArrow);
                  }
                  float totalScaleXY = abs(xScreenArrow - xScreenVertex) + abs(yScreenArrow - yScreenVertex);
                  scaleX = abs(xScreenArrow - xScreenVertex) / totalScaleXY;
                  scaleY = abs(yScreenArrow - yScreenVertex) / totalScaleXY;
                  float lengthArrowOnScreen = sqrt(pow((xScreenArrow - xScreenVertex), 2) + pow((yScreenArrow - yScreenVertex), 2));
                  scale3dAndScreen = 1 / lengthArrowOnScreen;
                  

                  This is the code I'm testing, it's not very accurate

                  解決方案

                  Here small ugly but very simple C++ example of what I had in mind for this:

                  //---------------------------------------------------------------------------
                  #include <vcl.h>
                  #include <math.h>
                  #pragma hdrstop
                  #include "Unit1.h"
                  #include "gl_simple.h"
                  //---------------------------------------------------------------------------
                  #pragma package(smart_init)
                  #pragma resource "*.dfm"
                  TForm1 *Form1;
                  //---------------------------------------------------------------------------
                  double mview[16],mmodel[16],mproj[16];  // OpenGL matrices
                  //---------------------------------------------------------------------------
                  // vector/matrix math
                  //---------------------------------------------------------------------------
                  double vector_len(double *a) { return sqrt((a[0]*a[0])+(a[1]*a[1])+(a[2]*a[2])); }          // = |vector[3]|
                  void   vector_sub(double *c,double *a,double *b) { for (int i=0;i<3;i++) c[i]=a[i]-b[i]; }  // c[3] = a[3] - b[3]
                  void   matrix_mul(double *c,double *a,double *b)                                            // c[4x4] = a[4x4] * b [4x4]
                      {
                      double q[16];
                      q[ 0]=(a[ 0]*b[ 0])+(a[ 1]*b[ 4])+(a[ 2]*b[ 8])+(a[ 3]*b[12]);
                      q[ 1]=(a[ 0]*b[ 1])+(a[ 1]*b[ 5])+(a[ 2]*b[ 9])+(a[ 3]*b[13]);
                      q[ 2]=(a[ 0]*b[ 2])+(a[ 1]*b[ 6])+(a[ 2]*b[10])+(a[ 3]*b[14]);
                      q[ 3]=(a[ 0]*b[ 3])+(a[ 1]*b[ 7])+(a[ 2]*b[11])+(a[ 3]*b[15]);
                      q[ 4]=(a[ 4]*b[ 0])+(a[ 5]*b[ 4])+(a[ 6]*b[ 8])+(a[ 7]*b[12]);
                      q[ 5]=(a[ 4]*b[ 1])+(a[ 5]*b[ 5])+(a[ 6]*b[ 9])+(a[ 7]*b[13]);
                      q[ 6]=(a[ 4]*b[ 2])+(a[ 5]*b[ 6])+(a[ 6]*b[10])+(a[ 7]*b[14]);
                      q[ 7]=(a[ 4]*b[ 3])+(a[ 5]*b[ 7])+(a[ 6]*b[11])+(a[ 7]*b[15]);
                      q[ 8]=(a[ 8]*b[ 0])+(a[ 9]*b[ 4])+(a[10]*b[ 8])+(a[11]*b[12]);
                      q[ 9]=(a[ 8]*b[ 1])+(a[ 9]*b[ 5])+(a[10]*b[ 9])+(a[11]*b[13]);
                      q[10]=(a[ 8]*b[ 2])+(a[ 9]*b[ 6])+(a[10]*b[10])+(a[11]*b[14]);
                      q[11]=(a[ 8]*b[ 3])+(a[ 9]*b[ 7])+(a[10]*b[11])+(a[11]*b[15]);
                      q[12]=(a[12]*b[ 0])+(a[13]*b[ 4])+(a[14]*b[ 8])+(a[15]*b[12]);
                      q[13]=(a[12]*b[ 1])+(a[13]*b[ 5])+(a[14]*b[ 9])+(a[15]*b[13]);
                      q[14]=(a[12]*b[ 2])+(a[13]*b[ 6])+(a[14]*b[10])+(a[15]*b[14]);
                      q[15]=(a[12]*b[ 3])+(a[13]*b[ 7])+(a[14]*b[11])+(a[15]*b[15]);
                      for(int i=0;i<16;i++) c[i]=q[i];
                      }
                  void   matrix_mul_vector(double *c,double *a,double *b)                                     // c[3] = a[4x4] * (b[3],1)
                      {
                      double q[3];
                      q[0]=(a[ 0]*b[0])+(a[ 4]*b[1])+(a[ 8]*b[2])+(a[12]);
                      q[1]=(a[ 1]*b[0])+(a[ 5]*b[1])+(a[ 9]*b[2])+(a[13]);
                      q[2]=(a[ 2]*b[0])+(a[ 6]*b[1])+(a[10]*b[2])+(a[14]);
                      for(int i=0;i<3;i++) c[i]=q[i];
                      }
                  //---------------------------------------------------------------------------
                  class DragDrop3D        // arrow translation controls (you need one for each objet)
                      {
                  public:
                      double *mm;         // model matrix
                      double *mv;         // view matrix
                      double *mp;         // projection matrix
                  
                      double o[3];        // start point
                      double l[3];        // length of the arrows
                      double a,b;         // size of the arrow head a length, b width/2
                      int sel;            // selected axis
                  
                      DragDrop3D()
                          {
                          mm=NULL; mv=NULL; mp=NULL;
                          o[0]=-1.0; l[0]=3.5; a=0.5;
                          o[1]=-1.0; l[1]=3.5; b=0.25;
                          o[2]=-1.0; l[2]=3.5; sel=-1;
                          }
                      DragDrop3D(DragDrop3D& a)   { *this=a; }
                      ~DragDrop3D()   {}
                      DragDrop3D* operator = (const DragDrop3D *a) { *this=*a; return this; }
                      //DragDrop3D* operator = (const DragDrop3D &a) { ...copy... return this; }
                  
                      void project(double *scr,double *mmvp,double *obj)  // obj -> scr
                          {
                          matrix_mul_vector(scr,mmvp,obj);
                          if (fabs(scr[2])>1e-10) scr[2]=1.0/scr[2]; else scr[2]=0.0;
                          scr[0]*=scr[2];
                          scr[1]*=scr[2];
                          }
                      void draw() // render arrows
                          {
                          int e;
                          double ang,dang=2.0*M_PI/36.0,u0,u1,v0,v1,q=1.0/sqrt((a*a)+(b*b));
                          // axis lines
                          glBegin(GL_LINES);
                          glColor3f(1.0,0.0,0.0); glVertex3dv(o); glVertex3d(o[0]+l[0],o[1],o[2]);
                          glColor3f(0.0,1.0,0.0); glVertex3dv(o); glVertex3d(o[0],o[1]+l[1],o[2]);
                          glColor3f(0.0,0.0,1.0); glVertex3dv(o); glVertex3d(o[0],o[1],o[2]+l[2]);
                          glEnd();
                          // cones
                          glBegin(GL_TRIANGLES);
                          u1=b*cos(-dang);
                          v1=b*sin(-dang);
                          for (e=1,ang=0.0;e;ang+=dang)
                              {
                              if (ang>=2.0*M_PI) { ang=2.0*M_PI; e=0; }
                              u0=u1; u1=b*cos(ang);
                              v0=v1; v1=b*sin(ang);
                              // X
                              if (sel==0) glColor3f(1.0,0.0,0.0); else glColor3f(0.5,0.1,0.1);
                              glNormal3f(a*q,(u0+u1)*0.5*q,(v0+v1)*0.5*q);
                              glVertex3d(o[0]+l[0]  ,o[1]   ,o[2]   );
                              glVertex3d(o[0]+l[0]-a,o[1]+u0,o[2]+v0);
                              glVertex3d(o[0]+l[0]-a,o[1]+u1,o[2]+v1);
                              glNormal3f(-1.0,0.0,0.0);
                              glVertex3d(o[0]+l[0]-a,o[1],o[2]);
                              glVertex3d(o[0]+l[0]-a,o[1]+u1,o[2]+v1);
                              glVertex3d(o[0]+l[0]-a,o[1]+u0,o[2]+v0);
                              // Y
                              if (sel==1) glColor3f(0.0,1.0,0.0); else glColor3f(0.1,0.5,0.1);
                              glNormal3f((u0+u1)*0.5*q,a*q,(v0+v1)*0.5*q);
                              glVertex3d(o[0]   ,o[1]+l[1]  ,o[2]   );
                              glVertex3d(o[0]+u1,o[1]+l[1]-a,o[2]+v1);
                              glVertex3d(o[0]+u0,o[1]+l[1]-a,o[2]+v0);
                              glNormal3f(0.0,-1.0,0.0);
                              glVertex3d(o[0]   ,o[1]+l[1]-a,o[2]   );
                              glVertex3d(o[0]+u0,o[1]+l[1]-a,o[2]+v0);
                              glVertex3d(o[0]+u1,o[1]+l[1]-a,o[2]+v1);
                              // Z
                              if (sel==2) glColor3f(0.0,0.0,1.0); else glColor3f(0.1,0.1,0.5);
                              glNormal3f((v0+v1)*0.5*q,(u0+u1)*0.5*q,a*q);
                              glVertex3d(o[0]   ,o[1]   ,o[2]+l[2]  );
                              glVertex3d(o[0]+v1,o[1]+u1,o[2]+l[2]-a);
                              glVertex3d(o[0]+v0,o[1]+u0,o[2]+l[2]-a);
                              glNormal3f(0.0,0.0,-1.0);
                              glVertex3d(o[0]   ,o[1]   ,o[2]+l[2]-a);
                              glVertex3d(o[0]+v0,o[1]+u0,o[2]+l[2]-a);
                              glVertex3d(o[0]+v1,o[1]+u1,o[2]+l[2]-a);
                              }
                          glEnd();
                          }
                      bool mouse(double mx,double my,TShiftState sh)  // handle mouse events return if redraw is needed
                          {
                          if ((mm==NULL)||(mv==NULL)||(mp==NULL)) return false;
                          int ql; double p[3],mmvp[16]; bool _redraw=false;
                          // MVP = M*V*P
                          matrix_mul(mmvp,mm,mv);
                          matrix_mul(mmvp,mmvp,mp);
                          // convert screen coords to <-1,+1> GL NDC
                          mx=    (2.0*mx/double(xs))-1.0;
                          my=1.0-(2.0*my/double(ys))    ;
                          // mouse left button state (last,actual)
                          ql=sh.Contains(ssLeft);
                          // select (no mouse button)
                          if (!ql)
                              {
                              int sel0=sel; sel=-1;
                              // arrowhead center                         screen x,y    distance to mouse               select if close
                              p[0]=o[0]+l[0]-0.5*a; p[1]=o[1]; p[2]=o[2]; project(p,mmvp,p); p[0]-=mx; p[1]-=my; p[2]=0.0; if (vector_len(p)<=0.5*b) sel=0;   // X
                              p[1]=o[1]+l[1]-0.5*a; p[0]=o[0]; p[2]=o[2]; project(p,mmvp,p); p[0]-=mx; p[1]-=my; p[2]=0.0; if (vector_len(p)<=0.5*b) sel=1;   // Y
                              p[2]=o[2]+l[2]-0.5*a; p[1]=o[1]; p[0]=o[0]; project(p,mmvp,p); p[0]-=mx; p[1]-=my; p[2]=0.0; if (vector_len(p)<=0.5*b) sel=2;   // Z
                              _redraw=(sel0!=sel);
                              }
                          // drag arrowhead center into mouse position (active button)
                          if ((ql)&&(sel>=0)&&(sel<3))
                              {
                              int i;
                              double len0,len;
                              double p0[3],dp[3]={0.0,0.0,0.0},t,dt,q[3]={mx,my,0.0};
                              // selected arrowhead position,direction
                              for (i=0;i<3;i++) p0[i]=o[i];
                              p0[sel]+=l[sel]-0.5*a;
                              dp[sel]=1.0;
                              // "closest" intersection between axis/mouse_ray
                              for (len0=-1.0,t=0.0,dt=1.0;fabs(dt)>1e-5;t+=dt)
                                  {
                                  // position on axis p(t) = p0 + t*dp
                                  for (i=0;i<3;i++) p[i]=p0[i]+(t*dp[i]);
                                  // len = distance to mouse
                                  project(p,mmvp,p);
                                  vector_sub(p,p,q); p[2]=0.0;
                                  len=vector_len(p);
                                  // handle iteration step
                                  if (len0<-0.5) len0=len;
                                  if (len>len0) dt=-0.1*dt;
                                  len0=len;
                                  }
                              // translate by t
                              double m[16]=
                                  {
                                  1.0,0.0,0.0,0.0,
                                  0.0,1.0,0.0,0.0,
                                  0.0,0.0,1.0,0.0,
                                  0.0,0.0,0.0,1.0,
                                  };
                              m[12+sel]=t;
                              matrix_mul(mm,m,mm);
                              _redraw=true;
                              }
                          return _redraw;
                          }
                      };
                  //---------------------------------------------------------------------------
                  DragDrop3D ctrl;    // I got single cube so single arrow drag drop control suffice
                  //---------------------------------------------------------------------------
                  void gl_draw()      // main rendering code
                      {
                      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
                      glEnable(GL_CULL_FACE);
                      glEnable(GL_LIGHTING);
                      glEnable(GL_LIGHT0);
                      glEnable(GL_COLOR_MATERIAL);
                  
                      // init
                      static bool _init=true;
                      if (_init)
                          {
                          _init=false;
                          // M,V init matrices
                          glMatrixMode(GL_MODELVIEW);
                          glPushMatrix();
                          glLoadIdentity();
                          glTranslated(0.0,0.0,-25.0);
                          glGetDoublev(GL_MODELVIEW_MATRIX,mview);
                          glLoadIdentity();
                          glTranslated(-2.0,-1.0,-1.0);
                          glRotated(-35.0,0.0,1.0,0.0);
                          glGetDoublev(GL_MODELVIEW_MATRIX,mmodel);
                          glPopMatrix();
                          // matrices -> ctrl
                          glGetDoublev(GL_PROJECTION_MATRIX,mproj);
                          ctrl.mp=mproj;
                          ctrl.mv=mview;
                          ctrl.mm=mmodel;
                          }
                      // matrices -> OpenGL
                      glMatrixMode(GL_MODELVIEW);
                      glLoadMatrixd(mview);
                      glMultMatrixd(mmodel);
                  
                      // draw VAO cube
                      ctrl.draw();
                      vao_draw(); // here render your object instead
                  
                      glFlush();
                      SwapBuffers(hdc);
                      }
                  //---------------------------------------------------------------------------
                  __fastcall TForm1::TForm1(TComponent* Owner):TForm(Owner)
                      {
                      // application init
                      gl_init(Handle);
                      vao_init();
                      }
                  //---------------------------------------------------------------------------
                  void __fastcall TForm1::FormDestroy(TObject *Sender)
                      {
                      // application exit
                      gl_exit();
                      vao_exit();
                      }
                  //---------------------------------------------------------------------------
                  void __fastcall TForm1::FormResize(TObject *Sender)
                      {
                      // window resize
                      gl_resize(ClientWidth,ClientHeight);
                      }
                  //---------------------------------------------------------------------------
                  void __fastcall TForm1::FormPaint(TObject *Sender)
                      {
                      // window repaint
                      gl_draw();
                      }
                  //---------------------------------------------------------------------------
                  void __fastcall TForm1::FormMouseWheel(TObject *Sender, TShiftState Shift, int WheelDelta, TPoint &MousePos, bool &Handled)
                      {
                      // mouse wheel translates camera (like zoom)
                      GLfloat dz=2.0;
                      if (WheelDelta<0) dz=-dz;
                      glMatrixMode(GL_MODELVIEW);
                      glPushMatrix();
                      glLoadMatrixd(mview);
                      glTranslatef(0,0,dz);
                      glGetDoublev(GL_MODELVIEW_MATRIX,mview);
                      glPopMatrix();
                      gl_draw();
                      }
                  //---------------------------------------------------------------------------
                  // mouse events
                  void __fastcall TForm1::FormMouseDown(TObject *Sender, TMouseButton Button,TShiftState Shift, int X, int Y) { if (ctrl.mouse(X,Y,Shift)) gl_draw(); }
                  void __fastcall TForm1::FormMouseUp(TObject *Sender, TMouseButton Button,TShiftState Shift, int X, int Y) { if (ctrl.mouse(X,Y,Shift)) gl_draw(); }
                  void __fastcall TForm1::FormMouseMove(TObject *Sender, TShiftState Shift, int X, int Y) { if (ctrl.mouse(X,Y,Shift)) gl_draw(); }
                  //---------------------------------------------------------------------------
                  

                  It is based on this: simple complete GL+VAO/VBO+GLSL+shaders example in C++ where you will find more info and the gl_simple.h I am using for this. The code is VCL based so ignore the VCL stuff and port the events to your kind of programming.

                  The program is using just OpenGL 1.0 API (appart of the VAO/VBO cube representing my object) so it does not need anything apart math.h for sin,cos,fabs functions.

                  The idea is to have one control DragDrop3D object per each controlable object in the world/scene. Init each first and then call mouse for each on every mouse event and redraw if needed.

                  Here small preview:

                  Sadly my GIF capture SW does not catch mouse cursor but it matches the movement exactly.

                  I was too lazy to compute the intersection between axises directly instead I iterate to find closest match (that for loop with dt). That part could be replaced by intersection equation.

                  The axises are bounded to the x,y,z axises of the object coordinate system (mm,mmodel).

                  For more objects you should also add locks so only one object can be selected ...

                  PS. see related: - OpenGL ray OBB intersection

                  這篇關于計算用箭頭和鼠標移動的對象的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!

                  【網站聲明】本站部分內容來源于互聯網,旨在幫助大家更快的解決問題,如果有圖片或者內容侵犯了您的權益,請聯系我們刪除處理,感謝您的支持!

                  相關文檔推薦

                  In what ways do C++ exceptions slow down code when there are no exceptions thown?(當沒有異常時,C++ 異常會以何種方式減慢代碼速度?)
                  Why catch an exception as reference-to-const?(為什么要捕獲異常作為對 const 的引用?)
                  When and how should I use exception handling?(我應該何時以及如何使用異常處理?)
                  Scope of exception object in C++(C++中異常對象的范圍)
                  Catching exceptions from a constructor#39;s initializer list(從構造函數的初始化列表中捕獲異常)
                  Difference between C++03 throw() specifier C++11 noexcept(C++03 throw() 說明符 C++11 noexcept 之間的區別)
                    1. <i id='aSmJK'><tr id='aSmJK'><dt id='aSmJK'><q id='aSmJK'><span id='aSmJK'><b id='aSmJK'><form id='aSmJK'><ins id='aSmJK'></ins><ul id='aSmJK'></ul><sub id='aSmJK'></sub></form><legend id='aSmJK'></legend><bdo id='aSmJK'><pre id='aSmJK'><center id='aSmJK'></center></pre></bdo></b><th id='aSmJK'></th></span></q></dt></tr></i><div class="qwawimqqmiuu" id='aSmJK'><tfoot id='aSmJK'></tfoot><dl id='aSmJK'><fieldset id='aSmJK'></fieldset></dl></div>

                        <tfoot id='aSmJK'></tfoot>
                          <bdo id='aSmJK'></bdo><ul id='aSmJK'></ul>
                            <tbody id='aSmJK'></tbody>
                          <legend id='aSmJK'><style id='aSmJK'><dir id='aSmJK'><q id='aSmJK'></q></dir></style></legend>

                          <small id='aSmJK'></small><noframes id='aSmJK'>

                            主站蜘蛛池模板: 亚洲欧美视频一区 | 免费成年网站 | 成人免费视频网站在线看 | 国产一区久久精品 | 精品美女久久久久久免费 | 暴草美女| 国产欧美一区二区三区在线看 | 国产精品久久 | 亚洲综合大片69999 | 天天操天天射综合 | 欧美日韩一 | 午夜视频在线免费观看 | 成人深夜小视频 | 久久久久久久久蜜桃 | 久久精品亚洲精品国产欧美 | 亚洲精品丝袜日韩 | 香蕉婷婷 | 国产亚洲一区二区精品 | 日韩一区二区在线观看视频 | 欧美性另类 | 99久久婷婷国产综合精品电影 | 91小视频在线 | 亚洲在线电影 | 亚洲国产精品久久久久婷婷老年 | 天天夜夜操 | 午夜视频免费网站 | 免费久久视频 | 亚洲二区在线 | 性视频一区 | 一区二区国产精品 | 少妇一级淫片aaaaaaaaa | 亚洲欧美日韩精品久久亚洲区 | 国产一级片av | 亚洲国产中文字幕 | 在线观看成人小视频 | 久久久男人的天堂 | 久久精品一| 午夜免费观看 | 九九九久久国产免费 | 毛片黄片| 男人天堂av网站 |