starts plate movement and frame improvements

This commit is contained in:
zomseffen 2022-01-15 14:31:19 +01:00
parent a783afbc7e
commit 6c5cae958b
4 changed files with 182 additions and 68 deletions

View file

@ -118,28 +118,28 @@ class Client:
r, g, b = colors[int(self.world_provider.world.plates[x_pos, y_pos])] r, g, b = colors[int(self.world_provider.world.plates[x_pos, y_pos])]
self.world_provider.world.set_color(x_pos, y_pos, z_pos, r, g, b) self.world_provider.world.set_color(x_pos, y_pos, z_pos, r, g, b)
total_x = self.world_provider.world.chunk_n_x * self.world_provider.world.chunk_size_x # total_x = self.world_provider.world.chunk_n_x * self.world_provider.world.chunk_size_x
total_y = self.world_provider.world.chunk_n_y * self.world_provider.world.chunk_size_y # total_y = self.world_provider.world.chunk_n_y * self.world_provider.world.chunk_size_y
for x_pos in range(0, 100): # for x_pos in range(0, 100):
for y_pos in range(0, 100): # for y_pos in range(0, 100):
if self.world_provider.world.faults[x_pos, y_pos] == -2: # if self.world_provider.world.faults[x_pos, y_pos] == -2:
self.world_provider.world.set_color(x_pos, y_pos, 0, 0, 0, 0) # self.world_provider.world.set_color(x_pos, y_pos, 0, 0, 0, 0)
#
for line_index, line in enumerate(self.world_provider.world.fault_lines): # for line_index, line in enumerate(self.world_provider.world.fault_lines):
for x_pos in range(0, 100): # for x_pos in range(0, 100):
for y_pos in range(0, 100): # for y_pos in range(0, 100):
if self.world_provider.world.faults[x_pos, y_pos] == line_index: # if self.world_provider.world.faults[x_pos, y_pos] == line_index:
if line_index != 9: # if line_index != 9:
self.world_provider.world.set_color(x_pos, y_pos, 0, 0, 0, 1) # self.world_provider.world.set_color(x_pos, y_pos, 0, 0, 0, 1)
else: # else:
self.world_provider.world.set_color(x_pos, y_pos, 0, 1, 1, 1) # self.world_provider.world.set_color(x_pos, y_pos, 0, 1, 1, 1)
#
for x_pos in range(0, 100): # for x_pos in range(0, 100):
for y_pos in range(0, 100): # for y_pos in range(0, 100):
for z_pos in range(0, 1): # for z_pos in range(0, 1):
if [x_pos, y_pos] in self.world_provider.world.fault_nodes: # if [x_pos, y_pos] in self.world_provider.world.fault_nodes:
r, g, b = 1, 0, 0 # r, g, b = 1, 0, 0
self.world_provider.world.set_color(x_pos, y_pos, z_pos, r, g, b) # self.world_provider.world.set_color(x_pos, y_pos, z_pos, r, g, b)
# # visualize direction lengths # # visualize direction lengths
# lengths = np.sqrt(np.sum(np.square(self.world_provider.world.directions), axis=2)) # lengths = np.sqrt(np.sum(np.square(self.world_provider.world.directions), axis=2))
@ -295,7 +295,7 @@ class Client:
# int(round(self.test_pixel[1])), # int(round(self.test_pixel[1])),
# int(round(self.test_pixel[2])), 1.0, 1.0, 1.0) # int(round(self.test_pixel[2])), 1.0, 1.0, 1.0)
# print(1.0 / (time.time() - self.time)) print(1.0 / (time.time() - self.time))
self.time = time.time() self.time = time.time()
glutPostRedisplay() glutPostRedisplay()

View file

@ -1,8 +1,12 @@
from OpenGL.GLU import gluErrorString from OpenGL.GLU import *
from OpenGL.GL import glGetError, GL_NO_ERROR from OpenGL.GL import *
import numpy as np
class Renderable: class Renderable:
def render(self, projMatrix, geometryRotMatrix, alternateprograms=None): def render(self, projMatrix, geometryRotMatrix, alternateprograms=None,
preselected_program=None, projection_pos=None, rot_pos=None):
pass pass
@staticmethod @staticmethod

