Направление рейкаста PyOpenGL неверно при перемещении камеры [закрыто]Python

Программы на Python
Anonymous
Направление рейкаста PyOpenGL неверно при перемещении камеры [закрыто]

Сообщение Anonymous »

Я делаю клон Minecraft, используя PyOpenGL, и реализовал хитовую программу, которая в основном запускает raycast относительно угла камеры, но в итоге она неправильно определяла положение камеры и разбивала блоки влево или вправо или положение камеры. Я предполагаю, что это может быть из-за моей среды Android.
Это мой файл main.py:

Код: Выделить всё

import os
import ctypes
import math
import pygame
import matrix
import block_type
import texture_manager
import camera
import chunk
import world
import hit
os.environ['PYOPENGL_PLATFORM'] = 'egl'
from OpenGL.GL import *
from OpenGL.GL.shaders import compileProgram, compileShader

VERTEX_SHADER = """#version 320 es
layout (location = 0) in vec3 vertex_position;
layout (location = 1) in vec3 tex_coords;
layout (location = 2) in float shading_values;
out vec3 local_position;
out vec3 interpolated_tex_coords;
out float interpolated_shading_value;
uniform mat4 matrix;
void main() {
local_position = vertex_position;
interpolated_tex_coords = tex_coords;
interpolated_shading_value = shading_values;
gl_Position = matrix * vec4(vertex_position, 1.0);
}
"""

FRAGMENT_SHADER = """#version 320 es
precision mediump float;
precision mediump sampler2DArray;
uniform sampler2DArray texture_array_sampler;
out vec4 fragment_colour;
in vec3 local_position;
in vec3 interpolated_tex_coords;
in float interpolated_shading_value;
void main() {
vec4 texture_colour = texture(texture_array_sampler, interpolated_tex_coords);
fragment_colour = texture_colour * interpolated_shading_value;

if (texture_colour.a == 0.0) {
discard;
}
}
"""

def main():
pygame.init()
pygame.display.set_mode((0, 0), pygame.OPENGL | pygame.DOUBLEBUF)

pygame.mouse.set_visible(True)
pygame.event.set_grab(True)

surface = pygame.display.get_surface()
w, h = surface.get_size()
clock = pygame.time.Clock()

shader = compileProgram(compileShader(VERTEX_SHADER, GL_VERTEX_SHADER), compileShader(FRAGMENT_SHADER, GL_FRAGMENT_SHADER))

shader_sampler_location = glGetUniformLocation(shader, "texture_array_sampler")

mcamera = camera.Camera(shader, w, h)
mcworld = world.World()
holding = 7
hit_ray = hit.Hit_ray(mcworld, mcamera.rotation, mcamera.position)

glEnable(GL_DEPTH_TEST)
glEnable(GL_CULL_FACE)
glClearColor(0.6, 0.8, 1.0, 1.0)

current_block = None
next_block = None

def hit_callback(current, next):
nonlocal current_block, next_block
current_block = next
next_block = current
return True

while True:
dt = clock.tick(60) / 1000.0

current_block = None
next_block = None
hit_ray = hit.Hit_ray(mcworld, mcamera.rotation, mcamera.position)

while hit_ray.distance <  hit.HIT_RANGE:
if hit_ray.step(hit_callback):
break

for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
return

if event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 3 and next_block: mcworld.set_block(next_block, holding)
if event.button == 1 and current_block: mcworld.set_block(current_block, 0)
if event.button == 2 and current_block: holding = mcworld.get_block_number(current_block)

if event.type == pygame.MOUSEMOTION:
dx, dy = event.rel
sensitivity = 5.2 / 2000
mcamera.rotation[0] -= dx * sensitivity
mcamera.rotation[1] += dy * sensitivity
mcamera.rotation[1] = max(-math.tau / 4, min(math.tau / 4, mcamera.rotation[1]))

mcamera.input = [0, 0, 0]
keys = pygame.key.get_pressed()

if keys[pygame.K_UP]:    mcamera.input[2] += 1
if keys[pygame.K_DOWN]:  mcamera.input[2] -= 1
if keys[pygame.K_LEFT]:  mcamera.input[0] -= 1
if keys[pygame.K_RIGHT]: mcamera.input[0] += 1
if keys[pygame.K_LSHIFT]: mcamera.input[1] += 1
if keys[pygame.K_RSHIFT]: mcamera.input[1] -= 1

mcamera.update_camera(dt)

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glUseProgram(shader)

mcamera.update_matrices()

glActiveTexture(GL_TEXTURE0)
glBindTexture(GL_TEXTURE_2D_ARRAY, mcworld.texture_manager.texture_array)
glUniform1i(shader_sampler_location, 0)
mcworld.draw()

pygame.display.flip()

if __name__ == "__main__":
main()
А это мой hit.py:

Код: Выделить всё

import math

HIT_RANGE = 8

class Hit_ray:
def __init__(self, world, rotation, starting_position):
self.world = world

self.vector = (
math.cos(rotation[0]) * math.cos(rotation[1]),
math.sin(rotation[1]),
math.sin(rotation[0]) * math.cos(rotation[1]))

self.position = list(starting_position)
self.block = tuple(map(lambda x: int(round(x)), self.position))

self.distance = 0

def check(self, hit_callback, distance, current_block, next_block):
if self.world.get_block_number(next_block):
hit_callback(current_block, next_block)
return True

self.position = list(map(lambda x: self.position[x] + self.vector[x] * distance, range(3)))

self.block = next_block
self.distance += distance

def step(self, hit_callback):
bx, by, bz = self.block
local_position = list(map(lambda x: self.position[x] - self.block[x], range(3)))

sign = [1, 1, 1]
absolute_vector = list(self.vector)

for component in range(3):
if self.vector[component] <  0:
sign[component] = -1

absolute_vector[component] = -absolute_vector[component]
local_position[component] = -local_position[component]

lx, ly, lz = local_position
vx, vy, vz = absolute_vector

if vx:
x = 0.5
y = (0.5 - lx) / vx * vy + ly
z = (0.5 - lx) / vx * vz + lz

if y >= -0.5 and y = -0.5 and z = -0.5 and x = -0.5 and z = -0.5 and x = -0.5 and y

Вернуться в «Python»