为了正常的体验网站,请在浏览器设置里面开启Javascript功能!

BUG00001 BUG症状: 我在上传我做的这个源码之前,我在自己的程序中遇 ...

2017-12-08 6页 doc 35KB 53阅读

用户头像

is_281650

暂无简介

举报
BUG00001 BUG症状: 我在上传我做的这个源码之前,我在自己的程序中遇 ...BUG00001 BUG症状: 我在上传我做的这个源码之前,我在自己的程序中遇 ... BUG00001 BUG 我在上传我做的这个源码之前,我在自己的程序中遇到一个BUG,但我发现delta3d也出现同样的错误,因此先解决delta3d本身的BUG: , 在delta3d中将例子testPhysics中空中下落物块,比如按下’b’键掉下 盒子,默认将碰撞模型设为setCollisionBox,程序运行正常,如果我们采取 三角形片检测,设为testPysics.cpp line230中修改为 box->SetCollis...
BUG00001 BUG症状: 我在上传我做的这个源码之前,我在自己的程序中遇 ...
BUG00001 BUG症状: 我在上传我做的这个源码之前,我在自己的程序中遇 ... BUG00001 BUG 我在上传我做的这个源码之前,我在自己的程序中遇到一个BUG,但我发现delta3d也出现同样的错误,因此先解决delta3d本身的BUG: , 在delta3d中将例子testPhysics中空中下落物块,比如按下’b’键掉下 盒子,默认将碰撞模型设为setCollisionBox,程序运行正常,如果我们采取 三角形片检测,设为testPysics.cpp line230中修改为 box->SetCollisionMesh();//bNormalizationResult有错!,默认的SetCollisionBox正确,程序总是不定时地弹出错误,并终止程序,如下图。 , 同样的问出现在ODE中,我们下载ODE0.9的源码,编译运行“demoMovingTrimesh” 例子,当我们按下键盘“m”,天上掉下兔子,如果我们一直按下m键,则程序也会弹 出消息框: 两者错误出处函数来自odemath.h 302: static __inline void _dNormalize3(dVector3 a) { int bNormalizationResult = dSafeNormalize3(a);//返回矢量是否为 dIASSERT(bNormalizationResult);//容易出错的地方 dVARIABLEUSED(bNormalizationResult); } BUG 由此可见,问题出现在ODE中,并且这是ODE的一个BUG,网上有不同的观点:有的认 为是矢量出现为0,当然,这个错误就是这么提示的;有的认为是因为两个mesh刚刚接触,互相穿透深度为0;有的认为是ODE中全局约束力混合值CFM(见ODE中文指南)设得过小,我调到最大1还是不行;有的认为是出现“退化三角形”的缘故,这里给大家介绍下 什么是“退化三角形”: 退化三角形(degenerate triangle)是一个面积为零的三角形,或者换句话说,是一个三点位于一 线上的三角形。如果我们传入一个退化三角形到渲染管线,则该三角形显示为空。 而对退化三角形求其法向量,我们知道法向量用叉乘u|vec1||vec2|sin(theta),theta是两者夹 角,如果为退化三角形theta=0或PI,则法向量结果为0,这可能是assertion "bNormalizationResult"报错的直接原因。 我尝试过修改碰撞检测函数dCollideTTL(),将互相嵌入深度为0的情况剔除掉,也尝试过 手动判断接触点矢量是否为0,如果为0,将其置为单位矢量,,甚至还尝试过只要dCollidTTL 检测是否碰撞,而不需要求得碰撞点个数及属性,均没有解决掉这个BUG,如下: //dCollideTTL等同于PerformTest(见碰撞检测\opcode\CDTestFramework\CDTestFramework\ OBBMeshQuery.cpp(112)) int dCollideTTL(dxGeom* g1, dxGeom* g2, int Flags, dContactGeom* Contacts, int Stride) { dIASSERT (Stride >= (int)sizeof(dContactGeom)); dIASSERT (g1->type == dTriMeshClass); dIASSERT (g2->type == dTriMeshClass); dIASSERT ((Flags & NUMC_MASK) >= 1); dxTriMesh* TriMesh1 = (dxTriMesh*) g1; dxTriMesh* TriMesh2 = (dxTriMesh*) g2; dReal * TriNormals1 = (dReal *) TriMesh1->Data->Normals; dReal * TriNormals2 = (dReal *) TriMesh2->Data->Normals; const dVector3& TLPosition1 = *(const dVector3*) dGeomGetPosition(TriMesh1); // TLRotation1 = column-major order const dMatrix3& TLRotation1 = *(const dMatrix3*) dGeomGetRotation(TriMesh1); const dVector3& TLPosition2 = *(const dVector3*) dGeomGetPosition(TriMesh2); // TLRotation2 = column-major order const dMatrix3& TLRotation2 = *(const dMatrix3*) dGeomGetRotation(TriMesh2); AABBTreeCollider& Collider = TriMesh1->_AABBTreeCollider; static BVTCache ColCache; ColCache.Model0 = &TriMesh1->Data->BVTree; ColCache.Model1 = &TriMesh2->Data->BVTree; // 碰撞检测第四步:Perform a collision query // 见碰撞检测\opcode\CDTestFramework\CDTestFramework\OBBMeshQuery.cpp(112) // Collision query: Collide(ColCache, World0, World1); //Returned bool just says everything was ok. It's not the collision status Matrix4x4 amatrix, bmatrix; BOOL IsOk = Collider.Collide(ColCache, &MakeMatrix(TLPosition1, TLRotation1, amatrix), &MakeMatrix(TLPosition2, TLRotation2, bmatrix) ); // Make "double" versions of these matrices, if appropriate dMatrix4 A, B; dMakeMatrix4(TLPosition1, TLRotation1, A); dMakeMatrix4(TLPosition2, TLRotation2, B); /* if (IsOk) { if ( Collider.GetContactStatus() ) // Get collision status => if true, objects overlap { 。。。。。。。。。。。。代码很长,忽略 } }*/ dNormalize3 static __inline void _dNormalize3(dVector3 a) { int bNormalizationResult = dSafeNormalize3(a);//返回矢量是否为 /* 在common.h中有定义: #define dIASSERT(a) if (!(a)) dDebug (d_ERR_IASSERT, \ "assertion \"" #a "\" failed in %s:%d",__FILE__,__LINE__); */ // dIASSERT(bNormalizationResult);//报错的地方 // dVARIABLEUSED(bNormalizationResult); } 重新编译ODE0.9,生成ode.dll,ode.lib,将ode.dll直接覆盖delta3d中ext/bin/ode.dll,再将ode.lib 更名为oded.lib,并覆盖delta3d中ext/lib/oded.lib,再也不会出现报错了,是不是觉得很好笑?呵呵,也许目前只能这样吧,治标没治本。 BUG 给大家讲几点我修正BUG过程中学到的一点东西: , Delta3d物理引擎基于ODE,ODE可以进行刚体动态仿真和碰撞检测,碰撞检测部分有 一个通用的监测函数,判断是什么碰撞类型,比如box vs box,cylinder vs box,mesh vs mesh等。 , 每个碰撞类型都有一个类,ODE将根据碰撞检测类型分别选择不同的碰撞检测函数, 比如若是两个mesh间的碰撞检测,则调用dCollideTTL(),两个“T”代“TriMesh” 一目了然。 , Delta3d碰撞检测执行(我没有函数调用查询及执行流程查询的工具,哪位有提供 下谢谢): OnMessage->NearCallBack(dtcore/scene.cpp)->dCollide(ext/include/ode/collision)->dCollideTT L(ode/collision_trimesh-trimesh.cpp)。 , 而对于ODE,本身并没有mesh vs mesh的碰撞检测功能,需用库Opcode,大家可以上 网了解下OPCODE。因此函数dCollideTTL()函数最终将会调用OPCODE库中的函数, 在DELTA3D中看不到OPCODE 的链接库是因为ODE已经将其打包封装起来一起编 译了。没有ODE0.9和OPCODE库的兄弟可以向我索要,如果大家都没有,我将这两 个库上传到邮件。
/
本文档为【BUG00001 BUG症状: 我在上传我做的这个源码之前,我在自己的程序中遇 ...】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索