3d格斗游戏的碰撞检测

https://blog.csdn.net/yaonai2003/article/details/8791493

在网上搜索了一些资料,最后采用了obb的碰撞检测,方法如下:

1 在3ds max中,将biped骨骼的大小设置恰当,在使用方框显示骨骼的时候能比较准确的包围住角色,如下图:

 

然后选中所有的骨骼,使用maxscript脚本导出来。脚本其实比较简单,代码如下:

---------------------------------------------------------------------------------

 
  1. -- file function

  2. fn existFile fname = (getfiles fname).count != 0

  3.  
  4. -- main

  5. fileName = "F://Work//MyProjects//3DGame//3dsmax_data//fight_action_data.txt"

  6. if existFile fileName then deleteFile fileName

  7. createFile fileName

  8. fp = openFile fileName mode:"at"

  9.  
  10. for sel in selection do

  11. (

  12. -- get bounding box

  13. bb = nodeLocalBoundingBox sel

  14. -- print bb

  15. -- print sel.transform

  16. -- print "-------------"

  17. position = (bb[2] + bb[1]) / 2

  18. size = bb[2] - bb[1]

  19.  
  20. len = sel.transform[1].x ^ 2 + sel.transform[1].y ^ 2 + sel.transform[1].z ^ 2

  21. len = len ^ 0.5

  22. x1 = sel.transform[1].x / len

  23. y1 = sel.transform[1].y / len

  24. z1 = sel.transform[1].z / len

  25.  
  26. extent1 = (size.x * x1 + size.y * y1 + size.z * z1) / 2

  27.  
  28.  
  29. len = sel.transform[2].x ^ 2 + sel.transform[2].y ^ 2 + sel.transform[2].z ^ 2

  30. len = len ^ 0.5

  31. x2 = sel.transform[2].x / len

  32. y2 = sel.transform[2].y / len

  33. z2 = sel.transform[2].z / len

  34.  
  35. extent2 = (size.x * x2 + size.y * y2 + size.z * z2) / 2

  36.  
  37. len = sel.transform[3].x ^ 2 + sel.transform[3].y ^ 2 + sel.transform[3].z ^ 2

  38. len = len ^ 0.5

  39. x3 = sel.transform[3].x / len

  40. y3 = sel.transform[3].y / len

  41. z3 = sel.transform[3].z / len

  42.  
  43. extent3 = (size.x * x3 + size.y * y3 + size.z * z3) / 2

  44.  
  45. print sel.name to:fp

  46.  
  47. print((extent1 as string) + "," + (extent2 as string) + "," + (extent3 as string)) to:fp

  48. print((position.x as string) + "," + (position.z as string) + "," + ((-position.y) as string)) to:fp

  49. print((x1 as string) + "," + (z1 as string) + "," + ((-y1) as string)) to:fp

  50. print((x2 as string) + "," + (z2 as string) + "," + ((-y2) as string)) to:fp

  51. print((x3 as string) + "," + (z3 as string) + "," + ((-y3) as string)) to:fp

  52. )

  53.  
  54. close fp

---------------------------------------------------------------------------------

生成的文件格式如下:

---------------------------------------------------------------------------------

 
  1. "Bip01"

  2. "2.18656,2.18656,2.18656"

  3. "0.583941,40.3044,-1.10637"

  4. "0.555635,0.0,0.831426"

  5. "0.831426,0.0,-0.555635"

  6. "0.0,1.0,0.0"

  7. "Bip01 Pelvis"

  8. "6.1669,5.71345,5.46639"

  9. "0.583941,40.3044,-1.10637"

  10. "-1.21579e-006,1.0,6.67132e-007"

  11. "0.481059,0.0,0.876688"

  12. "0.876688,1.3868e-006,-0.481059"

  13.  
  14. …………

---------------------------------------------------------------------------------

其中每个盒子的第二行数据就是盒子的半个长度,宽度和高度,和第四行至第六行的变换矩阵是一一对应的

第三行就是盒子的中心点位置,是全局坐标

第四行至第六行就是盒子在三个面方向上的标准变换矩阵了。

数据有了之后,就可以用obb碰撞算法进行碰撞检测了。

obb算法可以参考:

http://hi.baidu.com/jorbin/blog/item/2e7c2df5c146f423bd310977.html

或者他引用的一个国外的网址:

http://www.gamasutra.com/view/feature/3383/simple_intersection_tests_for_games.php?page=5

最后贴一个我在ogre里面根据obb数据画出来的碰撞盒子的图片,主要作用是调试碰撞检测是否正确:

猜你喜欢

转载自blog.csdn.net/lingyun5905/article/details/86382867