游戏开发论坛

 找回密码
 立即注册
搜索
查看: 10503|回复: 2

3d格斗游戏的碰撞检测

[复制链接]

1万

主题

1万

帖子

2万

积分

管理员

中级会员

Rank: 9Rank: 9Rank: 9

积分
20515
发表于 2013-1-4 22:27:21 | 显示全部楼层 |阅读模式
作者:xtxy的专栏

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

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

1.jpg

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

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

-- file function
fn existFile fname = (getfiles fname).count != 0

-- main
fileName = "F://Work//MyProjects//3DGame//3dsmax_data//fight_action_data.txt"
if existFile fileName then deleteFile fileName
createFile fileName
fp = openFile fileName mode:"at"

for sel in selection do
(
    -- get bounding box
    bb = nodeLocalBoundingBox sel
    -- print bb
    -- print sel.transform
    -- print "-------------"
    position = (bb[2] + bb[1]) / 2
    size = bb[2] - bb[1]
   
    len = sel.transform[1].x ^ 2 + sel.transform[1].y ^ 2 + sel.transform[1].z ^ 2
    len = len ^ 0.5
    x1 = sel.transform[1].x / len
    y1 = sel.transform[1].y / len
    z1 = sel.transform[1].z / len
   
    extent1 = (size.x * x1 + size.y * y1 + size.z * z1) / 2
   
   
    len = sel.transform[2].x ^ 2 + sel.transform[2].y ^ 2 + sel.transform[2].z ^ 2
    len = len ^ 0.5
    x2 = sel.transform[2].x / len
    y2 = sel.transform[2].y / len
    z2 = sel.transform[2].z / len
   
    extent2 = (size.x * x2 + size.y * y2 + size.z * z2) / 2
   
    len = sel.transform[3].x ^ 2 + sel.transform[3].y ^ 2 + sel.transform[3].z ^ 2
    len = len ^ 0.5
    x3 = sel.transform[3].x / len
    y3 = sel.transform[3].y / len
    z3 = sel.transform[3].z / len
   
    extent3 = (size.x * x3 + size.y * y3 + size.z * z3) / 2
   
    print sel.name to:fp
   
    print((extent1 as string) + "," + (extent2 as string) + "," + (extent3 as string)) to:fp
    print((position.x as string) + "," + (position.z as string) + "," + ((-position.y) as string)) to:fp
    print((x1 as string) + "," + (z1 as string) + "," + ((-y1) as string)) to:fp
    print((x2 as string) + "," + (z2 as string) + "," + ((-y2) as string)) to:fp
    print((x3 as string) + "," + (z3 as string) + "," + ((-y3) as string)) to:fp
)

close fp

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

生成的文件格式如下:

---------------------------------------------------------------------------------
"Bip01"
"2.18656,2.18656,2.18656"
"0.583941,40.3044,-1.10637"
"0.555635,0.0,0.831426"
"0.831426,0.0,-0.555635"
"0.0,1.0,0.0"
"Bip01 Pelvis"
"6.1669,5.71345,5.46639"
"0.583941,40.3044,-1.10637"
"-1.21579e-006,1.0,6.67132e-007"
"0.481059,0.0,0.876688"
"0.876688,1.3868e-006,-0.481059"
…………
…………
---------------------------------------------------------------------------------

其中每个盒子的第二行数据就是盒子的半个长度,宽度和高度,和第四行至第六行的变换矩阵是一一对应的
第三行就是盒子的中心点位置,是全局坐标
第四行至第六行就是盒子在三个面方向上的标准变换矩阵了。

数据有了之后,就可以用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数据画出来的碰撞盒子的图片,主要作用是调试碰撞检测是否正确:

2.jpg


9

主题

26

帖子

62

积分

注册会员

Rank: 2

积分
62
发表于 2013-1-5 16:19:08 | 显示全部楼层
嗯,基本原理就是这样。

1

主题

36

帖子

1442

积分

金牌会员

Rank: 6Rank: 6

积分
1442
发表于 2013-1-5 16:31:31 | 显示全部楼层
好贴,感谢分享
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-6-11 08:10

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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