如何在 3D 中对导入的波前 OBJ 文件实现对象碰撞

Posted

技术标签:

【中文标题】如何在 3D 中对导入的波前 OBJ 文件实现对象碰撞【英文标题】:How to implement object collision on imported wavefront OBJ files in 3D 【发布时间】:2019-07-10 16:51:20 【问题描述】:

我正在 pyGame 中制作 3D 迷宫游戏,并在 OBJ 文件中制作环境,并使用 pyGame 网站上的 OBJFileLoader 将其加载到我的游戏中。但是当我实现运动控制时,相机会穿过模型。如何检测我的相机和模型之间的碰撞以便修复?

我考虑过使用矩形碰撞检测,但我能找到的所有实现都是 2D 的,并且很难尝试在 3D 中进行,而且使用 obj 文件并没有让它变得更容易。我还在某处读到了可以使用光线追踪的文章,但找不到与在 pyGame 中使用光线投射相关的任何内容。

以下是我在主循环中用于控制游戏内移动的代码

while 1:
    for event in pygame.event.get():
        if event.type == QUIT:
            sys.exit()
        if event.type == KEYUP and event.key == K_ESCAPE:
            sys.exit()

    time_passed = clock.tick()
    time_passed_seconds = time_passed / 1000.

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
    glLoadIdentity()

    pressed = pygame.key.get_pressed()

    rotation_direction.set(0.0, 0.0, 0.0)
    movement_direction.set(0.0, 0.0, 0.0)

    if pressed[K_a]:
        rotation_direction.y = +1.0
    elif pressed[K_d]:
        rotation_direction.y = -1.0
    if pressed[K_w]:
        movement_direction.z = -1.0
    elif pressed[K_s]:
        movement_direction.z = +1.0

    # Calculate rotation matrix and multiply by camera matrix
    rotation = rotation_direction * rotation_speed * time_passed_seconds
    rotation_matrix = Matrix44.xyz_rotation(*rotation)
    camera_matrix *= rotation_matrix

    # Calcluate movment and add it to camera matrix translate
    heading = Vector3(camera_matrix.forward)
    movement = heading * movement_direction.z * movement_speed
    camera_matrix.translate += movement * time_passed_seconds

    # Upload the inverse camera matrix to OpenGL
    glLoadMatrixd(camera_matrix.get_inverse().to_opengl())

    glCallList(obj.gl_list)

    pygame.display.flip()

我很困惑如何真正阻止用户穿过墙壁,我需要这样做才能让我正在制作的迷宫游戏真正工作。

【问题讨论】:

您也许可以根据迷宫的布局做出一些简化的假设。从自上而下的角度来看,它本质上是“2D”吗?它是否遵循网格?这是在第一人称视角(在这种情况下,相机可以被视为一个点或边界球体)还是第三人称视角(在这种情况下,您可以制作一个表示对象边界的简化网格,而不是测试实际的网格本身三角形按三角形)? 【参考方案1】:

一般来说,使用 3D 几何网格作为碰撞检测数据并不是一个好主意。通常我们这样做的方式是使用更简单的碰撞几何体(理想情况下由简单的基元组成,例如盒子、圆柱体、球体、平面 - 尽管在某些情况下可以使用三网格)。玩家/相机通常被表示为一个胶囊,我们根据几何形状测试胶囊。在 3D 中实现这种形式的碰撞检测真的很难。

如果可以将迷宫游戏简化为 2D 问题(例如俯视图),则定义一组定义迷宫轮廓的 2D 线,并处理播放器/相机作为一个圆圈。

即使是 2D 场景也很困难。最好的系统需要求解大量联立方程以确定最近的交叉点。随着迷宫大小的增加,解决这个问题的复杂性变得非常令人不快(即您需要使用某种形式的空间分区,例如 BSP 树、四叉树等)

这是一个非常困难的问题,这就是为什么大多数理智的人会简单地使用物理引擎来为他们执行这些计算。我可能会建议您首先尝试使用简单的 2D 物理引擎,例如Box2D。如果您绝对需要 3D 碰撞检测,那么您可能想要查看 PhysX、bullet 或 Havok。

【讨论】:

以上是关于如何在 3D 中对导入的波前 OBJ 文件实现对象碰撞的主要内容,如果未能解决你的问题,请参考以下文章

解析波前 obj 文件格式

波前 OBJ 文件可以具有每个对象(或每个组)的顶点吗?

Machine learning for improved image-based wavefront sensing

波前 obj 模型加载器索引问题

ALU 如何在 AMD GPU (VLIW) 中执行指令?

如何导入 3D 场景(.obj 文件和 .mtl 文件)