View file

@ -15,10 +15,41 @@ from Objects.Renderable import Renderable
class Structure(Renderable): class Structure(Renderable):
def __init__(self): def __init__(self, x_offset=0, y_offset=1, z_offset=0):
self.Objects = {} self.Objects = {}
self.vais = {} self.vais = {}
self.dirty = False self.dirty = True
self.x_offset = x_offset
self.y_offset = y_offset
self.z_offset = z_offset
@property
def x_offset(self):
return self._x_offset
@x_offset.setter
def x_offset(self, value):
self.dirty = True
self._x_offset = value
@property
def y_offset(self):
return self._y_offset
@y_offset.setter
def y_offset(self, value):
self.dirty = True
self._y_offset = value
@property
def z_offset(self):
return self._z_offset
@z_offset.setter
def z_offset(self, value):
self.dirty = True
self._z_offset = value
def addShape(self, program, shape): def addShape(self, program, shape):
if not program in self.Objects.keys(): if not program in self.Objects.keys():
@ -59,9 +90,9 @@ class Structure(Renderable):
glBindBuffer(GL_ARRAY_BUFFER, tpbi) glBindBuffer(GL_ARRAY_BUFFER, tpbi)
positions = [] positions = []
for o in objects: for o in objects:
positions.append(o.pos[0]) positions.append(o.pos[0] + self.x_offset)
positions.append(o.pos[1]) positions.append(o.pos[1] + self.y_offset)
positions.append(o.pos[2]) positions.append(o.pos[2] + self.z_offset)
glBufferData(GL_ARRAY_BUFFER, np.array(positions, dtype=np.float32), GL_STATIC_DRAW) glBufferData(GL_ARRAY_BUFFER, np.array(positions, dtype=np.float32), GL_STATIC_DRAW)
glVertexAttribPointer(vid, 3, GL_FLOAT, GL_FALSE, 0, None) glVertexAttribPointer(vid, 3, GL_FLOAT, GL_FALSE, 0, None)
self.check_error("Could not create position buffer") self.check_error("Could not create position buffer")
@ -115,28 +146,38 @@ class Structure(Renderable):
glDeleteVertexArrays(1, vertex_array_ids[0]) glDeleteVertexArrays(1, vertex_array_ids[0])
self.check_error("Could not destroy vertex array") self.check_error("Could not destroy vertex array")
def render(self, projMatrix, geometryRotMatrix, alternateprograms=None): def render(self, projMatrix, geometryRotMatrix, alternateprograms=None,
preselected_program=None, projection_pos=None, rot_pos=None):
self.buildvertexArrays() self.buildvertexArrays()
for key, vertex_array_ids in self.vais.items(): for key, vertex_array_ids in self.vais.items():
if alternateprograms == None: if alternateprograms == None:
program_id = key program_id = key
else: else:
assert key in alternateprograms assert key in alternateprograms.keys()
program_id = alternateprograms[key] program_id = alternateprograms[key]
# check if a program was preloaded
if preselected_program is not None:
# if preloaded we only want to render the matching vertex arrays
if preselected_program != program_id:
continue
else:
glUseProgram(program_id) glUseProgram(program_id)
self.check_error("Renderingprogram is not initialized!") self.check_error("Renderingprogram is not initialized!")
projection = glGetUniformLocation(program_id, 'projModelViewMatrix') if rot_pos is None:
rot = glGetUniformLocation(program_id, 'rotMatrix') rot = glGetUniformLocation(program_id, 'rotMatrix')
glUniformMatrix4fv(projection, 1, GL_FALSE, np.array(projMatrix))
glUniformMatrix3fv(rot, 1, GL_FALSE, np.array(geometryRotMatrix)) glUniformMatrix3fv(rot, 1, GL_FALSE, np.array(geometryRotMatrix))
if projection_pos is None:
projection = glGetUniformLocation(program_id, 'projModelViewMatrix')
glUniformMatrix4fv(projection, 1, GL_FALSE, np.array(projMatrix))
glBindVertexArray(vertex_array_ids[0]) glBindVertexArray(vertex_array_ids[0])
glDrawArrays(GL_POINTS, 0, vertex_array_ids[4]) glDrawArrays(GL_POINTS, 0, vertex_array_ids[4])
self.check_error("Rendering problem") self.check_error("Rendering problem")
glBindVertexArray(0) glBindVertexArray(0)
if preselected_program is None:
glUseProgram(0) glUseProgram(0)
def __eq__(self, other): def __eq__(self, other):
@ -154,9 +195,11 @@ class CompoundStructure(Renderable):
R: np.matrix = np.identity(3, np.float)): R: np.matrix = np.identity(3, np.float)):
self.Structures.append((structure, M, R)) self.Structures.append((structure, M, R))
def render(self, projMatrix, geometryRotMatrix, alternateprograms=None): def render(self, projMatrix, geometryRotMatrix, alternateprograms=None,
preselected_program=None, projection_pos=None, rot_pos=None):
for (structure, M, R) in self.Structures: for (structure, M, R) in self.Structures:
structure.render(M * projMatrix, R * geometryRotMatrix, alternateprograms) structure.render(M * projMatrix, R * geometryRotMatrix, alternateprograms,
preselected_program, projection_pos, rot_pos)
def __eq__(self, other): def __eq__(self, other):
if type(other) is type(self): if type(other) is type(self):

