??xml version="1.0" encoding="utf-8" standalone="yes"?>
1.技能快捷键
2.判断技能CDQ范_Ҏ技能类型设|技能目标,eg.以自wؓ中心的AOE技能,目标是自w?br />3.向Server发送TryUseSkill消息
Server
1.收到Client消息,使用的技能压入到‘技能处理列?#8216;?br /> m_skillTaskMgr.Push( TaskType_Skill, target, position, skillID, skillLvl )
2.在玩家每一帧中调用 m_skillTaskMgr.GetTask() 处理所有类型的dQ包括技?/p>
3.判断使用技能的一些条Ӟeg.技能目标,技能范?..
都满_Client发送MsgIntonateStart开始吟唱消?br />
Server:
1.目标q入视野Q如果目标正在吟唱或l持法Q将此状态消息MsgSkillStatus发给自己
EnterMySight(pTarget)
if ( pTarget->IsIntonate() || pTarget->IsHoldSkill() )
pTarget->SendSkillStatusTo( pMe )
Client
1.接受到Server技能吟唱消?MsgIntonateStart MsgSkillStatus
参数:iSkillID, iSkillLvl, srcPlayerID, tagPlayerID, iPercent
1). 若是自己吟唱Q显C吟p度条 UIProgressBar::Show(...)
2). 加入到动作队列中{待处理 GetActionQueue()->Push_Intonate(...)
2. 每 HandleActionQueue 中处?‘技能吟?#8217;Intonate
1Q保存吟q技?skillID, skillLvl
2Q播攑ƈ记录吟唱的特?iSkillEffectID = PlayEffect(...)
3Q切换到吟唱动作 SwitchActionStatus( Intonate, ...)
3. 吟唱l束 条g诸如QEndIntonate IntonateInterrupt HoldSkillEnd HoldSkillCancel Dead
1).切换动作到idle状?br /> 2).清除播放中的吟唱Ҏ GetEffectMgr()->ReleaseEffect( iSkillEffectID )
本hx动实C世界坐标pM的一点到屏幕坐标pȝ转换 , |上的资料都是在讲解固定线的渲染过E?span style="line-height: normal"> , 本h的需求ƈ不需要做 背面拣选裁剪等操作 , 所以自己来写一?span style="line-height: normal"> ,
M程?span style="line-height: normal">
世界坐标p?span style="line-height: normal">->视图坐标p?span style="line-height: normal">->投媄q面坐标p?span style="line-height: normal">->屏幕坐标p?span style="line-height: normal">
世界坐标p?/span>->视图坐标p?/span>
见本人的另外一?br style="line-height: normal" />
视图坐标p?/span>->投媄q面坐标p?/span>(透视投媄)
投媄q面, ?span style="line-height: normal">D3D?span style="line-height: normal">Z = 1 且与X, Y轴^行的q面 , ׃透视投媄, 灭点在视囑֝标系的原?span style="line-height: normal">, L一点在该^面的投媄?span style="line-height: normal"> .
已知视图坐标pȝ一?span style="line-height: normal">P(Y , Z) , ?在投影^面的?span style="line-height: normal">P(Y’ , Z’) , ?span style="line-height: normal">a未知 ,?span style="line-height: normal">
׃角Ş怼可得 , (X Z的坐标u与上囄?span style="line-height: normal"> , 只是?span style="line-height: normal">Y换成X而已)
Y’= Y * Z’ / Z
X’= X * Z’ / Z
D3D中投影^?span style="line-height: normal">Z’ =1, 所?span style="line-height: normal">
Y’= Y / Z
X’= X / Z
Z’= 1
׃可得变换矩阵?span style="line-height: normal">
1 0 0 0
0 1 0 0
0 0 1 1
0 0 0 0
投媄q面坐标p?/span>->屏幕坐标p?/span>
设投投媄q面最大高宽ؓPh ,Pw ,通过Y轴的最大可视角?span style="line-height: normal">a , 视截体的最q?span style="line-height: normal">Z?span style="line-height: normal"> Zf 则可得出 , 投媄q面的最大高?span style="line-height: normal">Ph(Y轴方?span style="line-height: normal">)
Ph= tan( a/2 ) * Zf
通过屏幕高宽?span style="line-height: normal">Aspect, 求出最大宽?span style="line-height: normal">Pw
Pw= Ph * Aspect
求得Ph , Pw , 我们可以得到投媄q面到屏q^面的转换比例(׃Ph , Pw仅是整个最大高宽的一?span style="line-height: normal"> , 所以屏q最大高宽也除二)
Yscale= (Sh/2)/Ph
Xscale= (Sw/2)/Pw
则投影面上Q意一?span style="line-height: normal">P(X, Y) 到屏q^?span style="line-height: normal">P’(X’ , Y’)的{换ؓ
X’= Sw/2 + X * Xscale
Y’= Sh/2 - Y * Yscale
PS.屏幕坐标原点在左上角
׃可得变换矩阵?span style="line-height: normal">
Xscale 0 00
0 -Yscale 0 0
0 0 1 0
Sw/2 Sh/2 0 1
视口默认位置?span style="line-height: normal">(0 , 0) , 不排除你会修?span style="line-height: normal"> , 所以还要加上视口在windowsH口的v始位|?span style="line-height: normal"> , 可以通过getviewport获得 所以矩阵应?span style="line-height: normal">
Xscale 0 0 0
0 -Yscale 0 0
0 0 1 0
Port.x +Sw/2 Port.y +Sh/2 0 1
DirectX中投影变换D3DXMatrixPerspectiveFovLHQ)其实产生的变换矩阵不是将3D物体转换?Dq面画面的变换。实际上是把3D世界的物体变换到(1,1,0) (-1,1,0) (-1,-1,0) (1,-1,0) (1,1,1) (-1,1,1) (-1,-1,1) (1,-1,1)q个盒子中。在Jim Adams 的著?lt;Role playing games with DriectX 8.0>和Frank Luna 的著作中<Introduction to 3D Game Programming with DirectX9.0>都把q个变换矩阵讲成?D?D的变换。实际上在DirectX?D?D的变换是由SDK自己完成的。而我们要做的是把3D世界变换C面那个小盒子中?/p>
q个变换矩阵是投影变换的预变换?/span>
在DirectX中,把视口的高作?D世界里面的长度:2.0f来用的Q一个视点观察世界的视野范围在Y轴上无论什么情况下都是 -1.0f?.0fQ这一点在后面来证明)。把视口的高作ؓy_端坐标为(xQ?Q,底端坐标为(xQ?1Q?/span>
视口Q在H体中显C?D的矩形范_可以通过D3DDevice的SetViewPortQ)来设|大,默认的大ؓH体的大?/span>
变换的过E就是把点的向量乘以变换矩阵Q可以得到这个点在新坐标pȝ对应向量Q在投媄变换矩阵中Z轴的D?~1之内Q也是?D世界里所有的炚w会被投媄C上描q的盒子中?/span>
我们用函数D3DXMatrixPerspectiveFovLH来获得该“投媄变换”矩阵?/span>
D3DXMATRIX * D3DXMatrixPerspectiveFovLH(
D3DXMATRIX *pOut,
FLOAT fovy,
FLOAT Aspect,
FLOAT zn,
FLOAT zf
);
其中参数fovy为y轴上的视角,Aspect为高宽比Qzn裁面Qzf裁面?/span>
Y轴的视角Q在DirectX的帮助文档中描述fovy为filed of view in y direction?/p>
高宽比:一般用于全屏显C,如果我们要让3D世界充满整个H口Q就必须让高宽比{于H口的高宽比Q例如让我们的窗口正常显C?#8221;标准视野”[2X2 的一个面,点坐标为(1Q?Q,Q?1Q?Q,Q?1Q?1Q,Q?Q?1Q]Q我们必LH口的高宽比讄?Q?Q这P标准视野可以充满整个窗口,否则 会在左右留出I白Q这个空白是无法用VIEWQWORLD变换所能填充的Q相当于word文档采用“文档”视图里面的两边的灰色区域Q是无法~辑的,在一般的3DE序里面是不允许出现q种情况的,但是我们的显C器的高宽比不是1Q?Q而且大部分的用户也不习惯?Q?的窗口来使用E序Q我们需要调整这个标准视野,来适应我们的窗口大,Aspect是q个作用Q有一炚w要说明的Aspect不等?Q不代表标准视野׃是(1Q?Q,Q?1Q?Q,Q?1Q?1Q,Q?Q?1Q,如果Aspect = 0.5 标准视野也还是(1Q?Q,Q?1Q?Q,Q?1Q?1Q,Q?Q?1Q,只不qx轴上的单位长度的像素??y轴上单位长度的像素值的2倍?/p>
裁面的作? 在Z轴方向上Q不昄z坐标于zn的或者大?zf的点?/span>
在上图中QU色的线为我们要昄的面Q红色的弧就是上面函数fovy的夹角,当这个夹角ؓ90°的时候,我们H口的视野ؓ标准视野Q当夹角~小Ӟ可视范围变,如图Q从90°变ؓ60°的时候,可视范围变小了,要显C的面,相对于可以范围变大了Q由于我们的H口是不变的Q也是说实际显C的像素g变,要显C的面就相对于变大,fovy的值变的l果是把要昄的面变大?/span>
?/span>fovy?/span>0的时候呢Q视野就?/span>0Q就是说什么都看不刎ͼH口中显C的是底色?/span>
?/span>fovy变大?/span>180°的时候呢Q?/span>视野的范围ؓ视线夹角上的垂直?/span>Z轴的且过点(0Q?/span>0Q?/span>1Q的q线。当视线夹角变大视野范围也变大,夹角近?/span>180°的时候视野范围趋q于无穷大,要显C的面相对于视野范围是0Q也是说羃到最就?/span>0.所以我们在讑֮fovy的gؓ180°的时候也是什么都看不见,为底艌Ӏ?/span>
那大?/span>180°的情况呢Q在我们的视野理Z是不存在q种情况的,当视角大?/span>180°Ӟ视角?/span>Z轴垂直的q线是不会过点(0Q?/span>0Q?/span>1Q的。但是函数放在我们面前,我们是可以输入大?/span>180°的数|l果会如何呢Q?/span>
非常奇的事情发生了Q我们的图以原点Z心旋转了180°Q这是无法用我们的视野理论来解释?/span>,因ؓ180°的视野范围就已经是个极限了,“越极限”是只能在q告中出现的词汇Q如果能越Q那׃叫极限了Q?/span>PQ?/span>
?/span>MSDN的文档中有这样一个数学公式:y-scale = cotQ?/span>fovy/2Q?/span>
q下明白了Q当我们输入大于180°的时?/span>cot的gؓ负数。?/span>x-scale = y-scale/ Aspect?/span>.
也就是说Q一?/span>3D世界的点Q在视野大于180°的作用下Q它的放?/span>/~小倍数不变Q但是需要对X轴做一ơ对U变换,q要?/span>Y轴做一ơ对U变换。相当于对原点做一ơ对U变换?/span>
拿到q个公式Q我们就可以对前面的标准做一个证明:
?/span>fovy?/span>90° Aspect = 1的时候,是?/span>y-scale = cotQ?/span>45°Q?/span> = 1
x-scale = 1Q这?/span>y?/span>x的羃放比都ؓ1Q没有羃放。我们显C样一个面
{-1.0f, -1.0f, 0.0f},
{-1.0f, 1.0f, 0.0f},
{ 1.0f, 1.0f, 0.0f},
{-1.0f, -1.0f, 0.0f},
{ 1.0f, 1.0f, 0.0f},
{ 1.0f,-1.0f, 0.0f}
我们会发现无论怎么改变H口的高度,q个画面?/span>Y轴方向上都会充满整个视口。(如果我们把视口的高度和宽度设|成一LQ在X轴上也会充满整个视口Q所?/span>DirectX会以视口的高度的二分之一作ؓY轴的单位长度?/span>
多渐进U理׃l分辨率逐渐降低的纹理序列组成,每一U纹理宽度和高度都是上一U纹理宽度和高度的一半。宽和高不一定相{,也就是说Q这些纹理不一定都是正方Ş?/p>
Direct3D在纹理映时Q自动选择一q与物体大小最接近的纹理进行渲染。当物体L影^面较q时QDirect3D会选择一张尺寸较、分辨率较低的纹理进行渲染;当物体离投媄q面较近ӞDirect3D会选择一张尺寸较大、分辨率较高的纹理进行渲染。Direct3D纹理序列看成一条多U渐q纹理链。链头处U理的分辨率最高,下一U往后依ơ递减Q链֤U理的分辨率最低?/p>
Direct3D能估计出多渐进U理链中哪幅U理的分辨率最接近惌的输出结果,然后它将像素映射到纹理空间。当最l显C的囑Ş大小介于L两U理囑Ş之间ӞDirect3D两U纹理的相应元素q行混合后显C?/span>
多渐进U理qo能够有效?span style="color: red">提高囑Ş渲染速度
Q?span style="color: red">当物体离投媄q面较远ӞDirect3D会选择一张尺寸较的U理q行渲染Q而无需l过复杂的诸如各异性纹理过?/span>Qƈ且由于这时纹理需要的昑֭比不使用多渐进U理时小Q因此能有效?span style="color: red">减少U理载入昑֭的时间?/span>~点是对内存的要求比较高讄多渐进U理qo方式
当最l显C的U理贴图大小介于L两U理之间ӞDirect3D能够取得两U理元素q行混合后显C,具体的合方式由指定的多U渐q纹理过滤方式决定。可以调用函数IDirect3DDevice9::SetSamplerState()讄多渐进U理qo方式Q将W一个参数设为纹理层序号Q第二个参数设ؓD3DSAMP_MIPFILTER表示多渐进U理qoQ第三个参数设ؓ在相ȝ理之间的过滤方式,可取枚DcdD3DTEXTUREFILTERTYPE的Q意倹{下面的CZ代码讄盔RU理U之间的qo方式为线性过滤?/p>
g_device->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
如果第三个参数设ؓD3DTEXF_NONEQ那么就会一直用最高一U的U理Q即用多渐进U理qo。如果将其设为D3DTEXF_POINTQ就会只使用与图元大最匚w的一U纹理。如果将其设为D3DTEXF_LINEARQDirect3D将与图元大最匚w的两U纹理以U性方式合?/font>
需要注意的是,多U理qo是羃和攑֤qo器的l合。例如,如果羃和Ҏqo器设为线性过滤,但是多U理qo方式设ؓ最q点采样QDirect3D׃选择与要昄的纹理脓囑֤最接近的纹理别,在该U纹理上完成双线性纹理过滤,q将l果作ؓ像素的倹{如果将~小、放大过滤器和多U渐q纹理都讄为线性过滤,则Direct3D׃在两个最接近的纹理别上都进行双U性纹理过滤,然后再对盔R两U理囑Ş上对应的两个U理颜色q行加权q_Q最后的l果作ؓ单个像素倹{这Uؓ了图元中的一个像素,而结合了两幅U理Q共8个像素的技术,UCؓ“三线性过?#8221;Q因为它在纹理的三个方向----u?v和纹理别上都进行了U性过滤?/font>
可以通过IDirect3DDevice9::SetSamplerState()函数讄实际渲染时纹理过滤的最大敎ͼ其中需要将W二个参数设为D3DSAMP_MAXMIPLEVELQ第三个参数设ؓ实际渲染时纹理过滤的最大数。下面的CZ代码讄U理?的最大多U纹理过滤Cؓ16?/p>
g_device->SetSamplerState(0, D3DSAMP_MAXMIPLEVEL, 16);
q可以通过IDirect3DDevice9::SetSamplerState()的第二个参数设ؓD3DSAMP_MIPMAPLODBIASQ设|多U纹理映数偏Ud{如果对某个U理映射讄正偏Ud|得到的图形结果就会比原来的更清晰Q但锯更多Q反之设偏移|得到的图形结果就会更模糊?/p>
代码Q?a title="实例下蝲" href="/Files/wc250en007/D3D/TextQuadU理映射.rar">实例下蝲
-潘宏
-2009.12.31
-本h水^有限Q疏忽错误在所隑օQ还请各位数学高手、编E高手不吝赐?/span>
-email: popyy@netease.com
原文地址Q?a >http://blog.csdn.net/popy007/article/details/5120158
一些网友写信给我希望能够了解固定流水线中世界空间到相机I间变换矩阵的具体推DE。其实之前我在《向量几何在游戏~程中的使用6》中已经单的把相机变换作Z个用基理论的例子进行了说明Q但可能仍然不够具体。这文章中Q我会尽力阐q相机变换的整个来龙去脉。希望能够对正在学习固定水U的朋友们有所帮助。这里我们仍然会在推导相机变换之前介l几个理论知识,目的是ؓ了更好的理解推导q程。我们马上开始!
在流水线中,当物体从模型坐标通过世界矩阵变换C界空间之后,它将通过相机变换从世界空间变换到相机I间。下囄固定水U中Q蓝色框中的部分是q个q程?/span>
其实Q所谓的相机I间Q就是以相机作ؓ坐标原点的一个参考系Q所以,从世界空间变换到相机I间Q就是把物体从世界坐标系Q变换到相机为原点的相机坐标p,如下图所C?/span>
左半部分是小人在世界I间中的位置Q右半部分是h变换到相机空间后的位|。这L一个变换可以有很多U方式来实现Q欧拉相机系l?/span>UVNpȝ?/span>Two Points & A Twist{等。这里我们讨论最为广泛的UVNpȝ构徏相机矩阵Q如果读者对其他Ҏ感兴,可以查找相关的资料。我们仍然讨?/span>OpenGL的相机矩늚推导Q其?/span>API可以cM的推对{?/span>
我们在《向量几何在游戏~程中的使用6》中提到了正交矩阵,q是在基理论基础上的一个概念(如果对基理论不是很熟悉,请参考《向量几何在游戏~程中的使用6》)。正交矩阉|有列Q行Q向量构成了一?strong>标准正交?/strong>Q它的列向量都是互相正交Qƈ且长度ؓ1Q,因此Q可以把正交矩阵看成是对一个坐标系的描q。同Ӟ我们知道Q?strong>同一个向量,在不同的Z面的坐标是不同的。因此,可以用正交矩阉|代表坐标p(也可以看作基Q从而写出在l一的参考系Q全局坐标p)下同一个向量在不同Z的坐标?/span>
上面的式子表C,参考系中向?/span>v在基Q中的坐标?/span>v’Q在?/span>R中的坐标?/span>v’’Q注意这里的环境下基矩阵是用列向量表C的Q这L乘之后的l果表示的是基向量的U性组合)。如下图Q黑色基表示的是参考系Q红色是?/span>QQ蓝色是?/span>RQ?/span>v是参考系中的一个向量?/span>
Z让大家更清楚Q我举一个例子:
上式的意思是Q参考系中的向量vQ在?/span>Q( 1 0 0 ), ( 0 1 0 ), ( 0 0 1)下的坐标?/span>( 1 2 6 )Q在?/span>R( 0 1 0 ), ( 0 0 1 ), ( 1 0 0 )下的坐标?/span>( 2 6 1 )。注意,我们所讨论的所有基和向量的关系都只是线性表C的关系Q没有位Udp,因此我们?/span>3D向量表示Q而不?/span>4D的齐ơ表C(如果寚wơ坐标不是很熟悉Q请参考《深入探索透视投媄变换》中的齐ơ坐标部分)?/span>
q样Q已知一个基Q和向?/span>v在它之中的坐?/span>v’Q以及另外一个基RQ我们可以通过v=Qv’=Rv’’公式来计?/span>v’’?/span>
上面是?/span>v’’的公式,注意到右辚w要计基R的逆矩?/span>R^-1Q因为基R是正交矩阵,而正交矩늚一个重要性质是逆等于{|。因此,我们可以把它写成
q个公式是坐标转换公式。特别地Q如?/span>Q是和参考系相同的坐标系Q?/span>3D~程中大多数情况下如此)Q比如世界坐标系Q则Q是一个单位矩?/span>IQ则我们可以把它写成
q个坐标转换公式可以解释为:对于世界坐标pM的向?/span>v’Q它在坐标系R中的坐标?/span>v’’。我们在后面会用到这个公式?/span>
除了用正交矩阉|阐述坐标转换Q我们还可以使用点积所代表?strong>qE度Q?/span>colinear amountQ来描述坐标转换Q?/span>AndréLaMothe的?/span>Tricks Of The 3D Game Programming Gurus》)。这个理论基于点U的几何意义Q一个向量在另一个向量上的共U程度。比如两个向?/span>v?/span>s点积
几何意义是v?/span>s方向上的投媄长和s的长的乘U,或者是s?/span>v方向上的投媄长和v的长的乘U(U的W号为:?/span>v?/span>s的角度小?/span>90度,Uؓ正,如果是直角,UؓӞ否则Q?/span>
q一步地Q如?/span>v是一个单位向量,则这个点U可以解释ؓs?/span>v方向上的投媄长;如果s是一个单位向量,则可以解释ؓv?/span>s方向上的投媄ѝ现在,我们把点U推q到基的层次上,把一个向?/span>v’和一个基R的三个单位u向量q行点积Q点U得到的三个值则表示q个向量在这个基下的坐标v’’
数学表达?/span>
h意,Z?/span>v’能够和基的每一个u向量q行点积Q我们必L基写成{|Ş式,卌向量乘法Q否则就变成了线性组合的形式。这个公式的意义是世界I间中的向量v’和基R的u向量q行点积从而得?/span>v’?/span>R下的qE度——坐标v’’。这个公式和上面我们得到的坐标{换公式一模一栗实际上我们是从两个不同的方向解释同一个公式,希望你能够把两个方向都理解?/span>
UVNpȝ本n是一个基。如下图所C,三个基向?/span>UQ?/span>VQ?/span>N分别指向相机的右斏V上方和后方从而构成右手坐标系Q相机则处于坐标原点?/span>
使用UVNpȝ可以非常方便的设|相机朝向。它的构E如下如所C?/span>
在参考系下(q里是世界坐标系Q,我们l定相机的位|?#8212;—eyeQ被观察的小人的位置——lookatQ以及一个辅助向?#8212;—参考系中表C?#8220;上方”的向?/span>upQ这个向量会影响U?/span>V的生成,因ؓ以后求出?/span>V向量会在up?/span>N向量所军_的^面上Q有兴趣可以自己证明一下)Q所以可以通过q个向量让相Z生不同的偏{?/span>
首先我们求出向量N
很简单,用目标位|减ȝ机的位置Q就是图中的步骤2。第3步,我们求出向量U。这一步需要用辅助向?/span>upQ如果不希望相机产生偏{Q一般取(0, 1, 0)
U使用向量的叉乘实玎ͼ是图中的步?/span>3。最后,使用N?/span>U计算出向?/span>V
最后将计算出的UQ?/span>V?/span>Nq行单位化,得C相机?/span>UVNpȝ。结合上面我们谈到的坐标转换理论Q我们可以把UVNpȝ看作是相机的基,从而可以方便的把一个向量在世界坐标和相机坐标进行{换?/span>
OpenGL?/span>gluLookAt(eyex, eyey, eyez, lookatx, lookaty, lookatz, upx, upy, upz)Ҏ是使用的上面的步骤q行相机矩阵的设|。它的前三个参数是相机的位|向量,中间三个参数是所观察的目标位|向量,最后三个参数就是辅助向?/span>up?/span>
上面我们已经说明?/span>UVNpȝQ标准流水线中就是用了UVNpȝ来描q相机?/span>U, V, N分别对应相机坐标pȝ三个基向量?/span>
此外Q对于一个相机来_它在开始的时候和世界坐标pL重合的,用户控制相机在世界空间中Ud之后Q相机的状态可以用两个属性来描述——朝向和位|。也是_有了q两个属性,一个相机模型在世界中的状态就定了。而这两个属性,我们用变换的理论来描qͼ是旋{和^UR可以想象,对于世界中的M一个相机状态,我们都可以把它看成是Q相机先围绕自n基原Ҏ转一定的角度Q然后^Ud世界I间的某个地斏V下囑ֱCZq个q程
图中Q红色是相机的基Q而黑色是世界的基Q也是参考系。小人是世界中的一个物体。相机在Ud之前Q两个基是重合的。当相机在屏q中定位Ӟ它首先会q行朝向的确?#8212;—旋{Q然后进行位|的定——q移。图中的Rotation?/span>Translation两步是相机定位时所发生的变换。可以看到相机相对于h的运动。而当q行相机变换的时候,h应该从世界基变换到相机的基里面。这P他应该进行一个相机定位的逆定位,先逆^Ud人和相机Q然后再逆旋转小人和相机Q最后相机归位,h随相机变C相机I间。这是由Inverse Translation?/span>Inverse Rotation两个步骤完成的,q两个步骤就是相机变换。现在我们推D个变换。我们把关系写出来,相机本n的变?/span>C包括两个元素
其中T是^Ud换,R是旋转变换。而相机变换是相机本n变换的逆变?/span>
q个C^-1是我们要求出的相机变换。其?/span>T^-1很容易求出,?/span>
?/span>R^-1没有这么容易求出来了。所以,我们不求它,我们?/span>UVNpȝ。什么意思?L上面的那张相机变换的图,当相机变换进行完Inverse Translationq一步之后,相机的原点和世界原点重合了Q也是处理完了关于q移的变换。接下来我们要做的是逆旋转,而其?strong>逆旋转的目的Q就是要得到目前世界坐标中经q逆^U?/strong>的小人在相机坐标pM的坐?/strong>。是不是似曾相识Q我们的坐标变换理论派上用Z。我们回忆上面坐标变换的公式
q个坐标转换公式可以解释为:对于世界坐标pM的向?/span>v’Q它在坐标系R中的坐标?/span>v’’。那么,我们可以套用在这里:对于世界坐标中的已经l过逆^Uȝ坐标v’Q它在相机坐标系R中的坐标?/span>v’’。什么是相机坐标p?/span>RQ就是我们的相机UVNpȝQ就?/span>
则相机变换的完整公式是
q里Q?/span>v是小人在世界I间中的坐标Q?/span>v’’是小人在相机I间中的坐标。则相机变换矩阵是
xQ我们就完成了相机矩늚推导。物体经q这个矩阵就从世界空间变换到了相机空_{待水U对它进行投影变换?/span>OpenGL׃用了上面推导出的最后的那个矩阵。希望你能够理解q个推导q程Q如果你有什么问题或者不同的看法Q请一定给我发?/span>J下次见!
para Q?/font>其中p0, p1, p2分别指向三角形的三个点Qposition为射Uv点,direction为射U方向向量,u,v,Z炚w心坐标,因ؓ不可能只点到点上,可能点在三角形范围内Qdistancev点到交点距离Q成功返回TRUEQ失败返回FALSE?br>
vPickPos = v0 * ( 1-u-v) + v1*u + v2*v = v0 + u * (v1 - v0) + v * (v3 - v0);
特别注意Q方向向量必Mؓ单位向量Q即pRayDir - pRayPos 为单位向量否则,pDist的值和向量长度成正比关p?/span>
?如果是仅是求地表某点高度
则可用uv重心求法(注意上述W一点的d3d的那个uv重心求法不太一?他的uv跟他的向量走?)
float u = (fX-(int)fX);
float v = (fY-(int)fY);
float p0 = fHeight[0];
float p1 = fHeight[1];
float p2 = fHeight[2];
float p3 = fHeight[3];
if(u>v){ // 双
return p0 + u * (p1 - p0) + v * (p3 - p1);;
}
else{ // 左边
return p0 + u * (p3 - p2) + v * (p2 - p0);
}