青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

eryar

PipeCAD - Plant Piping Design Software.
RvmTranslator - Translate AVEVA RVM to OBJ, glTF, etc.
posts - 603, comments - 590, trackbacks - 0, articles - 0

OpenCASCADE View Manipulator

Posted on 2014-12-20 19:52 eryar 閱讀(4486) 評論(2)  編輯 收藏 引用 所屬分類: 2.OpenCASCADE

OpenCASCADE View Manipulator

eryar@163.com

Abstract. When you finish modeling objects in the scene, you must want to use some operations to view the scene objects, such as Pan, Zoom and Rotate the scene. Pan and Zoom is easy to understand, rotate the 3D scene according to 2D point in the viewport is a little complicated. There are many methods to rotate the 3D scene, but the Arcball Controller is intuitive for the user and any viewport can be described. You can rotate your model at will just by using the mouse.

Key Words. OpenCASCADE Camera, View, ArcBall, Rotate

1. Introduction

當用OpenGL建立了一個模型場景后,就需要有便捷的操作來觀察場景中的物體。場景的觀察即注重于一個從三維世界轉換到二維屏幕的過程。假設場景的觀察者使用一臺相機來記錄世界的變化,那么相機的移動、角度偏轉、焦距變化都會改變底片上顯現的內容,也就是觀察這個世界的方式,這涉及到三維人機的交互。

三維用戶交互是一種與三維環境本身特性相匹配的交互動作,可使用戶在虛擬場景中獲得身臨其境的直觀感受。三維世界的交互技術相當于一種“控制-顯示”的映射,用戶設備例如鼠標、鍵盤等向系統輸入控制信息,然后系統向用戶輸出執行結果。所以首先要對硬件設備的輸入信息進行處理,然后就是根據這些信息來改變場景數據。

三維交互涉及的任務很多,包括三維場景對象的選擇和編輯、三維世界中的導航漫游,乃至時下流行的三維交互建模等。本文主要介紹如何通過改變像機參數來對場景進行瀏覽,如對場景的平移、縮放和旋轉操作。

wps_clip_image-22681

Figure 1.1 OpenCASCADE Viewer 

2.Translate View

場景的移動就是改變觀察相機的位置,相對容易理解,在OpenCASCADE的類V3d_View中也是這樣實現的,代碼如下所示:

// ==================================================================
// function : Translate
// purpose  : Internal
// ==================================================================
void V3d_View::Translate (const Handle(Graphic3d_Camera)& theCamera,
                          
const Standard_Real theDXv,
                          
const Standard_Real theDYv) const
{
  
const gp_Pnt& aCenter = theCamera->Center();
  
const gp_Dir& aDir = theCamera->Direction();
  
const gp_Dir& anUp = theCamera->Up();

  gp_Ax3 aCameraCS (aCenter, aDir.Reversed(), aDir 
^ anUp);
  gp_Vec aCameraPanXv 
= gp_Vec (aCameraCS.XDirection()) * theDXv;
  gp_Vec aCameraPanYv 
= gp_Vec (aCameraCS.YDirection()) * theDYv;
  gp_Vec aCameraPan 
= aCameraPanXv + aCameraPanYv;

  gp_Trsf aPanTrsf;
  aPanTrsf.SetTranslation (aCameraPan);

  theCamera
->Transform (aPanTrsf);
}

由上述代碼可知,根據兩次鼠標位置計算出需要移動的偏移量來對相機進行移動變換。根據鼠標第一次按下及移動過程中的坐標點來計算偏移量。計算偏移量時,需要注意坐標系的統一,即要么都在視口坐標系,要么都在世界坐標系中。如下代碼是將鼠標點變換到世界坐標系中進行移動:

void ArcballController::Translate(const gp_Pnt2d &thePoint)
{
  gp_Pnt aCurrentPoint 
= Convert2World(thePoint);
  
    gp_Trsf aTrsf;
  aTrsf.SetTranslation(aCurrentPoint, mPreviousPoint);
  
    mCamera
->Transform(aTrsf);
}

