【3D技术宅公社】XR数字艺术论坛  XR技术讨论 XR互动电影 定格动画

 找回密码
 立即注册

QQ登录

只需一步,快速开始

调查问卷
论坛即将给大家带来全新的技术服务,面向三围图形学、游戏、动画的全新服务论坛升级为UTF8版本后,中文用户名和用户密码中有中文的都无法登陆,请发邮件到324007255(at)QQ.com联系手动修改密码

3D技术论坛将以计算机图形学为核心,面向教育 推出国内的三维教育引擎该项目在持续研发当中,感谢大家的关注。

查看: 2697|回复: 4

[计算机图形学] [求助]如何将鼠标点击的点转换成3D世界坐标中的点

[复制链接]
发表于 2009-6-10 17:23:50 | 显示全部楼层 |阅读模式

    理论好象就是用摄象机所在的点和鼠标点击的点(要经过逆投影变换,变换后鼠标处于视图坐标系中,也就是视锥里的坐标)构造一条射线,用这条射线和视锥里的网格进行相交测试(用D3DXIntersect函数)。

    现在我的问题是:有一张网格地图,我对它使用了一个单独的世界矩阵(以对它进行缩放和平移),我怎么得到鼠标在它上点击的世界坐标(也就是说我想要把一个物体移动到该点)呢?  如果我现在可以使用D3DXIntersect函数得到交点,那么这个"交点"是属于网格的一个三角形,那么我就可以得到三角形的三个顶点,这三个顶点的坐标肯定是地图网格对象没有经过转换的坐标,那么我现在该使用哪个世界矩阵来转换他们呢?是地图网格拥有的那个单独的世界矩阵还是其他对象公用的世界矩阵???

发表于 2009-6-11 20:44:29 | 显示全部楼层

没有办法获取3D世界中鼠标的位置的,因为鼠标就是2D的

 

我没仔细看你的代码,鼠标拣选的关键是计算  鼠标点在屏幕上作为起点,向3D世界发射一条射线,根据视角转换矩阵可以计算出这个射线与3D世界中模型的交点。你要的点就是这个交点。

 楼主| 发表于 2009-6-10 18:36:04 | 显示全部楼层

   看看我的代码,不能正常运行.

 OINT p;
 GetCursorPos(&p);
 ScreenToClient(g_hWnd,&p);
 static D3DXMATRIXA16 matView,matProj;
 g_d3dDevice->GetTransform(D3DTS_VIEW,&matView);
 g_d3dDevice->GetTransform(D3DTS_PROJECTION,&matProj);
 static D3DXMATRIXA16 matInvV;
 D3DXMatrixInverse(&matInvV,0,&matView);
 //计算射线的方向和原点
 D3DXVECTOR3 vecTemp,vPickVecDir,vPickOrigin;
 vecTemp.x = ( ( (2.0f*p.x) / g_desc.Width ) - 1 )/matProj._11;
 vecTemp.y =-( ( (2.0f*p.y) / g_desc.Height) - 1 )/matProj._22;
 vecTemp.z = 1.0f;

 vPickVecDir.x = vecTemp.x*matInvV._11 + vecTemp.y*matInvV._21 + vecTemp.z*matInvV._31;
 vPickVecDir.y = vecTemp.x*matInvV._12 + vecTemp.y*matInvV._22 + vecTemp.z*matInvV._32;
 vPickVecDir.z = vecTemp.x*matInvV._13 + vecTemp.y*matInvV._23 + vecTemp.z*matInvV._33;

 vPickOrigin.x = matInvV._41;
 vPickOrigin.y = matInvV._42;
 vPickOrigin.z = matInvV._43;

 //计算是否和地面网格相交
 BOOL hited=FALSE;
 DWORD faceIndex=-1;
 FLOAT bu=0.0f;
 FLOAT bv=0.0f;
 const LPD3DXMESH pMesh = m_pTerrian->GetMesh();
 if(SUCCEEDED(D3DXIntersect(pMesh,&vPickOrigin,&vPickVecDir //这里使用的是Mesh的什么坐标?(物体or世界)
  ,&hited,&faceIndex,&bu,&bv,0,0,0)))
 {
  if(hited)//点中
  {
   //获得三角形顶点坐标
   LPDIRECT3DINDEXBUFFER9 pIndices=0;
   LPDIRECT3DVERTEXBUFFER9 pVertices=0;
   pMesh->GetIndexBuffer(&pIndices);
   pMesh->GetVertexBuffer(&pVertices);
   WORD* w=0;
   if(FAILED(pIndices->Lock(0,0,(LPVOID*)&w,0)))
   {
    SAFE_RELEASE(pIndices);
    SAFE_RELEASE(pVertices);
    return;
   }
   WORD vi1=w[fontIndex*3+0];//顶点索引
   WORD vi2=w[fontIndex*3+1];
   WORD vi3=w[fontIndex*3+2];
   pIndices->Unlock();
   SAFE_RELEASE(pIndices);
   BYTE* bp=0;
   if(FAILED(pVertices->Lock(0,0,(LPVOID*)&bp,0)))
   {
    SAFE_RELEASE(pIndices);
    SAFE_RELEASE(pVertices);
    return;
   }
   DWORD verTexSize=pMesh->GetNumBytesPerVertex();
   D3DXVECTOR3 v1 = *(D3DXVECTOR3*)(bp[verTexSize*vi1]);  //指针总是非法
   D3DXVECTOR3 v2 = *(D3DXVECTOR3*)(bp[verTexSize*vi2]);
   D3DXVECTOR3 v3 = *(D3DXVECTOR3*)(bp[verTexSize*vi3]);
   pVertices->Unlock(); 
   SAFE_RELEASE(pVertices);

   D3DXVECTOR3 target = v1 + bu*(v2-v1) + bv*(v3-v1);
   m_pPlayer->SetPosition(target);
  }
 }

 

 我有个两问题不明白,这里面用的Mesh在计算的时候是使用自己的物体坐标,还是被世界矩阵转换之后的坐标?

还有我计算顶点数据指针偏移那里为什么会出错?

 

 楼主| 发表于 2009-6-11 00:17:40 | 显示全部楼层
是的,我需要世界坐标系中的坐标.
发表于 2009-6-10 23:08:49 | 显示全部楼层
你是在说鼠标点选吧
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|3D数字艺术论坛 ( 沪ICP备14023054号 )

GMT+8, 2025-5-14 19:27

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表