在某些虚拟现实应用中,当用鼠标拣选物体时,可能不仅仅需要Ogitor中的那种效果,也可能需要表现一些3D的效果,如图1所示:
图1 3D鼠标拣选示意图
要实现此功能,原来其实很简单,只需要一个实体不断的变换大小,当鼠标拣选到相应的物体时,三维鼠标的模型移动到相应的位置就可以。这样就能达到三维鼠标的效果。鼠标的三维效果可以通过Max创建一个简单的模型或者手动创建一个Mesh,然后再每一帧中处理模型的大小。模型的大小可以根据当前拣选的物体的坐标与视点之间的距离的大小来设定。
示例代码如下:
更新代码:
1: bool CDynCursor::frameStarted(const FrameEvent& evt)2: {
3: if (mpNode && mpCam)4: {
5: Real scale;
6: static Real time = 0;7: time += evt.timeSinceLastFrame;
8: if (time > 2) time = 0;9:
10: //5 frame update, 16.0 experience value11: int n = time / (5*1.0/16.0);12: scale = ((n & (n-1)) == 0) * 0.2 + 1.0;
13:
14: //keep project size15: float sz = scale * computePixelSizeAtDistance((mpNode->getPosition() - mpCam->getPosition()).length());16: mpNode->setScale(sz, sz, sz);
17: // mpNode->showBoundingBox(true);18: }
19:
20: return true;21: }
根据物体拣选的坐标与视点之间的距离设置模型的缩放比例的代码:
1: Real CDynCursor::computePixelSizeAtDistance(Real distance)
2: {
3: HWND hwnd = TDE::Workspace::getSingleton().getActiveWindowHandle();
4: Camera *pCam = TDE::Workspace::getSingleton().getCamera(hwnd);
5: if (pCam == NULL) return 0;6: RenderWindow *pWnd = TDE::Workspace::getSingleton().getRenderWindow(hwnd);
7: if (pWnd == NULL) return 0;8: Real halfFov = pCam->getFOVy().valueRadians()/2;
9: Real width = pWnd->getWidth();
10:
11: float pixScale;12: if (width > 0)13: {
14: pixScale = 2*Math::Tan(halfFov) / width;
15: }
16: else17: {
18: pixScale = 0;
19: }
20: return Math::Abs(distance)*pixScale;21: }
至此就可以实现场景中的3D鼠标效果,通过这种方式也可以实现场景中某些报警信息。