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

 找回密码
 立即注册

QQ登录

只需一步,快速开始

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

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

查看: 4305|回复: 13

[DirectX] 3D对象在屏幕中的定位???

[复制链接]
发表于 2006-6-5 14:49:32 | 显示全部楼层 |阅读模式

2D的Sprite在屏幕中的定位是非常简单的只要给定(X,Y)就可以了

但是3D对象呢??

比如,我在写 D3D9 入门程序的时候,读入一个"tiger.x"模型进去,然后:

下面是伪代码:

SetView();

SetLight();

SetMetrix();

DrawMesh();

最后,我们就可以在屏幕中心看到一个"老虎"在那里转啊转的

上面的都有点废话~~~~~~~~~~~~~~~

现在的问题是,如何将3D坐标和屏幕位置对应起来,比如,我要将这个老虎的屏幕显示区域限制在长200像素的正方形中,并且让这个正方形的左上角的坐标是(100,200),假设我的屏幕是 800*600 的

如何利用"SetMetrix"将3D对象放到屏幕上指定的位置呢???

发表于 2006-6-5 15:05:12 | 显示全部楼层

你自己定的坐标系,然后移动的摄像机(摄像机默认在(0,0,0)上,面对z轴的正方向镜头上方为y轴正方向),物体的位置当然就是心中有数了,一般都采用相对原点的位置布局物体坐标的

 楼主| 发表于 2006-6-5 16:24:17 | 显示全部楼层

我的意思是如何将它和屏幕坐标对应,比如:

D3DXMatrixTranslation( &matTrans, 10.0f,10.0f, 0.0f );

这行代码执行后,3D对象将向X,Y的正方向各移动10.0f,那么移动后的位置在屏幕上的位置是多少呢??

也就是3D对象的左上角,在屏幕中的位置是多少呢??

要怎么才能计算出来??

发表于 2006-6-5 17:30:29 | 显示全部楼层

干吗要算这个?3D的就用3D的思维方式就好了。

矩阵函数里面有一个视角转换就是做这个的吧,它负责把3D场景投影到屏幕上,可我从来没有利用过。

 楼主| 发表于 2006-6-5 17:56:53 | 显示全部楼层

这个当然有用啦~~~~~~~~

因为我们要控制3D对象在屏幕上的位置啊~~~~~

比如:

D3DXMatrixTranslation( &matTrans, 10.0f,0.0f, 0.0f );

我们都知道通过这个矩阵变换,可以让3D对象,在X轴的正方向移动10.0f个单位.

但是你能告诉我它在我们的屏幕上移动了多少像素吗???

又比如,我想让一个圆球模型在屏幕中做自由运动,当碰到屏幕边缘的时候反弹回来.

那我怎么才能知道球是否到达了屏幕边缘呢????

不要忘记了我们显示的最终输出是一个2D的屏幕.

我不知道你是否懂了我的意思,我自己都有点乱了.呵呵

[em07][em07][em07][em07][em07][em07]
 楼主| 发表于 2006-6-6 07:17:33 | 显示全部楼层

我终于知道我要问什么了..............

我实际上想问的就是屏幕坐标到世界坐标的转换,也就是 2D坐标 到 3D坐标的转换~~~~

还有就是,如何得到一个3D对象,在屏幕坐标中的映射范围(也就是显示在屏幕中的矩形区域)??

发表于 2006-6-6 09:44:20 | 显示全部楼层

我猜想你是准备调用鼠标控制3D模型吧

三维矩阵里面不是有3个转换矩阵嘛。具体我记得不是很清楚了,好像是世界坐标转换--视角转换---屏幕投影转换,你要的东西应该在屏幕投影转换矩阵这里,它不是2D转3D而是把3D世界投影到2D屏幕(显示器)上显示出来。我很久没有碰3D了,你可以看看3D游戏中的鼠标拾取一类的文章,应该可以解决你的问题。

 楼主| 发表于 2006-6-6 12:42:37 | 显示全部楼层

其实我是想做一个简单的3D屏保.

就像WINDOWS自带的那个"三维文字"一样,我想让字在屏幕中自由运动,当碰到边缘的时候自动反弹.

但是我不知道,怎么才能检测文字碰到屏幕边缘了???

发表于 2006-6-6 15:44:57 | 显示全部楼层

字的个数是随时改变的吗?

不是的话,你慢慢手动调整测出什么时候到边缘好了~也不是社么大程序