對相機參數進行修改后,需要更新場景數據。移動場景只涉及到MODELVIEW變換,所以需要刷新模型視圖MODELVIEW變換矩陣數據并重繪場景,相關代碼如下所示:

// model/view transformation for pan and rotate.
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glLoadMatrixf(theArcballController.GetOrientationMatrix());

其中theArcballController的這個函數是調用了Graphic3d_Camera的函數來設置模型視圖變換矩陣。經過測試,移動效果還可以,如下圖所示為將一個Teapot從屏幕左上角移動到了右下角:

wps_clip_image-8405

Figure 2.1 Translate the Scene

3.Zoom View

對于透視投影而言,靠模型越近,看到模型就越大,因為透視投影的特點就是近大遠小。而對平行投影而言,這種規律就不適用了。其實二者都可以統一到通過調整視口大小來對場景模型進行縮放。同樣的模型,當投影到較大的視口中時,模型的投影得到的二維圖形也會較大;當投影到較小的視口中時,模型的投影得到的二維圖形也會較小。這樣就達到對場景進行縮放的目的了。其中OpenCASCADE中的實現是通過設置Graphic3d_Camera的Scale來實現的,代碼如下圖所示:

//===================================================================
//function : SetZoom
//purpose  :
//===================================================================
void V3d_View::SetZoom(const Standard_Real Coef,const Standard_Boolean Start)
{
  V3d_BadValue_Raise_if( Coef 
<= 0.,"V3d_View::SetZoom, bad coefficient");
  
if (Start)
  {
    myCamStartOpEye    
= myCamera->Eye();
    myCamStartOpCenter 
= myCamera->Center();
  }

  Standard_Real aViewWidth  
= myCamera->ViewDimensions().X();
  Standard_Real aViewHeight 
= myCamera->ViewDimensions().Y();

  
// ensure that zoom will not be too small or too big
  Standard_Real coef = Coef;
  
if (aViewWidth < coef * Precision::Confusion())
  {
    coef 
= aViewWidth / Precision::Confusion();
  }
  
else if (aViewWidth > coef * 1e12)
  {
    coef 
= aViewWidth / 1e12;
  }
  
if (aViewHeight < coef * Precision::Confusion())
  {
    coef 
= aViewHeight / Precision::Confusion();
  }
  
else if (aViewHeight > coef * 1e12)
  {
    coef 
= aViewHeight / 1e12;
  }

  myCamera
->SetEye (myCamStartOpEye);
  myCamera
->SetCenter (myCamStartOpCenter);
  myCamera
->SetScale (myCamera->Scale() / Coef);
  View()
->AutoZFit();

  ImmediateUpdate();
}

根據鼠標點計算出縮改系數,通過myCamera->SetScale()來達到對場景進行縮放的目的。場景縮放操作涉及到需要更新OpenGL的投影矩陣數據,代碼如下所示:

// projection transformation for zoom.
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glLoadMatrixf(theArcballController.GetProjectionMatrix());

wps_clip_image-31482

Figure 3.1 Zoom the scene

4.Rotate View

通過鼠標在二維屏幕上來旋轉三維的場景有幾種方法,如下圖所示:

wps_clip_image-1268