View file

@ -10,6 +10,18 @@ import numpy as np
import random import random
import sys import sys
# Plate Types
SEA_PLATE = 0
CONTINENTAL_PLATE = 1
# Rock types
EMPTY = 0
SEA_PLATE_STONE = 1
MAGMATIC_STONE = 2
METAMORPH_STONE = 3
SEDIMENTAL_STONE = 4
SEDIMENT = 5
class WorldChunk(Structure): class WorldChunk(Structure):
def __init__(self, width: int, length: int, height: int, programs: dict): def __init__(self, width: int, length: int, height: int, programs: dict):
assert width > 0, 'Width must be greater than 0' assert width > 0, 'Width must be greater than 0'
@ -135,9 +147,9 @@ class WorldChunk(Structure):
glBindBuffer(GL_ARRAY_BUFFER, tpbi) glBindBuffer(GL_ARRAY_BUFFER, tpbi)
positions = [] positions = []
for o in object_list: for o in object_list:
positions.append(o.pos[0]) positions.append(o.pos[0] + self.x_offset)
positions.append(o.pos[1]) positions.append(o.pos[1] + self.y_offset)
positions.append(o.pos[2]) positions.append(o.pos[2] + self.z_offset)
glBufferData(GL_ARRAY_BUFFER, np.array(positions, dtype=np.float32), GL_STATIC_DRAW) glBufferData(GL_ARRAY_BUFFER, np.array(positions, dtype=np.float32), GL_STATIC_DRAW)
glVertexAttribPointer(vid, 3, GL_FLOAT, GL_FALSE, 0, None) glVertexAttribPointer(vid, 3, GL_FLOAT, GL_FALSE, 0, None)
self.check_error("Could not create position buffer") self.check_error("Could not create position buffer")
@ -175,11 +187,14 @@ class WorldChunk(Structure):
self.vais[key] = (tvai, tpbi, tcbi, tsbi, counts[key]) self.vais[key] = (tvai, tpbi, tcbi, tsbi, counts[key])
self.dirty = False self.dirty = False
def render(self, proj_matrix, geometry_rot_matrix, alternate_programs=None): def render(self, proj_matrix, geometry_rot_matrix, alternate_programs=None,
super(WorldChunk, self).render(proj_matrix, geometry_rot_matrix, alternate_programs) preselected_program=None, projection_pos=None, rot_pos=None):
super(WorldChunk, self).render(proj_matrix, geometry_rot_matrix, alternate_programs,
preselected_program, projection_pos, rot_pos)
for entity in self.entities: for entity in self.entities:
entity.render(proj_matrix, geometry_rot_matrix, alternate_programs) entity.render(proj_matrix, geometry_rot_matrix, alternate_programs,
preselected_program, projection_pos, rot_pos)
def set_color(self, x: int, y: int, z: int, r: float, g: float, b: float): 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 <= x < self.width, 'Put out of bounds for x coordinate! Must be between 0 and %i' % self.width
@ -206,6 +221,9 @@ class World(Renderable):
self.fault_lines = [] self.fault_lines = []
self.plates = None self.plates = None
self.directions = None self.directions = None
self.num_plates = 0
self.stone = None
self.faults = None
self.chunks: [[[WorldChunk]]] = [] self.chunks: [[[WorldChunk]]] = []
for x in range(chunk_n_x): for x in range(chunk_n_x):
@ -215,7 +233,7 @@ class World(Renderable):
for z in range(chunk_n_z): for z in range(chunk_n_z):
self.chunks[x][y].append(None) self.chunks[x][y].append(None)
def generate(self, seed=None, sea_height=50, continental_height=200): def generate(self, seed: int=None, sea_plate_height: int = 50, continental_plate_height: int = 200):
if seed is None: if seed is None:
seed = random.randrange(2**32) seed = random.randrange(2**32)
seed = 229805811 seed = 229805811
@ -381,12 +399,6 @@ class World(Renderable):
item.remove(plate) item.remove(plate)
directions = np.zeros((total_x, total_y, 3)) directions = np.zeros((total_x, total_y, 3))
heights = np.zeros((total_x, total_y))
for plate in range(1, plate_num):
if random.randint(1, 2) == 1:
heights[plates == plate] = sea_height
else:
heights[plates == plate] = continental_height
coords = np.zeros((total_x, total_y, 2)) coords = np.zeros((total_x, total_y, 2))
for x in range(total_x): for x in range(total_x):
@ -431,11 +443,37 @@ class World(Renderable):
directions[plates == plate, :2] += perpendicular * (scalar / abs(scalar)) directions[plates == plate, :2] += perpendicular * (scalar / abs(scalar))
pass pass
for x in range(total_x):
for y in range(total_y):
if plates[x, y] == -1:
plate = np.max(plates[x - 1: x + 1, y - 1: y + 1])
plates[x, y] = plate
self.plates = plates self.plates = plates
self.directions = directions self.directions = directions
self.num_plates = plate_num
# max height will be three times the continental height
# sea level will be at one and a half time continental height
# with the continental plates top end ending there
# sea plates will be flush at the bottom end
max_height = 3 * continental_plate_height
sea_level = int(1.5 * continental_plate_height)
lower_level = sea_level - continental_plate_height
upper_sea_plate_level = lower_level + sea_plate_height
# stone kinds: 0: lava/air, 1: sea_plate, 2: magmatic_continental, 3: metamorph, 4: sedimental_rock, 5: sediment
self.stone = np.zeros((total_x, total_y, max_height), np.int)
plate_to_type = {}
for plate in range(1, plate_num):
if random.randint(1, 2) == 1:
self.stone[plates == plate, lower_level:upper_sea_plate_level] = SEA_PLATE_STONE
plate_to_type[plate] = SEA_PLATE
else:
self.stone[plates == plate, lower_level:sea_level] = MAGMATIC_STONE
plate_to_type[plate] = CONTINENTAL_PLATE
pass
def set_color(self, x: int, y: int, z: int, r: float, g: float, b: float): 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) x = x % (self.chunk_size_x * self.chunk_n_x)
@ -462,6 +500,9 @@ class World(Renderable):
if self.chunks[chunk_x][chunk_y][chunk_z] is None: 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] = WorldChunk(self.chunk_size_x, self.chunk_size_y, self.chunk_size_z, self.programs)
self.chunks[chunk_x][chunk_y][chunk_z].x_offset = chunk_x * self.chunk_size_x
self.chunks[chunk_x][chunk_y][chunk_z].y_offset = chunk_y * self.chunk_size_z
self.chunks[chunk_x][chunk_y][chunk_z].z_offset = chunk_z * self.chunk_size_y
carry_overs = self.chunks[chunk_x][chunk_y][chunk_z].put_object(x % self.chunk_size_x, carry_overs = self.chunks[chunk_x][chunk_y][chunk_z].put_object(x % self.chunk_size_x,
y % self.chunk_size_y, y % self.chunk_size_y,
@ -529,17 +570,38 @@ class World(Renderable):
y % self.chunk_size_y, y % self.chunk_size_y,
z % self.chunk_size_z) z % self.chunk_size_z)
def render(self, proj_matrix, geometry_rot_matrix, alternate_programs=None): def render(self, proj_matrix, geometry_rot_matrix, alternate_programs=None,
preselected_program=None, projection_pos=None, rot_pos=None):
if preselected_program is not None:
for x in range(self.chunk_n_x): for x in range(self.chunk_n_x):
for y in range(self.chunk_n_y): for y in range(self.chunk_n_y):
for z in range(self.chunk_n_z): for z in range(self.chunk_n_z):
if self.chunks[x][y][z] is not None: if self.chunks[x][y][z] is not None:
self.chunks[x][y][z].render(translate(x * self.chunk_size_x, self.chunks[x][y][z].render(proj_matrix,
y * self.chunk_size_y, geometry_rot_matrix, alternate_programs,
z * self.chunk_size_z) * proj_matrix, preselected_program, projection_pos, rot_pos)
geometry_rot_matrix, alternate_programs) else:
for _, program_id in self.programs.items():
if alternate_programs == None:
used_program_id = program_id
else:
assert program_id in alternate_programs.keys()
used_program_id = alternate_programs[program_id]
glUseProgram(used_program_id)
self.check_error("Renderingprogram is not initialized!")
projection = glGetUniformLocation(used_program_id, 'projModelViewMatrix')
rot = glGetUniformLocation(used_program_id, 'rotMatrix')
glUniformMatrix3fv(rot, 1, GL_FALSE, np.array(geometry_rot_matrix))
glUniformMatrix4fv(projection, 1, GL_FALSE, np.array(proj_matrix))
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(proj_matrix,
geometry_rot_matrix, alternate_programs,
used_program_id, projection, rot)
def add_light(self, x: float, y: float, z: float, l: Light): def add_light(self, x: float, y: float, z: float, l: Light)-> Light:
x = x % (self.chunk_size_x * self.chunk_n_x) x = x % (self.chunk_size_x * self.chunk_n_x)
y = y % (self.chunk_size_y * self.chunk_n_y) y = y % (self.chunk_size_y * self.chunk_n_y)
z = z % (self.chunk_size_z * self.chunk_n_z) z = z % (self.chunk_size_z * self.chunk_n_z)
@ -550,10 +612,15 @@ class World(Renderable):
if self.chunks[chunk_x][chunk_y][chunk_z] is None: 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] = WorldChunk(self.chunk_size_x, self.chunk_size_y, self.chunk_size_z, self.programs)
self.chunks[chunk_x][chunk_y][chunk_z].x_offset = chunk_x * self.chunk_size_x
self.chunks[chunk_x][chunk_y][chunk_z].y_offset = chunk_y * self.chunk_size_z
self.chunks[chunk_x][chunk_y][chunk_z].z_offset = chunk_z * self.chunk_size_y
self.chunks[chunk_x][chunk_y][chunk_z].lights.append(l) self.chunks[chunk_x][chunk_y][chunk_z].lights.append(l)
l.pos = [x, y, z] l.pos = [x, y, z]
return l
def remove_light(self, l: Light): def remove_light(self, l: Light):
chunk_x = int(l.pos[0] / self.chunk_size_x) chunk_x = int(l.pos[0] / self.chunk_size_x)
chunk_y = int(l.pos[1] / self.chunk_size_y) chunk_y = int(l.pos[1] / self.chunk_size_y)