??xml version="1.0" encoding="utf-8" standalone="yes"?>
]]>
]]>
GRE的空间变?对于新手来说是一个头疼的问题,而其中的陷阱也是一堆一?即我已l爬些陷?我还是觉得有必要讲一?
translate()q个秘的函?|上发现一个朋友中了陷?
以下黑体字ؓ(f)论坛某个|友的错误理?
----------------------------------------------------------------------------------------------------------------------------------
在CSDN和gameres上都发了q个问题Q一直没{,不知道这儿怎么P
void createScene() {
... //W一个物?坐标原点)
Entity* head = mSceneMgr->createEntity("object1", "ogrehead.mesh");
head->setMaterialName("Examples/Rockwall");
SceneNode* node1 = rootNode->createChildSceneNode();
node1->attachObject(head);
//W二个物?span class=Apple-converted-space>
head = mSceneMgr->createEntity("object2", "ogrehead.mesh");
SceneNode* node2 = node1->createChildSceneNode();
node2->attachObject(head);
node2->translate(Vector3(50, 0, 0), SceneNode::TS_PARENT);
//W三个物?span class=Apple-converted-space>
我对q个参数的理解是Q?br>TS_WORLDQ不当前节Ҏ(gu)在哪个节点下Q他的操作都是相对于世界坐标pȝ原点的?br> 如node3是在node2下面Q所以他的初始世界坐标应该是(50,0,0)Q?br> 如果它translate(Vector3(0, 50, 0), SceneNode::TS_LOCAL)Q?世界坐标应该?50, 50, 0)
如果它translate(Vector3(0, 50, 0), SceneNode::TS_WORLD)Q?相对于世界坐标原点的q移Q世界坐标应该是(0, 50, 0)
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
q个|友遇到的问?其实是translate变换的问?Z么他?x)这么理?我们慢慢分析:
translate()q个函数,其实是相对于父节点的相对Ud,而不是那个网友理解的l对Ud.
但是如果是相对于父节点的相对Ud,q要选择3个参考空间干???
q就是关键所?q?个参考空?是决定相对移动量的方向的,而不是那个网友理解成的移动的位置!!!
Z么他的代码中的第3个节Ҏ(gu)论怎么改变参考空间结果都一?如果理解成方?p然开朗了.
因ؓ(f)世界原点,父节?他本w?q?个节点的面向的方向都是一L(fng)(默认-Z方向),所以相对移动的值是一?都是Y方向相对Ud50
如果世界原点,父节炚w是默认面向Z正方?本n节点旋{90度面向Y的方?br>如果他在本地I间translate(Vector3(0, 50, 0),SceneNode::TS_LOCAL),
因ؓ(f)他本w朝向Y, 在本地空间Y方向Ud50, 在世界空?其实是-Z方向Ud?0.
一句话:都是相对父节点移?0单位,而参考空间只是决定这50个单位移动的方向!
所以参考空间理解成朝向,对?br>世界I间----------认定世界原点的朝向ؓ(f)标准朝向,默认-Z方向
父节点空?---------认定父节点的朝向为标准朝?br>本地I间--------------认定本n节点的朝向ؓ(f)标准朝向
那个|友的理?其实合情合理,他的理解其实是下面假想的函?
setPosition(TS_WORLD);
setPosition(TS_PARENT);
setPosition(TS_LOCAL);
可惜q只是假?讄位置的函数ƈ没有参考空间可以选~~~
OGREZ么不讄q样的函数呢?因ؓ(f)其实已经有替代的函数?
setPosition() // 相对父空间坐?/span>
setDerivedPosition() // 世界I间l对坐标
而本地空间的讄位置函数Ҏ(gu)不需?...
最?回头一?Z么容易把translate()理解?...原因是translate(TS_PARENT)相对父空间移?br>的时?如果把参考空间父I间理解成方向或者位|?2U情况下l果是正好是一L(fng),巧合?br>是q种巧合,暗藏了一个陷q?让很多h认ؓ(f)理解成位|正好是对的...
不信看源?
因ؓ(f)mPosition相对于父节点的位|和方向,
所以计结果都要换成父空间相?
本地I间,朝本w节点的朝向Udd,换到mPosition的所在的父空间只需要旋转一定角?
q个角度应该是本w节Ҏ(gu)向和父节点的方向的夹?正好是mOrientation
mPosition += mOrientation * d;
世界I间,朝世界原点的朝向Udd ,换到mPosition的所在父I间只需要旋转一定角?
q个角度应该是世界原Ҏ(gu)向和父节点的方向的夹?正好是父节点世界l对角度再取?
(Z么要取反,2个四元数怹是不能交换的,因ؓ(f)世界节点和父节点夹角 != 父节点和世界节点夹角,正好相反)
mPosition += (mParent->_getDerivedOrientation().Inverse() * d)
/ mParent->_getDerivedScale();
父节点空?朝父节点的朝向移动d ,换到mPosition的所在父I间只需要旋转一定角?
父空间{到父I间....其实角度是一致的
应该是mPosition += Quaternion::IDENTITY * d;
{h(hun)于mPosition += d;
人物的动作分Z半nQ下半n动作
上半w动作:(x)休闲、走路(向前、向后、向左、向叻I(j)、跑步(向前、向后、向左、向叻I(j)、准备战斗、蟩Q开始蟩Q蟩循环、结束蟩Q?br>下半w动作:(x)休闲、走路(向前、向后、向左、向叻I(j)、跑步(向前、向后、向左、向叻I(j)、准备战斗、蟩Q开始蟩Q蟩循环、结束蟩Q?/p>
控制逻辑Q?/p>
*******************************************************(zhn)伤的分割线****************************************************************
队列命o(h)问题Q?br>1.走\的时候队列创建太频繁Q进行解冻I使用队列池)(j)
2.上面一个队列执行完毕后执行下一个队列?br>3.队列要能够同时处理两个命令,因ؓ(f)在运动的时候是一个命令,战斗的时候是另外一个命令?br>4.初步军_使用两个队列Q分别控制上半n和下班n动作?/p>
W一U解x案思\整理Q走?dQ:(x)
1.命o(h)分类Q外部根据命令往队列里面插入命o(h)
2.命o(h)开始执行,成员变量C命o(h)的参敎ͼq在渲染的每一帧执行命令?br>3.执行的每一帧插|处理命o(h)
举例Q?br>1.往命o(h)队列中插入走路命令?nbsp; 1
2.在每一帧中执行走\命o(h)Q保存目标位|和源位|,q进行插倹{?br>3.往命o(h)队列中插入准备攻d?nbsp; 2 有一帧不走动了。解x\Q执行攻ȝ时候也执行走\插倹{?Q有可能没有问题Q因为速度q快
4.开始执行准备攻d?nbsp;
5.在每一帧中执行准备d命o(h) 3
6.往命o(h)队列中插入走路命令?nbsp;
7.在每一帧中执行走\命o(h)Q保存目标位|和源位|,q进行插?nbsp; 4
xQ?br>1.上半w和下半w无M影响Q战斗:(x)如果下半w进行休闲动作才改变Q否则只改变动作。移动:(x)如果上半w休闲才改变Q否则不改变Q?br>2.上半w动作媄(jing)响下半n.Q施法:(x)直接修改上下半n动作为施法)(j)
3.动作播放l束后处理ؓ(f)
队列影响Q?br>W二U情늛接用队列一个一个处理?br>W一U情冉|较难处理Q在处理战斗时候,处理换动作命令,然后处理Ud命o(h)Q?br>//StartAction分ؓ(f)全n和上半n。。。。?/p>
动作分组Q?br>休闲动作Q不打断动作Q进度条动作Q?动作播放完毕?/p>
不可行:(x)因ؓ(f)只有一个队列,所以执行走路命令的时候不能处理战斗的命o(h)?此方法抛弃?/p>
*******************************************************希望的分割线****************************************************************
ȝ(ch)Q?br>解决Ҏ(gu)Q?br>对外接口Q外部参C上半nQ下半n动作Q根据命令类型分配到上半w和下半w队列中去,控制上半w和下半w休Ԍ战斗?/全n动作或者上半n动作?/p>
1.分ؓ(f)上半w,下半w动作两个命令队列分别处理上半n和下半n动作?/p>
举例Q?br>走\+战斗Q?br>1.命o(h)队列中插入走路命?br>2.向上半nQ下半n队列中分发各分发一个走路命令?br>3.?x)同时处理走路命令?br>4.命o(h)队列中增加战斗命令?br>5.判断下半w时候休Ԍ不是的话分发战斗命o(h)Q向上半w队列中分发战斗命o(h)?br>6.处理上半w,下半w动L放过E中的处理?/p>
注意Q?br>1.上半w的动作和下半n一L(fng)时候。根据下半n的动作数控制?br>2.分发器,Ҏ(gu)不同的游戏有不同的分发原则?/p>
*******************************************************希望的分割线****************************************************************
表面和其它一些Direct3D资源被放在多U内存池中。内存池的种cȝD3DPOOL枚Dcd的一个成员来指定。可用到的内存池有下列几U:(x)
D3DPOOL_DEFAULT——表CDirect3D根据资源的cd和用途把它们攑֜最合适的地方。这有可能是昑֭、AGP内存或者系l内存中。值得注意的是Q这U内存池中的资源必须要在IDirect3DDevice9::Reset被调用之前消毁掉Qƈ且再ơ用时必须重新初始化?/p>
理解Q?pȝ自动分配内存Q栈内存一Ppȝ自动分配内存位置?/p>
D3DPOOL_MANAGED——资源将由Direct3D理q且按设备的需要来指定攑֜昑֭q是攑֜AGP内存中。当应用E序讉K和改变资源时它先把这些资源拷贝到pȝ内存中,当需要时Direct3D?x)自动把它们拯到显存里?/p>
理解Q直接放在显存中Q当改变资源Ӟ拯?x)内存,修改完再回显存,不需改变的资源比较适合?/p>
D3DPOOL_SYSTEMMEM——指定资源放在系l内存中?/p>
D3DPOOL_SCRATCH——指定资源放在系l内存中Q它与D3DPOOL_SYSTEMMEM不同之处在于使用q些资源不必受图形设备的限制。因此,参数使图形设备不能访问该内存池的资源Q但资源可以怺拯?/p>
理解Q放在内存中Q当囑Ş讑֤不能讉KQ经常访问和修改的资源?/p>
内存锁定方式
D3DLOCK_DISCARD——这个参C仅会(x)在动态缓存时被用。它指示g丢弃~存q返回一个指向新分配的缓存的指针。这是很有用Q因为当我们存取一个新分配的缓存时它允许硬件l从丢弃的缓存渲染。这防止了硬件gq?/p>
动态缓存的时候用,原有的会(x)被丢弃?/p>
D3DLOCK_NOOVERWRITE——这个参C仅会(x)在动态缓存时被用。它声明你将向缓存中d数据。即你不能向已经渲染的内存中写数据。这是有好处的因Z允许你在d新数据到~存的同时让gl箋渲染?/p>
只向~存中增加数?/p>
D3DLOCK_READONLY——这个参数声明你锁定的缓存只能从中读取数据而不能写数据。这允许一些内在的优化?/p>
用参数D3DLOCK_DISCARD和D3DLOCK_NOOVERWRITE表明~存的一部分被锁定之后能l箋被用。假如硬仉|允许这些标记被使用Q则在对~存q行锁定Ӟ其他的显C操作就不会(x)中断?/p>
交换~冲cd
D3DSWAPEFFECT_DISCARDQ?nbsp; 后台的缓冲区复制到屏q上Q丢弃后备缓冲区
D3DSWAPEFFECT_FLIPQ?nbsp; 后台~冲区和前台~冲?br>D3DSWAPEFFECT_COPYQ?nbsp; 后台~冲区复制到前台~冲?nbsp;
~存创徏标志
3DUSAGE_DYNAMIC——设|这个参数可以ɾ~存是动态的?br>D3DUSAGE_POINTS——这个参数指定缓存存储原始点。这个参C仅用在顶点缓冲中?br>D3DUSAGE_SOFTWAREPROCESSING——用Y仉点处?br>D3DUSAGE_WRITEONLY——指定应用程序只能写~存。它允许驱动E序分配最适合的内存地址作ؓ(f)写缓存。注意如果从创徏好的q种~存中读数据Q将?x)返回错误信息?/p>