Figure 4.1 3D Rotation(http://www.cabiatl.com/mricro/obsolete/graphics/3d.html)

方法一是通過Euler Angles來實現,好處是用戶比較容易理解Euler角,如yaw, pitch和roll,如下圖所示:

wps_clip_image-19192

Figure 4.2 Euler Angles: Yaw, Pitch and Roll

缺點就是因為死鎖問題(gimbal lock)導致不能指定一些視圖,當出現死鎖問題時,操作就顯得不直觀了。

比較直觀的方法就是ArcBall方式了,使用這種方法可以以任意方向來查看場景中的模型。有個網頁版的實現,可以去體驗一下:

http://www.math.tamu.edu/~romwell/arcball_js/index.html

wps_clip_image-1409

Figure 4.3 Arcball in Javascript

ArcBall的原理是將二維屏幕上鼠標點轉換到球面上,拖動鼠標就是在轉動這個球。根據映射到球面的兩個點,通過矢量的點乘及叉乘得到旋轉角度及旋轉軸。通過這種方式可以將二維的鼠標位置映射到三維的場景來實現對場景觀察的直觀操作。

OpenCASCADE中場景的旋轉方式是通過先遍歷場景中的模型計算出重心點,再繞三個坐標軸來旋轉,代碼如下所示:

//=============================================================================
//function : Rotate
//purpose  :
//=============================================================================
void V3d_View::Rotate(const Standard_Real ax, const Standard_Real ay, const Standard_Real az,
                      
const Standard_Real X, const Standard_Real Y, const Standard_Real Z, const Standard_Boolean Start)
{

  Standard_Real Ax 
= ax ;
  Standard_Real Ay 
= ay ;
  Standard_Real Az 
= az ;

  
if( Ax > 0. ) while ( Ax > DEUXPI ) Ax -= DEUXPI ;
  
else if( Ax < 0. ) while ( Ax < -DEUXPI ) Ax += DEUXPI ;
  
if( Ay > 0. ) while ( Ay > DEUXPI ) Ay -= DEUXPI ;
  
else if( Ay < 0. ) while ( Ay < -DEUXPI ) Ay += DEUXPI ;
  
if( Az > 0. ) while ( Az > DEUXPI ) Az -= DEUXPI ;
  
else if( Az < 0. ) while ( Az < -DEUXPI ) Az += DEUXPI ;

  
if (Start)
  {
    myGravityReferencePoint.SetCoord (X, Y, Z);
    myCamStartOpUp 
= myCamera->Up();
    myCamStartOpEye 
= myCamera->Eye();
    myCamStartOpCenter 
= myCamera->Center();
  }

  
const Graphic3d_Vertex& aVref = myGravityReferencePoint;

  myCamera
->SetUp (myCamStartOpUp);
  myCamera
->SetEye (myCamStartOpEye);
  myCamera
->SetCenter (myCamStartOpCenter);

  
// rotate camera around 3 initial axes
  gp_Pnt aRCenter (aVref.X(), aVref.Y(), aVref.Z());

  gp_Dir aZAxis (myCamera
->Direction().Reversed());
  gp_Dir aYAxis (myCamera
->Up());
  gp_Dir aXAxis (aYAxis.Crossed (aZAxis)); 

  gp_Trsf aRot[
3], aTrsf;
  aRot[
0].SetRotation (gp_Ax1 (aRCenter, aYAxis), -Ax);
  aRot[
1].SetRotation (gp_Ax1 (aRCenter, aXAxis), Ay);
  aRot[
2].SetRotation (gp_Ax1 (aRCenter, aZAxis), Az);
  aTrsf.Multiply (aRot[
0]);
  aTrsf.Multiply (aRot[
1]);
  aTrsf.Multiply (aRot[
2]);

  myCamera
->Transform (aTrsf);

  View()
->AutoZFit();

  ImmediateUpdate();
}

5.Conclusion

當實現三維場景的建模后,最激動人心的應該是對場景及場景中模型的控制。通過交互操作使用戶方便地觀察場景的模型,或直觀地編輯場景中的模型。所以交互也是三維軟件中的重要功能,且是給用戶最直接的感覺的操作。

因為交互操作涉及到鼠標鍵盤消息的處理,所以首先要設計好對這些消息的處理方式,在OpenSceneGraph中使用了適配器的方式來實現跨平臺的消息處理,使用戶通過繼承的方式來實現對消息的處理。這種方式使程序的可擴展性及代碼的可讀性更好,OpenCASCADE中的消息的處理還是比較直接的,沒有什么封裝。

本文主要介紹了如何實現對場景的控制,如移動、縮放及旋轉操作,這些功能的實現需要對OpenGL的渲染管線有一定的了解。在理解了對視圖/場景的控制后,為進一步理解對場景中的模型的控制打下基礎,如選擇Picking,拖拽Drag等操作。最后給出一個基于OpenCASCADE的類Graphic3d_Camera及GLUT實現的場景變換操作,功能不是很完善,僅供參考。若有好的意見,歡迎反饋。

6. References

1. Brad Smith. ArcBall. http://rainwarrior.ca/dragon/arcball.html

2. WikiBooks. Modern OpenGL Tutorial Arcball. 

http://en.wikibooks.org/wiki/OpenGL_Programming/Modern_OpenGL_Tutorial_Arcball

3. sgCore demo code. http://www.shnenglu.com/eryar/archive/2013/06/30/201411.html

4. Virtual Trackballs Revisited. http://image.diku.dk/research/trackballs/index.html

5. http://oviliazhang.diandian.com/post/2012-05-19/40027878859

6. 王銳,錢學雷. OpenSceneGraph三維渲染引擎設計與實踐. 清華大學出版社. 2009

PDF Version and Source code: OpenCASCADE View Manipulator

Feedback

# re: OpenCASCADE View Manipulator  回復  更多評論   

2015-06-19 20:07 by 佚名
博主您好,我想請教一下,如何改變view3d的z向顯示范圍,目前的情況是z向范圍不夠,自己通過opengl函數在屏幕邊部繪制點能顯示出來,但一旋轉到屏幕中間,就被屏蔽看不見了。

# re: OpenCASCADE View Manipulator  回復  更多評論   

2015-06-19 20:26 by eryar
@佚名
Hi ,
你好!

你可以調用Camera的SetZRange()或ZFitAll()試試看。

Best Regards,
Shing Liu
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美午夜免费电影| 性视频1819p久久| 欧美日本成人| 亚洲午夜久久久久久久久电影院| 欧美福利专区| 欧美日韩精品二区| 亚洲永久免费精品| 午夜精品影院在线观看| 在线观看欧美日韩| 亚洲日本黄色| 亚洲精品久久久久久一区二区| 亚洲黑丝一区二区| 亚洲破处大片| 国产精品视频一| 女生裸体视频一区二区三区| 欧美+亚洲+精品+三区| 一区二区三区久久久| 欧美一区二区三区另类| 亚洲精品国产视频| 亚洲欧美日韩国产| 最新中文字幕一区二区三区| 一本色道久久综合| 亚洲福利在线视频| 亚洲视频碰碰| 亚洲国产视频直播| 亚洲一区二区三区精品视频| 在线观看国产日韩| 亚洲一级一区| 亚洲乱码精品一二三四区日韩在线| 一区二区三区高清在线观看| 亚洲成人自拍视频| 亚洲香蕉在线观看| 亚洲麻豆国产自偷在线| 亚洲综合不卡| 在线亚洲一区| 麻豆精品网站| 久久久精品国产免大香伊| 欧美另类变人与禽xxxxx| 久久米奇亚洲| 国产老女人精品毛片久久| 亚洲黄色大片| 在线精品国精品国产尤物884a| 亚洲一区二区三区免费观看| 亚洲免费av片| 欧美77777| 你懂的视频欧美| 国产日韩在线看| 一区二区三区四区在线| 亚洲精品一区二区三区四区高清 | 国产中文一区二区| 亚洲性视频网站| 一本久道久久综合中文字幕| 嫩模写真一区二区三区三州| 老司机午夜精品| 国产在线日韩| 欧美一级电影久久| 欧美在线亚洲一区| 国产精品视频精品| 一区二区三区精密机械公司| 一区二区av在线| 欧美激情一区二区久久久| 欧美国产视频在线| 亚洲黄色片网站| 免费成人小视频| 亚洲国产成人av好男人在线观看| 在线电影国产精品| 老司机精品视频网站| 欧美国产激情| 亚洲精选久久| 欧美色综合天天久久综合精品| 欧美日本亚洲韩国国产| 亚洲人成人99网站| 宅男噜噜噜66一区二区| 欧美日韩精品综合| 亚洲性线免费观看视频成熟| 在线国产日韩| 国产一区视频网站| 欧美一级片在线播放| 久久久www成人免费毛片麻豆| 国产在线精品一区二区夜色| 久久理论片午夜琪琪电影网| 欧美成人免费在线视频| 亚洲精品看片| 欧美午夜精品理论片a级大开眼界 欧美午夜精品理论片a级按摩 | 999在线观看精品免费不卡网站| 欧美国产日韩免费| 一本久久a久久精品亚洲| 性色一区二区三区| 亚洲国产精品va在线看黑人 | 久久精品国产亚洲aⅴ| 欧美国产精品专区| 久久久久久色| 久久久99爱| avtt综合网| 榴莲视频成人在线观看| 亚洲另类一区二区| 国产资源精品在线观看| 欧美激情精品久久久久久大尺度 | 亚洲欧美激情视频在线观看一区二区三区| 欧美中在线观看| 日韩视频在线一区二区三区| 国产乱码精品一区二区三区av | 欧美一区二区三区在线播放| 亚洲人成精品久久久久| 欧美尤物一区| 99国产精品视频免费观看| 国产日韩欧美在线看| 欧美成人免费一级人片100| 午夜精品久久久久久| 亚洲国产裸拍裸体视频在线观看乱了 | 久久国产福利| 亚洲一区二区三区视频播放| 欧美激情一区二区在线| 久久成人国产| 亚洲伊人一本大道中文字幕| 亚洲国产精品va在看黑人| 国产亚洲精品高潮| 欧美日韩亚洲在线| 麻豆精品在线视频| 久久国产精品电影| 亚洲一二三四区| 亚洲精品免费一区二区三区| 欧美freesex8一10精品| 欧美在线视频网站| 亚洲伊人一本大道中文字幕| 亚洲麻豆视频| 亚洲日韩欧美视频一区| 亚洲第一页自拍| 国产一区二区三区久久精品| 国产精品亚洲人在线观看| 欧美四级伦理在线| 欧美日韩美女一区二区| 欧美激情亚洲激情| 欧美国产日韩在线| 欧美电影免费观看大全| 久久亚洲国产精品日日av夜夜| 性欧美超级视频| 欧美一区二区三区婷婷月色| 欧美日本韩国在线| 欧美激情久久久| 欧美成人资源网| 欧美成年人视频| 欧美国产高清| 欧美欧美在线| 欧美日韩免费观看一区| 欧美日韩色婷婷| 国产精品爱久久久久久久| 国产精品成人一区二区三区吃奶| 欧美色视频一区| 国产精品一区二区久久久久| 国产日韩在线亚洲字幕中文| 国产日韩精品一区| 国内精品久久久久国产盗摄免费观看完整版 | 欧美片网站免费| 国产精品va在线播放我和闺蜜| 国产精品扒开腿爽爽爽视频| 国产精品欧美日韩| 黄色在线一区| 亚洲日韩欧美视频一区| 亚洲在线免费| 久久久噜噜噜久久| 亚洲第一偷拍| 国产精品99久久久久久有的能看| 亚洲一区二区视频在线| 久久精品色图| 欧美日产在线观看| 国产欧美一区二区精品性色| 激情婷婷欧美| 99国产精品国产精品毛片| 欧美永久精品| 亚洲成色精品| 亚洲午夜视频| 久久影院午夜片一区| 欧美日韩精品一本二本三本| 国产日韩欧美91| 亚洲欧洲日本国产| 性欧美激情精品| 亚洲国产精品ⅴa在线观看| 在线视频免费在线观看一区二区| 欧美在线观看一区| 欧美日韩色婷婷| 影音先锋中文字幕一区二区| 一本色道**综合亚洲精品蜜桃冫| 久久久久国产精品麻豆ai换脸| 亚洲精品一区二区三区樱花| 香蕉久久国产| 欧美日韩一区三区| 狠狠色狠色综合曰曰| 亚洲欧美日韩人成在线播放| 亚洲国产精品一区在线观看不卡| 亚洲国产欧美一区二区三区丁香婷| 亚洲日韩欧美视频一区| 欧美一区二区三区视频| 欧美国产精品v| 久久久91精品国产一区二区三区 | 午夜激情久久久| 欧美日韩蜜桃| 亚洲国产天堂网精品网站| 久久国产主播| 亚洲一区在线直播|