thermodynamic v1
This commit is contained in:
parent
5168061d1b
commit
41761b7b56
16 changed files with 1025 additions and 212 deletions
|
@ -6,7 +6,6 @@ import numpy as np
|
|||
|
||||
|
||||
class Cube(Object):
|
||||
|
||||
def __init__(self):
|
||||
super(Cube, self).__init__()
|
||||
if (Cube.GeometryShaderId == -1):
|
||||
|
|
15
Objects/Identifiable.py
Normal file
15
Objects/Identifiable.py
Normal file
|
@ -0,0 +1,15 @@
|
|||
from multiprocessing import Semaphore
|
||||
|
||||
creatingID = Semaphore()
|
||||
|
||||
class Identifiable:
|
||||
lastID: int = 0
|
||||
|
||||
def __init__(self):
|
||||
creatingID.acquire()
|
||||
self.lastID += 1
|
||||
self.id = self.lastID
|
||||
creatingID.release()
|
||||
|
||||
def __eq__(self, other):
|
||||
return self.id == other.id and type(self) == type(other)
|
18
Objects/Renderable.py
Normal file
18
Objects/Renderable.py
Normal file
|
@ -0,0 +1,18 @@
|
|||
from OpenGL.GLU import gluErrorString
|
||||
from OpenGL.GL import glGetError, GL_NO_ERROR
|
||||
|
||||
class Renderable:
|
||||
def render(self, projMatrix, geometryRotMatrix, alternateprograms=None):
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def check_error(message):
|
||||
gl_error = glGetError()
|
||||
if (gl_error != GL_NO_ERROR):
|
||||
print("Error: " + message)
|
||||
if (gluErrorString(gl_error)):
|
||||
print(gluErrorString(gl_error))
|
||||
else:
|
||||
print(hex(gl_error))
|
||||
return True
|
||||
return False
|
|
@ -11,31 +11,13 @@ import numpy as np
|
|||
from OpenGL.extensions import alternate
|
||||
|
||||
from Objects.Objects import Object
|
||||
from MatrixStuff.Transformations import translate
|
||||
|
||||
|
||||
def check_error(message):
|
||||
gl_error = glGetError()
|
||||
if (gl_error != GL_NO_ERROR):
|
||||
print("Error: " + message)
|
||||
if (gluErrorString(gl_error)):
|
||||
print(gluErrorString(gl_error))
|
||||
else:
|
||||
print(hex(gl_error))
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
class Renderable:
|
||||
def render(self, projMatrix, geometryRotMatrix, alternateprograms=None):
|
||||
pass
|
||||
from Objects.Renderable import Renderable
|
||||
|
||||
|
||||
class Structure(Renderable):
|
||||
def __init__(self):
|
||||
self.Objects = {}
|
||||
self.vais = {}
|
||||
self.Matrix = np.identity(4, np.float32)
|
||||
self.dirty = False
|
||||
|
||||
def addShape(self, program, shape):
|
||||
|
@ -65,6 +47,7 @@ class Structure(Renderable):
|
|||
tpbi = GLuint(0)
|
||||
tcbi = GLuint(0)
|
||||
tsbi = GLuint(0)
|
||||
num = len(objects)
|
||||
|
||||
glGenVertexArrays(1, tvai)
|
||||
glBindVertexArray(tvai)
|
||||
|
@ -81,7 +64,7 @@ class Structure(Renderable):
|
|||
positions.append(o.pos[2])
|
||||
glBufferData(GL_ARRAY_BUFFER, np.array(positions, dtype=np.float32), GL_STATIC_DRAW)
|
||||
glVertexAttribPointer(vid, 3, GL_FLOAT, GL_FALSE, 0, None)
|
||||
check_error("Could not create position buffer")
|
||||
self.check_error("Could not create position buffer")
|
||||
|
||||
colors = []
|
||||
for o in objects:
|
||||
|
@ -95,7 +78,7 @@ class Structure(Renderable):
|
|||
if vc != -1:
|
||||
glEnableVertexAttribArray(vc)
|
||||
glVertexAttribPointer(vc, 3, GL_FLOAT, GL_FALSE, 0, None)
|
||||
check_error("Could not create color buffer")
|
||||
self.check_error("Could not create color buffer")
|
||||
|
||||
if hasattr(objects[0], 'size'):
|
||||
sizes = []
|
||||
|
@ -110,36 +93,38 @@ class Structure(Renderable):
|
|||
if vs != -1:
|
||||
glEnableVertexAttribArray(vs)
|
||||
glVertexAttribPointer(vs, 3, GL_FLOAT, GL_FALSE, 0, None)
|
||||
check_error("Could not create size buffer")
|
||||
self.check_error("Could not create size buffer")
|
||||
|
||||
glBindVertexArray(0)
|
||||
self.vais[key] = (tvai, tpbi, tcbi, tsbi)
|
||||
self.vais[key] = (tvai, tpbi, tcbi, tsbi, num)
|
||||
self.dirty = False
|
||||
|
||||
def clearVertexArrays(self):
|
||||
for key, (a, p, c, s) in self.vais.items():
|
||||
if p != -1:
|
||||
glDisableVertexAttribArray(p)
|
||||
glDeleteBuffers(1, [p])
|
||||
if c != -1:
|
||||
glDisableVertexAttribArray(c)
|
||||
glDeleteBuffers(1, [c])
|
||||
if s != -1 and s != GLuint(-1):
|
||||
glDisableVertexAttribArray(s)
|
||||
glDeleteBuffers(1, [s])
|
||||
glDeleteVertexArrays(1, a)
|
||||
check_error("Could not destroy vertex array")
|
||||
temp = dict(self.vais)
|
||||
self.vais = {}
|
||||
for key, vertex_array_ids in temp.items():
|
||||
if vertex_array_ids[1] != -1 and vertex_array_ids[1] != GLuint(-1):
|
||||
glDeleteBuffers(1, [vertex_array_ids[1]])
|
||||
self.check_error("Could not destroy buffer")
|
||||
if vertex_array_ids[2] != -1 and vertex_array_ids[2] != GLuint(-1):
|
||||
glDeleteBuffers(1, [vertex_array_ids[2]])
|
||||
self.check_error("Could not destroy buffer")
|
||||
if vertex_array_ids[3] != -1 and vertex_array_ids[3] != GLuint(-1):
|
||||
glDeleteBuffers(1, [vertex_array_ids[3]])
|
||||
self.check_error("Could not destroy buffer")
|
||||
glDeleteVertexArrays(1, vertex_array_ids[0])
|
||||
self.check_error("Could not destroy vertex array")
|
||||
|
||||
def render(self, projMatrix, geometryRotMatrix, alternateprograms=None):
|
||||
|
||||
for key, tupel in self.vais.items():
|
||||
self.buildvertexArrays()
|
||||
for key, vertex_array_ids in self.vais.items():
|
||||
if alternateprograms == None:
|
||||
program_id = key
|
||||
else:
|
||||
assert key in alternateprograms
|
||||
program_id = alternateprograms[key]
|
||||
glUseProgram(program_id)
|
||||
check_error("Renderingprogram is not initialized!")
|
||||
self.check_error("Renderingprogram is not initialized!")
|
||||
|
||||
projection = glGetUniformLocation(program_id, 'projModelViewMatrix')
|
||||
rot = glGetUniformLocation(program_id, 'rotMatrix')
|
||||
|
@ -147,9 +132,9 @@ class Structure(Renderable):
|
|||
glUniformMatrix4fv(projection, 1, GL_FALSE, np.array(projMatrix))
|
||||
glUniformMatrix3fv(rot, 1, GL_FALSE, np.array(geometryRotMatrix))
|
||||
|
||||
glBindVertexArray(tupel[0])
|
||||
glDrawArrays(GL_POINTS, 0, len(self.Objects[key]))
|
||||
check_error("Rendering problem")
|
||||
glBindVertexArray(vertex_array_ids[0])
|
||||
glDrawArrays(GL_POINTS, 0, vertex_array_ids[4])
|
||||
self.check_error("Rendering problem")
|
||||
|
||||
glBindVertexArray(0)
|
||||
glUseProgram(0)
|
||||
|
@ -171,83 +156,10 @@ class CompoundStructure(Renderable):
|
|||
|
||||
def render(self, projMatrix, geometryRotMatrix, alternateprograms=None):
|
||||
for (structure, M, R) in self.Structures:
|
||||
structure.buildvertexArrays()
|
||||
structure.render(M * projMatrix, R * geometryRotMatrix, alternateprograms)
|
||||
|
||||
def __eq__(self, other):
|
||||
if type(other) is type(self):
|
||||
return self.Structures == other.Structures
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
class WorldChunk(Renderable):
|
||||
def __init__(self, width, length, height):
|
||||
assert width > 0, 'Width must be greater than 0'
|
||||
assert length > 0, 'length must be greater than 0'
|
||||
assert height > 0, 'height must be greater than 0'
|
||||
self.visible = []
|
||||
self.content = []
|
||||
self.entities = []
|
||||
|
||||
self.width = width
|
||||
self.length = length
|
||||
self.height = height
|
||||
|
||||
for x in range(width):
|
||||
self.content.append([])
|
||||
self.visible.append([])
|
||||
for y in range(length):
|
||||
self.content[x].append([])
|
||||
self.visible[x].append([])
|
||||
for z in range(height):
|
||||
self.content[x][y].append(None)
|
||||
self.visible[x][y].append(4)
|
||||
|
||||
def put_object(self, x: int, y: int, z: int, new_object: Object):
|
||||
assert 0 <= x < self.width, 'Put out of bounds for x coordinate! Must be between 0 and %i' % self.width
|
||||
assert 0 <= y < self.length, 'Put out of bounds for y coordinate! Must be between 0 and %i' % self.length
|
||||
assert 0 <= z < self.height, 'Put out of bounds for z coordinate! Must be between 0 and %i' % self.height
|
||||
self.content[x][y][z] = new_object
|
||||
|
||||
change = -1 if new_object is not None else 1
|
||||
visible_carry_over = []
|
||||
if x + 1 >= self.width:
|
||||
visible_carry_over.append((1, 0, 0, change))
|
||||
else:
|
||||
self.visible[x + 1][y][z] += change
|
||||
if x - 1 < 0:
|
||||
visible_carry_over.append((-1, 0, 0, change))
|
||||
else:
|
||||
self.visible[x - 1][y][z] += change
|
||||
|
||||
if y + 1 >= self.length:
|
||||
visible_carry_over.append((0, 1, 0, change))
|
||||
else:
|
||||
self.visible[x][y + 1][z] += change
|
||||
if y - 1 < 0:
|
||||
visible_carry_over.append((0, -1, 0, change))
|
||||
else:
|
||||
self.visible[x][y - 1][z] += change
|
||||
|
||||
if z + 1 >= self.height:
|
||||
visible_carry_over.append((0, 0, 1, change))
|
||||
else:
|
||||
self.visible[x][y][z + 1] += change
|
||||
if z - 1 < 0:
|
||||
visible_carry_over.append((0, 0, -1, change))
|
||||
else:
|
||||
self.visible[x][y][z - 1] += change
|
||||
|
||||
return visible_carry_over
|
||||
|
||||
def render(self, projMatrix, geometryRotMatrix, alternateprograms=None):
|
||||
for x in range(self.width):
|
||||
for y in range(self.length):
|
||||
for z in range(self.height):
|
||||
if self.visible[x][y][z] > 0 and self.content[x][y][z] is not None:
|
||||
self.content[x][y][z].render(translate(x, y, z) * projMatrix,
|
||||
geometryRotMatrix, alternateprograms)
|
||||
|
||||
for entity in self.entities:
|
||||
entity.render(projMatrix, geometryRotMatrix, alternateprograms)
|
||||
return False
|
363
Objects/World.py
Normal file
363
Objects/World.py
Normal file
|
@ -0,0 +1,363 @@
|
|||
from Lights.Lights import Light
|
||||
from Objects.Objects import Object
|
||||
from Objects.Renderable import Renderable
|
||||
from Objects.Structure import Structure
|
||||
from MatrixStuff.Transformations import translate
|
||||
from OpenGL.GLU import *
|
||||
from OpenGL.GL import *
|
||||
import math
|
||||
import numpy as np
|
||||
|
||||
class WorldChunk(Structure):
|
||||
def __init__(self, width: int, length: int, height: int, programs: dict):
|
||||
assert width > 0, 'Width must be greater than 0'
|
||||
assert length > 0, 'length must be greater than 0'
|
||||
assert height > 0, 'height must be greater than 0'
|
||||
super(WorldChunk, self).__init__()
|
||||
self.visible = []
|
||||
self.content = []
|
||||
self.entities = []
|
||||
self.lights = []
|
||||
|
||||
self.width = width
|
||||
self.length = length
|
||||
self.height = height
|
||||
self.programs = programs
|
||||
|
||||
for x in range(width):
|
||||
self.content.append([])
|
||||
self.visible.append([])
|
||||
for y in range(length):
|
||||
self.content[x].append([])
|
||||
self.visible[x].append([])
|
||||
for z in range(height):
|
||||
self.content[x][y].append(None)
|
||||
self.visible[x][y].append(4)
|
||||
|
||||
def put_object(self, x: int, y: int, z: int, new_object: Object):
|
||||
assert 0 <= x < self.width, 'Put out of bounds for x coordinate! Must be between 0 and %i' % self.width
|
||||
assert 0 <= y < self.length, 'Put out of bounds for y coordinate! Must be between 0 and %i' % self.length
|
||||
assert 0 <= z < self.height, 'Put out of bounds for z coordinate! Must be between 0 and %i' % self.height
|
||||
no_visibility_changes = (self.content[x][y][z] is None) == (new_object is None)
|
||||
|
||||
self.content[x][y][z] = new_object
|
||||
new_object.translate(translate(x, y, z))
|
||||
|
||||
change = -1 if new_object is not None else 1
|
||||
visible_carry_over = []
|
||||
if not no_visibility_changes:
|
||||
if x + 1 >= self.width:
|
||||
visible_carry_over.append((1, 0, 0, change))
|
||||
else:
|
||||
self.visible[x + 1][y][z] += change
|
||||
if x - 1 < 0:
|
||||
visible_carry_over.append((-1, 0, 0, change))
|
||||
else:
|
||||
self.visible[x - 1][y][z] += change
|
||||
|
||||
if y + 1 >= self.length:
|
||||
visible_carry_over.append((0, 1, 0, change))
|
||||
else:
|
||||
self.visible[x][y + 1][z] += change
|
||||
if y - 1 < 0:
|
||||
visible_carry_over.append((0, -1, 0, change))
|
||||
else:
|
||||
self.visible[x][y - 1][z] += change
|
||||
|
||||
if z + 1 >= self.height:
|
||||
visible_carry_over.append((0, 0, 1, change))
|
||||
else:
|
||||
self.visible[x][y][z + 1] += change
|
||||
if z - 1 < 0:
|
||||
visible_carry_over.append((0, 0, -1, change))
|
||||
else:
|
||||
self.visible[x][y][z - 1] += change
|
||||
|
||||
return visible_carry_over
|
||||
|
||||
def get_object(self, x: int, y: int, z: int):
|
||||
assert 0 <= x < self.width, 'Put out of bounds for x coordinate! Must be between 0 and %i' % self.width
|
||||
assert 0 <= y < self.length, 'Put out of bounds for y coordinate! Must be between 0 and %i' % self.length
|
||||
assert 0 <= z < self.height, 'Put out of bounds for z coordinate! Must be between 0 and %i' % self.height
|
||||
|
||||
return self.content[x][y][z]
|
||||
|
||||
def apply_visible_carry_over(self, x: int, y: int, z: int, change: int):
|
||||
assert 0 <= x < self.width, 'Apply visible out of bounds for x coordinate! Must be between 0 and %i' % self.width
|
||||
assert 0 <= y < self.length, 'Apply visible out of bounds for y coordinate! Must be between 0 and %i' % self.length
|
||||
assert 0 <= z < self.height, 'Apply visible out of bounds for z coordinate! Must be between 0 and %i' % self.height
|
||||
|
||||
self.visible[x][y][z] += change
|
||||
|
||||
def set_visibility(self, x: int, y: int, z: int, visibility: int):
|
||||
assert 0 <= x < self.width, 'Apply visible out of bounds for x coordinate! Must be between 0 and %i' % self.width
|
||||
assert 0 <= y < self.length, 'Apply visible out of bounds for y coordinate! Must be between 0 and %i' % self.length
|
||||
assert 0 <= z < self.height, 'Apply visible out of bounds for z coordinate! Must be between 0 and %i' % self.height
|
||||
|
||||
self.visible[x][y][z] = visibility
|
||||
|
||||
def buildvertexArrays(self):
|
||||
if self.dirty:
|
||||
self.clearVertexArrays()
|
||||
glEnableClientState(GL_VERTEX_ARRAY)
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY)
|
||||
glEnableClientState(GL_NORMAL_ARRAY)
|
||||
glEnableClientState(GL_COLOR_ARRAY)
|
||||
self.vais = {}
|
||||
|
||||
objects = {}
|
||||
counts = {}
|
||||
for x in range(self.width):
|
||||
for y in range(self.length):
|
||||
for z in range(self.height):
|
||||
if self.content[x][y][z] is not None: # and self.visible[x][y][z] > 0: TODO: check visibility...
|
||||
if self.programs[type(self.content[x][y][z])] not in objects.keys():
|
||||
objects[self.programs[type(self.content[x][y][z])]] = []
|
||||
counts[self.programs[type(self.content[x][y][z])]] = 0
|
||||
objects[self.programs[type(self.content[x][y][z])]].append(self.content[x][y][z])
|
||||
counts[self.programs[type(self.content[x][y][z])]] += 1
|
||||
|
||||
for key, object_list in objects.items():
|
||||
tvai = GLuint(0)
|
||||
tpbi = GLuint(0)
|
||||
tcbi = GLuint(0)
|
||||
tsbi = GLuint(0)
|
||||
|
||||
glGenVertexArrays(1, tvai)
|
||||
glBindVertexArray(tvai)
|
||||
|
||||
vid = glGetAttribLocation(key, "in_position")
|
||||
glEnableVertexAttribArray(vid)
|
||||
|
||||
tpbi = glGenBuffers(1)
|
||||
glBindBuffer(GL_ARRAY_BUFFER, tpbi)
|
||||
positions = []
|
||||
for o in object_list:
|
||||
positions.append(o.pos[0])
|
||||
positions.append(o.pos[1])
|
||||
positions.append(o.pos[2])
|
||||
glBufferData(GL_ARRAY_BUFFER, np.array(positions, dtype=np.float32), GL_STATIC_DRAW)
|
||||
glVertexAttribPointer(vid, 3, GL_FLOAT, GL_FALSE, 0, None)
|
||||
self.check_error("Could not create position buffer")
|
||||
|
||||
colors = []
|
||||
for o in object_list:
|
||||
colors.append(o.color[0])
|
||||
colors.append(o.color[1])
|
||||
colors.append(o.color[2])
|
||||
tcbi = glGenBuffers(1)
|
||||
glBindBuffer(GL_ARRAY_BUFFER, tcbi)
|
||||
glBufferData(GL_ARRAY_BUFFER, np.array(colors, dtype=np.float32), GL_STATIC_DRAW)
|
||||
vc = glGetAttribLocation(key, "MyInColor")
|
||||
if vc != -1:
|
||||
glEnableVertexAttribArray(vc)
|
||||
glVertexAttribPointer(vc, 3, GL_FLOAT, GL_FALSE, 0, None)
|
||||
self.check_error("Could not create color buffer")
|
||||
|
||||
if hasattr(object_list[0], 'size'):
|
||||
sizes = []
|
||||
for o in object_list:
|
||||
sizes.append(o.size[0])
|
||||
sizes.append(o.size[1])
|
||||
sizes.append(o.size[2])
|
||||
tsbi = glGenBuffers(1)
|
||||
glBindBuffer(GL_ARRAY_BUFFER, tsbi)
|
||||
glBufferData(GL_ARRAY_BUFFER, np.array(sizes, dtype=np.float32), GL_STATIC_DRAW)
|
||||
vs = glGetAttribLocation(key, "MyInSize")
|
||||
if vs != -1:
|
||||
glEnableVertexAttribArray(vs)
|
||||
glVertexAttribPointer(vs, 3, GL_FLOAT, GL_FALSE, 0, None)
|
||||
self.check_error("Could not create size buffer")
|
||||
|
||||
glBindVertexArray(0)
|
||||
self.vais[key] = (tvai, tpbi, tcbi, tsbi, counts[key])
|
||||
self.dirty = False
|
||||
|
||||
def render(self, proj_matrix, geometry_rot_matrix, alternate_programs=None):
|
||||
super(WorldChunk, self).render(proj_matrix, geometry_rot_matrix, alternate_programs)
|
||||
|
||||
for entity in self.entities:
|
||||
entity.render(proj_matrix, geometry_rot_matrix, alternate_programs)
|
||||
|
||||
def set_color(self, x: int, y: int, z: int, r: float, g: float, b: float):
|
||||
assert 0 <= x < self.width, 'Put out of bounds for x coordinate! Must be between 0 and %i' % self.width
|
||||
assert 0 <= y < self.length, 'Put out of bounds for y coordinate! Must be between 0 and %i' % self.length
|
||||
assert 0 <= z < self.height, 'Put out of bounds for z coordinate! Must be between 0 and %i' % self.height
|
||||
|
||||
if self.content[x][y][z] is not None:
|
||||
self.content[x][y][z].setColor(r, g, b)
|
||||
self.dirty = True
|
||||
|
||||
class World(Renderable):
|
||||
def __init__(self, chunk_size_x: int, chunk_size_y: int, chunk_size_z: int,
|
||||
chunk_n_x: int, chunk_n_y: int, chunk_n_z: int, programs: dict):
|
||||
super(World, self).__init__()
|
||||
self.chunk_size_x = chunk_size_x
|
||||
self.chunk_size_y = chunk_size_y
|
||||
self.chunk_size_z = chunk_size_z
|
||||
self.chunk_n_x = chunk_n_x
|
||||
self.chunk_n_y = chunk_n_y
|
||||
self.chunk_n_z = chunk_n_z
|
||||
self.programs = programs
|
||||
|
||||
self.chunks: [[[WorldChunk]]] = []
|
||||
for x in range(chunk_n_x):
|
||||
self.chunks.append([])
|
||||
for y in range(chunk_n_y):
|
||||
self.chunks[x].append([])
|
||||
for z in range(chunk_n_z):
|
||||
self.chunks[x][y].append(None)
|
||||
|
||||
def set_color(self, x: int, y: int, z: int, r: float, g: float, b: float):
|
||||
x = x % (self.chunk_size_x * self.chunk_n_x)
|
||||
y = y % (self.chunk_size_y * self.chunk_n_y)
|
||||
z = z % (self.chunk_size_z * self.chunk_n_z)
|
||||
|
||||
chunk_x = int(x / self.chunk_size_x)
|
||||
chunk_y = int(y / self.chunk_size_y)
|
||||
chunk_z = int(z / self.chunk_size_z)
|
||||
if self.chunks[chunk_x][chunk_y][chunk_z] is not None:
|
||||
self.chunks[chunk_x][chunk_y][chunk_z].set_color(x % self.chunk_size_x,
|
||||
y % self.chunk_size_y,
|
||||
z % self.chunk_size_z,
|
||||
r, g, b)
|
||||
|
||||
def put_object(self, x: int, y: int, z: int, new_object: Object):
|
||||
x = x % (self.chunk_size_x * self.chunk_n_x)
|
||||
y = y % (self.chunk_size_y * self.chunk_n_y)
|
||||
z = z % (self.chunk_size_z * self.chunk_n_z)
|
||||
|
||||
chunk_x = int(x / self.chunk_size_x)
|
||||
chunk_y = int(y / self.chunk_size_y)
|
||||
chunk_z = int(z / self.chunk_size_z)
|
||||
|
||||
if self.chunks[chunk_x][chunk_y][chunk_z] is None:
|
||||
self.chunks[chunk_x][chunk_y][chunk_z] = WorldChunk(self.chunk_size_x, self.chunk_size_y, self.chunk_size_z, self.programs)
|
||||
|
||||
carry_overs = self.chunks[chunk_x][chunk_y][chunk_z].put_object(x % self.chunk_size_x,
|
||||
y % self.chunk_size_y,
|
||||
z % self.chunk_size_z,
|
||||
new_object)
|
||||
for carry_over in carry_overs:
|
||||
if self.chunks[(chunk_x + carry_over[0]) % self.chunk_n_x][(chunk_y + carry_over[1]) % self.chunk_n_y][(chunk_z + carry_over[2]) % self.chunk_n_z] is not None:
|
||||
self.chunks[
|
||||
(chunk_x + carry_over[0]) % self.chunk_n_x][
|
||||
(chunk_y + carry_over[1]) % self.chunk_n_y][
|
||||
(chunk_z + carry_over[2]) % self.chunk_n_z].apply_visible_carry_over(
|
||||
(x + carry_over[0]) % self.chunk_size_x,
|
||||
(y + carry_over[1]) % self.chunk_size_y,
|
||||
(z + carry_over[2]) % self.chunk_size_z,
|
||||
carry_over[3])
|
||||
self.chunks[
|
||||
(chunk_x + carry_over[0]) % self.chunk_n_x][
|
||||
(chunk_y + carry_over[1]) % self.chunk_n_y][
|
||||
(chunk_z + carry_over[2]) % self.chunk_n_z].dirty = True
|
||||
|
||||
visibility = 6
|
||||
neighbour = self.get_object(x - 1, y, z)
|
||||
if neighbour is not None:
|
||||
visibility -= 1
|
||||
|
||||
neighbour = self.get_object(x + 1, y, z)
|
||||
if neighbour is not None:
|
||||
visibility -= 1
|
||||
|
||||
neighbour = self.get_object(x, y - 1, z)
|
||||
if neighbour is not None:
|
||||
visibility -= 1
|
||||
|
||||
neighbour = self.get_object(x, y + 1, z)
|
||||
if neighbour is not None:
|
||||
visibility -= 1
|
||||
|
||||
neighbour = self.get_object(x, y, z - 1)
|
||||
if neighbour is not None:
|
||||
visibility -= 1
|
||||
|
||||
neighbour = self.get_object(x, y, z + 1)
|
||||
if neighbour is not None:
|
||||
visibility -= 1
|
||||
|
||||
self.chunks[chunk_x][chunk_y][chunk_z].set_visibility(x % self.chunk_size_x,
|
||||
y % self.chunk_size_y,
|
||||
z % self.chunk_size_z,
|
||||
visibility)
|
||||
self.chunks[chunk_x][chunk_y][chunk_z].dirty = True
|
||||
|
||||
def get_object(self, x: int, y: int, z: int):
|
||||
x = x % (self.chunk_size_x * self.chunk_n_x)
|
||||
y = y % (self.chunk_size_y * self.chunk_n_y)
|
||||
z = z % (self.chunk_size_z * self.chunk_n_z)
|
||||
|
||||
chunk_x = int(x / self.chunk_size_x)
|
||||
chunk_y = int(y / self.chunk_size_y)
|
||||
chunk_z = int(z / self.chunk_size_z)
|
||||
|
||||
if self.chunks[chunk_x][chunk_y][chunk_z] is None:
|
||||
return None
|
||||
|
||||
return self.chunks[chunk_x][chunk_y][chunk_z].get_object(x % self.chunk_size_x,
|
||||
y % self.chunk_size_y,
|
||||
z % self.chunk_size_z)
|
||||
|
||||
def render(self, proj_matrix, geometry_rot_matrix, alternate_programs=None):
|
||||
for x in range(self.chunk_n_x):
|
||||
for y in range(self.chunk_n_y):
|
||||
for z in range(self.chunk_n_z):
|
||||
if self.chunks[x][y][z] is not None:
|
||||
self.chunks[x][y][z].render(translate(x * self.chunk_size_x,
|
||||
y * self.chunk_size_y,
|
||||
z * self.chunk_size_z) * proj_matrix,
|
||||
geometry_rot_matrix, alternate_programs)
|
||||
|
||||
def add_light(self, x: float, y: float, z: float, l: Light):
|
||||
x = x % (self.chunk_size_x * self.chunk_n_x)
|
||||
y = y % (self.chunk_size_y * self.chunk_n_y)
|
||||
z = z % (self.chunk_size_z * self.chunk_n_z)
|
||||
|
||||
chunk_x = int(x / self.chunk_size_x)
|
||||
chunk_y = int(y / self.chunk_size_y)
|
||||
chunk_z = int(z / self.chunk_size_z)
|
||||
|
||||
if self.chunks[chunk_x][chunk_y][chunk_z] is None:
|
||||
self.chunks[chunk_x][chunk_y][chunk_z] = WorldChunk(self.chunk_size_x, self.chunk_size_y, self.chunk_size_z, self.programs)
|
||||
|
||||
self.chunks[chunk_x][chunk_y][chunk_z].lights.append(l)
|
||||
l.pos = [x, y, z]
|
||||
|
||||
def remove_light(self, l: Light):
|
||||
chunk_x = int(l.pos[0] / self.chunk_size_x)
|
||||
chunk_y = int(l.pos[1] / self.chunk_size_y)
|
||||
chunk_z = int(l.pos[2] / self.chunk_size_z)
|
||||
|
||||
if self.chunks[chunk_x][chunk_y][chunk_z] is None:
|
||||
return False
|
||||
|
||||
if l in self.chunks[chunk_x][chunk_y][chunk_z].lights:
|
||||
self.chunks[chunk_x][chunk_y][chunk_z].lights.remove(l)
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def move_light(self, l: Light, target_x: float, target_y: float, target_z: float):
|
||||
self.remove_light(l)
|
||||
self.add_light(target_x, target_y, target_z, l)
|
||||
|
||||
def get_lights_to_render(self, pos, distance):
|
||||
distance_x = math.ceil(float(distance) / self.chunk_size_x)
|
||||
distance_y = math.ceil(float(distance) / self.chunk_size_y)
|
||||
distance_z = math.ceil(float(distance) / self.chunk_size_z)
|
||||
|
||||
pos_x = int(pos[0] / self.chunk_size_x)
|
||||
pos_y = int(pos[1] / self.chunk_size_y)
|
||||
pos_z = int(pos[2] / self.chunk_size_z)
|
||||
|
||||
lights = []
|
||||
for x in range(distance_x):
|
||||
for y in range(distance_y):
|
||||
for z in range(distance_z):
|
||||
chunk = self.chunks[(pos_x + x) % self.chunk_n_x][(pos_y + y) % self.chunk_n_y][(pos_z + z) % self.chunk_n_z]
|
||||
if chunk is not None:
|
||||
lights += chunk.lights
|
||||
|
||||
return lights
|
Loading…
Add table
Add a link
Reference in a new issue