不过鼠标获取那个例子也许对你有帮助,它就是通过鼠标在屏幕上(2D)上的操作控制3D世界的。

 楼主| 发表于 2006-6-6 18:56:54 | 显示全部楼层

“慢慢手动调整测出什么时候到边缘好了”

我几年前通常都是这么做的,但是现在的我已经变的比较严谨,比较爱钻牛角尖了,呵呵

况且,这应该也是3D乃至2D的图形基础,我不想错过。

我到网上找了一些这方面的资料,主要提到了,2D到3D坐标的变换,以及3D碰撞检测,看来以后有的忙了

[em07][em07][em07][em07][em07][em07][em07]
发表于 2006-6-7 01:08:16 | 显示全部楼层

那你就利用这个小程序锻炼一下也好

就跟我现在正在用推箱子锻炼渲染一样,我翻来覆去用了三种方法绘制推箱子,呵呵

不过最近公司可能会让我做服务器端的东西了~~我就要离开客户端了~~5555

发表于 2006-7-7 20:39:23 | 显示全部楼层

期待楼主贡献发现....只记得好象是个逆矩阵的问题....

碰撞这个感觉好难

[em04]
发表于 2006-7-25 18:31:17 | 显示全部楼层

这是我写的DEMO里拾取的一段!最后那个是用 D3DXIntersect来拾取多边形的面!!所以指向第一个参数为网格模型,这里我创建了包围盒就指向包围盒了!

//////////////////////////////////////////////////////////////////////////
//拾取网格
//////////////////////////////////////////////////////////////////////////
BOOL GameUI:ick(NPC *pNPC){
BOOL isPick=false;

float Dist;
D3DXMATRIXA16 ProjMatrix; //投影
D3DXMATRIXA16 ViewMatrix; //观察
D3DXMATRIXA16 im; //观察矩阵取逆
D3DXVECTOR3 v; //发射点
D3DXVECTOR3 vPickRayDir; //Mouse点击射线的空间方向

m_pd3dDevice->GetTransform(D3DTS_PROJECTION,&rojMatrix); //投影矩阵
v.x = (((2.0f * p.x) / ScreenW) - 1) / ProjMatrix._11; //基本投影的射线
v.y =-(((2.0f * p.y) / ScreenH) - 1) / ProjMatrix._22;
v.z = 1.0f;
m_pd3dDevice->GetTransform( D3DTS_VIEW, &ViewMatrix ); //视图矩阵
D3DXMatrixInverse(&im,NULL,&ViewMatrix); //求逆
vPickRayDir.x = v.x*im._11 + v.y*im._21 + v.z*im._31; //基于视图的射线
vPickRayDir.y = v.x*im._12 + v.y*im._22 + v.z*im._32;
vPickRayDir.z = v.x*im._13 + v.y*im._23 + v.z*im._33;

D3DXVec3Normalize(&vPickRayDir,&vPickRayDir);
D3DXVECTOR3 vPickRayOrig;
vPickRayOrig.x = im._41;
vPickRayOrig.y = im._42;
vPickRayOrig.z = im._43;

vPickRayOrig += vPickRayDir;

//变换到物体坐标内和物体求交
D3DXMATRIX matInv;
D3DXVECTOR3 vPickRayDir_tmp, vPickRayOrig_tmp;
D3DXMatrixInverse(&matInv, NULL, &pNPC->matBoxWorld);
D3DXVec3TransformCoord(&vPickRayOrig_tmp, &vPickRayOrig, &matInv);
D3DXVec3TransformNormal(&vPickRayDir_tmp, &vPickRayDir, &matInv);
//根据NPC的包围盒来拾取物体
D3DXIntersect(pNPC->ptagetMesh, //改变为自己生成出的BOX
&vPickRayOrig_tmp,&vPickRayDir_tmp,&isPick,
NULL,NULL,NULL,&Dist,NULL,NULL);
return isPick;
}

//////////////////////////////////////////////////////////////////////////

发表于 2006-7-25 18:34:29 | 显示全部楼层

关键在于屏上的点,转换为空间的射线。

空间的点转化为屏上的点!!!如果要反过来求空间的点投影回来,就要像设置视图矩阵,设置投影矩阵的运算一样算过来才行!!!

这些实现像刀剑ONLINE,大唐豪侠这样直接在屏上显示文字的游戏。如果要求差一点可以像魔兽世界那样,在角色模型上建一个“公告牌”把自己要写的文字RENDER上去!

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2025-2-6 04:09

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

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