在Pygame中一次显示多个3D对象时出现问题

时间:2018-08-03 09:08:44

标签: 3d pygame models

因此,我看了this tutorial(很棒的视频),基本上复制了他的代码。一切进展顺利,所以我决定开始升级。我添加了模型文件(“ .smd”格式),如下所示:

obj:cube1 {
    v:1,-2,-2;
    v:5,-2,-2;
    v:5,2,-2;
    v:1,2,-2;
    v:1,-2,2;
    v:5,-2,2;
    v:5,2,2;
    v:1,2,2;
    e:0,1;
    e:1,2;
    e:2,3;
    e:3,0;
    e:4,5;
    e:5,6;
    e:6,7;
    e:7,4;
    e:0,4;
    e:1,5;
    e:2,6;
    e:7,3;
    f:0,1,2,3:red;
    f:4,5,6,7:red;
    f:0,1,5,4:red;
    f:2,3,7,6:red;
    f:0,3,7,4:red;
    f:1,2,6,5:red;
}
obj:cube2 {
    v:-1,-3,2;
    v:1,-3,2;
    v:1,-1,2;
    v:-1,-1,2;
    v:-1,-3,4;
    v:1,-3,4;
    v:1,-1,4;
    v:-1,-1,4;
    e:0,1;
    e:1,2;
    e:2,3;
    e:3,0;
    e:4,5;
    e:5,6;
    e:6,7;
    e:7,4;
    e:0,4;
    e:1,5;
    e:2,6;
    e:7,3;
    f:0,1,2,3:yellow;
    f:4,5,6,7:yellow;
    f:0,1,5,4:yellow;
    f:2,3,7,6:yellow;
    f:0,3,7,4:yellow;
    f:1,2,6,5:yellow;
}
obj:cube3 {
    v:0,0,-4;
    v:2,0,-4;
    v:2,2,-4;
    v:0,2,-4;
    v:0,0,-2;
    v:2,0,-2;
    v:2,2,-2;
    v:0,2,-2;
    e:0,1;
    e:1,2;
    e:2,3;
    e:3,0;
    e:4,5;
    e:5,6;
    e:6,7;
    e:7,4;
    e:0,4;
    e:1,5;
    e:2,6;
    e:7,3;
    f:0,1,2,3:blue;
    f:4,5,6,7:blue;
    f:0,1,5,4:blue;
    f:2,3,7,6:blue;
    f:0,3,7,4:blue;
    f:1,2,6,5:blue;
}

我使用对象来简化复杂模型文件的定向。 为了使文件可读,我使用了一个编译器,该编译器将创建如下内容:

{'cube1': [[(1, -2, -2), (5, -2, -2), (5, 2, -2), (1, 2, -2), (1, -2, 2), (5, -2, 2), (5, 2, 2), (1, 2, 2)], [(0, 1), (1, 2), (2, 3), (3, 0), (4, 5), (5, 6), (6, 7), (7, 4), (0, 4), (1, 5), (2, 6), (7, 3)], {(0, 1, 2, 3): 'red', (4, 5, 6, 7): 'red', (0, 1, 5, 4): 'red', (2, 3, 7, 6): 'red', (0, 3, 7, 4): 'red', (1, 2, 6, 5): 'red'}], 'cube2': [[(-1, -3, 2), (1, -3, 2), (1, -1, 2), (-1, -1, 2), (-1, -3, 4), (1, -3, 4), (1, -1, 4), (-1, -1, 4)], [(0, 1), (1, 2), (2, 3), (3, 0), (4, 5), (5, 6), (6, 7), (7, 4), (0, 4), (1, 5), (2, 6), (7, 3)], {(0, 1, 2, 3): 'yellow', (4, 5, 6, 7): 'yellow', (0, 1, 5, 4): 'yellow', (2, 3, 7, 6): 'yellow', (0, 3, 7, 4): 'yellow', (1, 2, 6, 5): 'yellow'}], 'cube3': [[(0, 0, -4), (2, 0, -4), (2, 2, -4), (0, 2, -4), (0, 0, -2), (2, 0, -2), (2, 2, -2), (0, 2, -2)], [(0, 1), (1, 2), (2, 3), (3, 0), (4, 5), (5, 6), (6, 7), (7, 4), (0, 4), (1, 5), (2, 6), (7, 3)], {(0, 1, 2, 3): 'blue', (4, 5, 6, 7): 'blue', (0, 1, 5, 4): 'blue', (2, 3, 7, 6): 'blue', (0, 3, 7, 4): 'blue', (1, 2, 6, 5): 'blue'}]}

在线框模式下,一切正常。但是在显示脸部时不起作用。我试图使人脸显示算法与我的多个对象兼容。它仅显示最后一个颜色的第一个对象。在此示例中,它显示带有蓝色面孔的cube1,除此之外没有其他内容。 这是“原始”代码的一部分(我在对象之前使用的那一部分):

vert_list = []
screen_coords = []

for x, y, z in verts:
    x -= cam.pos[0]
    y -= cam.pos[1]
    z -= cam.pos[2]

    x, z = cam.rotate2d((x, z), cam.rot[1])
    y, z = cam.rotate2d((y, z), cam.rot[0])

    vert_list.append((x, y, z))

    f = round((width // 2) / z)
    x, y = x * f, y * f

    screen_coords.append((currX + x, currY + y))

face_list = []
face_color = []
depth = []

if not WIREFRAME:

    for f in range(len(faces)):
        face = list(faces)[f]

        on_screen = False

        for i in face:
            x, y = screen_coords[i]
            if vert_list[i][2] > 0 and 0 < x < width and y and y < height:
                on_screen = True
                break

        if on_screen:
            coords = [screen_coords[i] for i in face]
            face_list.append(coords)
            face_color += colors[f]

            depth.append(sum(sum(vert_list[j][i] for j in face) ** 2 for i in range(3)))

    order = sorted(range(len(face_list)), key=lambda i: depth[i], reverse=True)

    for i in order:
        pygame.draw.polygon(window, face_color[i], face_list[i])

这是我现在正在使用的代码:

vert_list = []
screen_coords = []

for obj in OBJECTS:
    name = obj
    obj = OBJECTS[name]
    verts = obj[0]
    for x, y, z in verts:
        x -= cam.pos[0]
        y -= cam.pos[1]
        z -= cam.pos[2]

        x, z = cam.rotate2d((x, z), cam.rot[1])
        y, z = cam.rotate2d((y, z), cam.rot[0])

        vert_list.append((x, y, z))

        f = round((width // 2) / z)
        x, y = x * f, y * f

        screen_coords.append((currX + x, currY + y))

face_list = []
face_color = []
depth = []

for obj in OBJECTS:
    name = obj
    obj = OBJECTS[name]
    faces = obj[2]

    if not WIREFRAME:

        for f in faces:
            face = f

            on_screen = False

            for i in face:
                x, y = screen_coords[i]
                if vert_list[i][2] > 0 and 0 < x < width and y and y < height:
                    on_screen = True
                    break

            if on_screen:
                coords = [screen_coords[i] for i in face]
                face_list.append(coords)
                face_color.append(COLORS_DICT[faces[f]])

                depth.append(sum(sum(vert_list[j][i] for j in face) ** 2 for i in range(3)))

        order = sorted(range(len(face_list)), key=lambda i: depth[i], reverse=True)

        for i in order:
            pygame.draw.polygon(window, face_color[i], face_list[i])

0 个答案:

没有答案