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])]
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_y = self.world_provider.world.chunk_n_y * self.world_provider.world.chunk_size_y
for x_pos in range(0, 100):
for y_pos in range(0, 100):
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)
for line_index, line in enumerate(self.world_provider.world.fault_lines):
for x_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 line_index != 9:
self.world_provider.world.set_color(x_pos, y_pos, 0, 0, 0, 1)
else:
self.world_provider.world.set_color(x_pos, y_pos, 0, 1, 1, 1)
for x_pos in range(0, 100):
for y_pos in range(0, 100):
for z_pos in range(0, 1):
if [x_pos, y_pos] in self.world_provider.world.fault_nodes:
r, g, b = 1, 0, 0
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_y = self.world_provider.world.chunk_n_y * self.world_provider.world.chunk_size_y
# for x_pos in range(0, 100):
# for y_pos in range(0, 100):
# 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)
#
# for line_index, line in enumerate(self.world_provider.world.fault_lines):
# for x_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 line_index != 9:
# self.world_provider.world.set_color(x_pos, y_pos, 0, 0, 0, 1)
# else:
# self.world_provider.world.set_color(x_pos, y_pos, 0, 1, 1, 1)
#
# for x_pos in range(0, 100):
# for y_pos in range(0, 100):
# for z_pos in range(0, 1):
# if [x_pos, y_pos] in self.world_provider.world.fault_nodes:
# r, g, b = 1, 0, 0
# self.world_provider.world.set_color(x_pos, y_pos, z_pos, r, g, b)
# # visualize direction lengths
# 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[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()
glutPostRedisplay()

View file

@ -1,8 +1,12 @@
from OpenGL.GLU import gluErrorString
from OpenGL.GL import glGetError, GL_NO_ERROR
from OpenGL.GLU import *
from OpenGL.GL import *
import numpy as np
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
@staticmethod
@ -15,4 +19,4 @@ class Renderable:
else:
print(hex(gl_error))
return True
return False
return False

View file

@ -15,10 +15,41 @@ from Objects.Renderable import Renderable
class Structure(Renderable):
def __init__(self):
def __init__(self, x_offset=0, y_offset=1, z_offset=0):
self.Objects = {}
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):
if not program in self.Objects.keys():
@ -59,9 +90,9 @@ class Structure(Renderable):
glBindBuffer(GL_ARRAY_BUFFER, tpbi)
positions = []
for o in objects:
positions.append(o.pos[0])
positions.append(o.pos[1])
positions.append(o.pos[2])
positions.append(o.pos[0] + self.x_offset)
positions.append(o.pos[1] + self.y_offset)
positions.append(o.pos[2] + self.z_offset)
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")
@ -115,29 +146,39 @@ class Structure(Renderable):
glDeleteVertexArrays(1, vertex_array_ids[0])
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()
for key, vertex_array_ids in self.vais.items():
if alternateprograms == None:
program_id = key
else:
assert key in alternateprograms
assert key in alternateprograms.keys()
program_id = alternateprograms[key]
glUseProgram(program_id)
self.check_error("Renderingprogram is not initialized!")
# 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)
self.check_error("Renderingprogram is not initialized!")
projection = glGetUniformLocation(program_id, 'projModelViewMatrix')
rot = glGetUniformLocation(program_id, 'rotMatrix')
if rot_pos is None:
rot = glGetUniformLocation(program_id, 'rotMatrix')
glUniformMatrix3fv(rot, 1, GL_FALSE, np.array(geometryRotMatrix))
glUniformMatrix4fv(projection, 1, GL_FALSE, np.array(projMatrix))
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])
glDrawArrays(GL_POINTS, 0, vertex_array_ids[4])
self.check_error("Rendering problem")
glBindVertexArray(0)
glUseProgram(0)
if preselected_program is None:
glUseProgram(0)
def __eq__(self, other):
if type(other) is type(self):
@ -154,9 +195,11 @@ class CompoundStructure(Renderable):
R: np.matrix = np.identity(3, np.float)):
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:
structure.render(M * projMatrix, R * geometryRotMatrix, alternateprograms)
structure.render(M * projMatrix, R * geometryRotMatrix, alternateprograms,
preselected_program, projection_pos, rot_pos)
def __eq__(self, other):
if type(other) is type(self):

View file

@ -10,6 +10,18 @@ import numpy as np
import random
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):
def __init__(self, width: int, length: int, height: int, programs: dict):
assert width > 0, 'Width must be greater than 0'
@ -135,9 +147,9 @@ class WorldChunk(Structure):
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])
positions.append(o.pos[0] + self.x_offset)
positions.append(o.pos[1] + self.y_offset)
positions.append(o.pos[2] + self.z_offset)
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")
@ -175,11 +187,14 @@ class WorldChunk(Structure):
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)
def render(self, proj_matrix, geometry_rot_matrix, alternate_programs=None,
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:
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):
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.plates = None
self.directions = None
self.num_plates = 0
self.stone = None
self.faults = None
self.chunks: [[[WorldChunk]]] = []
for x in range(chunk_n_x):
@ -215,7 +233,7 @@ class World(Renderable):
for z in range(chunk_n_z):
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:
seed = random.randrange(2**32)
seed = 229805811
@ -381,12 +399,6 @@ class World(Renderable):
item.remove(plate)
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))
for x in range(total_x):
@ -431,11 +443,37 @@ class World(Renderable):
directions[plates == plate, :2] += perpendicular * (scalar / abs(scalar))
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.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):
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:
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,
y % self.chunk_size_y,
@ -529,17 +570,38 @@ class World(Renderable):
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 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 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,
preselected_program, projection_pos, rot_pos)
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)
y = y % (self.chunk_size_y * self.chunk_n_y)
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:
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)
l.pos = [x, y, z]
return l
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)