diff --git a/README.md b/README.md index 6cbbe17..1ab48d0 100644 --- a/README.md +++ b/README.md @@ -7,11 +7,31 @@

An open source implementation of 3D Computer Universe

-I started programming a computer universe based on voxels in February 2024 and I am trying to make it more complete. -This project has a custom built-in 3D rendering engine written using OpenGL -Any programmer can use the codes in this project to build his own world or help improve ICU. +[![Hits](https://hits.seeyoufarm.com/api/count/incr/badge.svg?url=https%3A%2F%2Fgithub.com%2FMatinAfzal%2F3DICU&count_bg=%2379C83D&title_bg=%23555555&icon=docusign.svg&icon_color=%23E7E7E7&title=Views&edge_flat=false)](https://hits.seeyoufarm.com) + +I started programming a computer universe based on voxels in February 2024 and I am trying to make it more complete. +This project has an internal 3D rendering engine that was built by me using OpenGL called FA-Engine. + +You can find more information about FA-Engine here: [FAE Repository](https://github.com/MatinAfzal/FloatArtsEngine) + +Any programmer can use the codes in this project to build his own world or help improve OpenUniverse. Developer: [@MatinAfzal](https://github.com/MatinAfzal) +Click [here](https://www.youtube.com/watch?v=u1sz5jymhfI) to watch the YouTube video of the project! + +![2](https://github.com/user-attachments/assets/80d340bf-94b9-4515-8e91-b43c219624f1) + + +## Usage + +Open cmd: +``` +C:\Windows\system32> cd .//main +``` +``` +C:\TheJumonRunner> python OpenUniverse.py +``` ![3DICU_Screenshot1](https://github.com/MatinAfzal/3DICU/assets/128434167/9a1a3d19-8475-4d27-9280-13d635cc2bdd) + diff --git a/main/Engine2/Axes.py b/main/Engine2/Axes.py index 925269a..fc65297 100644 --- a/main/Engine2/Axes.py +++ b/main/Engine2/Axes.py @@ -8,7 +8,8 @@ class Axes(Mesh): World mesh axes x, y, z """ def __init__(self, location, material) -> None: - print("Loading Axes...") + if ESP: + print("Loading Axes...") vertices = WORLD_AXES_VERTICES colors = WORLD_AXES_COLORS draw_type = WORLD_AXES_DRAWTYPE diff --git a/main/Engine2/Camera.py b/main/Engine2/Camera.py index 34a2d60..7638d63 100644 --- a/main/Engine2/Camera.py +++ b/main/Engine2/Camera.py @@ -11,7 +11,8 @@ class Camera: World Camera """ def __init__(self, width, height) -> None: - print("Loading Camera...") + if ESP: + print("Loading Camera...") self.transformation = identity_mat() self.last_mouse = pygame.math.Vector2(0, 0) self.mouse_sensitivity_x = CAMERA_MOUSE_SENSITIVITY_X diff --git a/main/Engine2/CellAttach.py b/main/Engine2/CellAttach.py index 41dda37..a302f7b 100644 --- a/main/Engine2/CellAttach.py +++ b/main/Engine2/CellAttach.py @@ -1,5 +1,6 @@ -from main.Engine2.Mesh import * -from main.Engine2.Settings2 import * +import threading +from .Mesh import * +from .Settings2 import * class CellAttach: @@ -10,7 +11,10 @@ class CellAttach: """ def __init__(self, cells: list[object], draw_type=GL_TRIANGLES, shader=None, image=None) -> None: - print("Attaching Cells...") + if ESP: + print("Attaching Cells...") + + self.level_name = cells[0].level_name self.image = image self.cells = cells @@ -23,12 +27,25 @@ def __init__(self, cells: list[object], draw_type=GL_TRIANGLES, shader=None, ima self.colors = [] self.call_time = 0 - self.attach_vertices(self.cells) - self.attach_uvs(self.cells) - self.attach_normals(self.cells) + t1 = threading.Thread(target=self.attach_vertices) + t2 = threading.Thread(target=self.attach_uvs) + t3 = threading.Thread(target=self.attach_normals) + + t1.start() + t2.start() + t3.start() + + t1.join() + t2.join() + t3.join() + + # self.attach_vertices(self.cells) + # self.attach_uvs(self.cells) + # self.attach_normals(self.cells) self.load_world() - def attach_vertices(self, cells): + def attach_vertices(self): + cells = self.cells if len(cells) < 2: print("\n\nERROR: NO ENOUGH CELLS TO ATTACH!\n\n") return 0 @@ -38,7 +55,8 @@ def attach_vertices(self, cells): for instance in cells[2:]: self.world_formatted_vertices = np.concatenate((self.world_formatted_vertices, instance.vertices)) - def attach_uvs(self, cells): + def attach_uvs(self): + cells = self.cells if len(cells) < 2: print("ERROR: NO ENOUGH CELLS TO ATTACH!") return 0 @@ -48,7 +66,8 @@ def attach_uvs(self, cells): for instance in cells[2:]: self.world_formatted_uvs = np.concatenate((self.world_formatted_uvs, instance.vertex_uvs)) - def attach_normals(self, cells): + def attach_normals(self): + cells = self.cells if len(cells) < 2: print("ERROR: NO ENOUGH CELLS TO ATTACH!") return 0 @@ -64,12 +83,23 @@ def load_world(self): self.colors.append(CHUNK_COLOR_G) self.colors.append(CHUNK_COLOR_B) - self.world = Mesh( - vertices=self.world_formatted_vertices, - imagefile=self.image, - material=self.world_shader, - draw_type=self.world_draw_type, - vertex_colors=self.colors, - vertex_uvs=self.world_formatted_uvs, - vertex_normals=self.world_formatted_normals - ) + if self.level_name == "tree1": + self.world = Mesh( + vertices=self.world_formatted_vertices, + imagefile=self.image, + material=self.world_shader, + draw_type=self.world_draw_type, + vertex_colors=self.colors, + vertex_uvs=self.world_formatted_uvs, + vertex_normals=self.world_formatted_normals + ) + else: + self.world = Mesh( + vertices=self.world_formatted_vertices, + imagefile=self.image, + material=self.world_shader, + draw_type=self.world_draw_type, + vertex_colors=self.colors, + vertex_uvs=self.world_formatted_uvs, + vertex_normals=self.world_formatted_normals + ) diff --git a/main/Engine2/Cullings/ChunkRenderDistance.py b/main/Engine2/Cullings/ChunkRenderDistance.py deleted file mode 100644 index 6c9c4a9..0000000 --- a/main/Engine2/Cullings/ChunkRenderDistance.py +++ /dev/null @@ -1,109 +0,0 @@ -import numpy as np - -class ChunkRenderDistance: - def __init__(self, renderdistance=1) -> None: - self.render_distance = renderdistance # Chunks - self.maximum_distance = 500 - self.block_distance = self.render_distance * 8 # Blocks - - self.load_map = None - self.init_map() - - # self.player_location = [int(round(self.maximum_distance / 2)), int(round(self.maximum_distance / 2))] - self.player_location = [0, 0] - self.player_identifier = 5 # Player identifier - - def first_load(self): - self.load_map[self.player_location[0]][self.player_location[1]] = self.player_identifier # initilaise player on chunk map - - # Render Cross One - self.load_map[self.player_location[0]:self.player_location[0]+self.block_distance, self.player_location[1]:self.player_location[1]+self.block_distance] = 1 # BR - self.load_map[self.player_location[0]-self.block_distance:self.player_location[0], self.player_location[1]-self.block_distance:self.player_location[1]] = 1 # TL - - - # Render Cross Two - self.load_map[self.player_location[0]:self.player_location[0]+self.block_distance, self.player_location[1]-self.block_distance:self.player_location[1]] = 1 # BL - self.load_map[self.player_location[0]-self.block_distance:self.player_location[0], self.player_location[1]:self.player_location[1]+self.block_distance] = 1 # TR - - def init_map(self): - self.load_map = np.zeros(shape=(self.maximum_distance, self.maximum_distance), dtype=np.uint8) - - def update_load_map(self, direction): - """ updating new load map based on player direction. - - Args: - direction (tuple): player new direction - - Sample: - (X, Y, Z, W): X Croos One, Y Cross One, Z Cross Two, W Cross Two - (1, 0, 0, 0): Positive move on X Croos One - (0, 0, -1, 0): Negative move on Z Cross Two - """ - - triger = 0 # Stay - try: - triger = 1 - positive = direction.index(1) - except: - triger = 2 - negative = direction.index(-1) - - # Positive move - if triger == 1: - self.init_map() - - # Cross One X & Y - if positive == 0: # X Croos One (Right Column Move) - self.player_location[1] += 1 - self.first_load() - - elif positive == 1: # Y Croos One (Up Row Move) - self.player_location[0] -= 1 - self.first_load() - - # Cross Two Z & W - elif positive == 2: # Z Cross Two (Right up column and row move) - self.player_location[0] -= 1 - self.player_location[1] += 1 - self.first_load() - - elif positive == 3: # W Cross Two (Left up column and row move) - self.player_location[0] -= 1 - self.player_location[1] -= 1 - self.first_load() - - # Negative Move - elif triger == 2: - self.init_map() - # Cross One X & Y - if negative == 0: # -X Cross One (Left Column Move) - self.player_location[1] -= 1 - self.first_load() - - elif negative == 1: # -Y Cross One (Down Row Move) - self.player_location[0] += 1 - self.first_load() - - # Cross Two Z & W - elif negative == 2: # -Z Cross Two (Down left row and column move) - self.player_location[0] += 1 - self.player_location[1] -= 1 - self.first_load() - - elif negative == 3: # -W Cross Two (Down right row and column move) - self.player_location[0] += 1 - self.player_location[1] += 1 - self.first_load() - - else: - pass - -# if __name__ == "__main__": -# map = ChunkRenderDistance() -# map.first_load() -# print(map.load_map) -# print("\n\n\n\n") -# map.update_load_map(direction=(0, 0, 0, -1)) - -# print(map.load_map) - \ No newline at end of file diff --git a/main/Engine2/Cullings/DistanceCulling.py b/main/Engine2/Cullings/DistanceCulling.py new file mode 100644 index 0000000..eb133e8 --- /dev/null +++ b/main/Engine2/Cullings/DistanceCulling.py @@ -0,0 +1,144 @@ +import numpy as np +import pygame +from math import sqrt +from Engine2.Settings2 import * + + +class DistanceCulling: + def __init__(self, distance=13) -> None: + self.block_distance = distance + self.chunk_distance = self.block_distance * 8 + self.maximum_distance = 14 + self.player_location = [0, 0] + + def chunk_in_distance(self, camera, object): + x = camera.transformation[0, 3] + y = camera.transformation[1, 3] + z = camera.transformation[2, 3] + d = sqrt(((x - object.chunk_center.x)**2) + ((y - object.chunk_center.y)**2) + ((z - object.chunk_center.z)**2)) + + if d > self.chunk_distance: + return False + return True + + def direction_calculator(self, A, B): + """ calculating movement direction. + + Args: + A (pygame.Vector3): old location of camera + B (pygame.Vector3): new loacton of camera (after chunk delete) + + Formola: + link: [https://math.stackexchange.com/questions/1086104/get-directional-vector-from-point-a-to-point-b] + the vector pointing in the direction from point A to point B is BA→=OB→−OA→. + """ + try: + vector = A - B + # direction_vector = vector.normalize() + direction_vector = vector + direction = None + + # N + if int(direction_vector.x) == 0 and direction_vector.z < 0: + direction = "N" + + # S + elif int(direction_vector.x) == 0 and direction_vector.z > 0: + direction = "S" + + # E + elif direction_vector.x > 0 and int(direction_vector.z) == 0: + direction = "E" + + # W + elif direction_vector.x < 0 and int(direction_vector.z) == 0: + direction = "W" + + # NE + elif direction_vector.x > 0 and direction_vector.z < 0: + direction = "NE" + + # NW + elif direction_vector.x < 0 and direction_vector.z < 0: + direction = "NW" + + # SE + elif direction_vector.x > 0 and direction_vector.z > 0: + direction = "SE" + + # SW + elif direction_vector.x < 0 and direction_vector.z > 0: + direction = "SW" + + return direction + + except Exception as Error: + if ESP: + print("ERROR: direction vector calculating faild...") + print(Error) + + def coordinates_calculator(self, unloaded_chunk, direction): + """ calculating the cordinates of new chunk. + + Args: + direction (str): player new direction + + Sample: + note! cam: player location + [NW, N, NE] + [W, CAM, E] + [SW, S, SE] + "N" : North + "S" : South + "E" : East + "W" : West + "NE" : Northeast + "NW" : Northwest + "SE" : Southeast + "SW" : Southwest + """ + x = None + z = None + coordinates = None + if direction == "N": + x = unloaded_chunk.chunk_center.x + z = unloaded_chunk.chunk_center.z - self.chunk_distance - 1 + + elif direction == "S": + x = unloaded_chunk.chunk_center.x + z = unloaded_chunk.chunk_center.z + self.chunk_distance + 1 + + elif direction == "E": + x = unloaded_chunk.chunk_center.x + self.chunk_distance + 1 + z = unloaded_chunk.chunk_center.z + + elif direction == "W": + x = unloaded_chunk.chunk_center.x - self.chunk_distance - 1 + z = unloaded_chunk.chunk_center.z + + elif direction == "NE": + x = unloaded_chunk.chunk_center.x + self.chunk_distance + 1 + z = unloaded_chunk.chunk_center.z - self.chunk_distance + 1 + + elif direction == "NW": + x = unloaded_chunk.chunk_center.x - self.chunk_distance - 1 + z = unloaded_chunk.chunk_center.z - self.chunk_distance - 1 + + elif direction == "SE": + x = unloaded_chunk.chunk_center.x + self.chunk_distance + 1 + z = unloaded_chunk.chunk_center.z + self.chunk_distance + 1 + + elif direction == "SW": + x = unloaded_chunk.chunk_center.x - self.chunk_distance - 1 + z = unloaded_chunk.chunk_center.z + self.chunk_distance + 1 + + else: + coordinates = pygame.Vector3(0, 30, 0) + + if x and z: + coordinates = pygame.Vector3(x, 0, z) + return coordinates + +# if __name__ == "__main__": +# temp = DistanceCulling() +# temp.direction_calculator(pygame.Vector3(3, 0, 7), pygame.Vector3(7, 0, 3)) diff --git a/main/Engine2/Light.py b/main/Engine2/Light.py index 2c4f543..e8d7a9b 100644 --- a/main/Engine2/Light.py +++ b/main/Engine2/Light.py @@ -2,11 +2,13 @@ import pygame from .Transformations import * from .Uniform import * +from .Settings2 import * class Light: def __init__(self, position=pygame.Vector3(0, 0, 0), color=pygame.Vector3(1, 1, 1), light_number=0): - print("Loading light...") + if ESP: + print("Loading light...") self.transformation = identity_mat() self.position = position self.color = color diff --git a/main/Engine2/LoadObject.py b/main/Engine2/LoadObject.py index 00804ed..998f6e7 100644 --- a/main/Engine2/LoadObject.py +++ b/main/Engine2/LoadObject.py @@ -1,6 +1,7 @@ # This file reads meshes from objs and processes them from .Mesh import * from .Utils import * +from .Settings2 import * class LoadObject(Mesh): @@ -19,7 +20,8 @@ def __init__(self, filename, imagefile, draw_type=GL_TRIANGLES, memory_save_chunk=False, distance_range=12 ): - print("Loading Objects...") + if ESP: + print("Loading Objects...") # Mesh sections coordinates, triangles, uvs, uvs_ind, normals, normal_ind = self.load_drawing(filename) diff --git a/main/Engine2/Material.py b/main/Engine2/Material.py index b39bcab..bc21189 100644 --- a/main/Engine2/Material.py +++ b/main/Engine2/Material.py @@ -3,7 +3,8 @@ class Material: def __init__(self, vertex_shader, fragment_shader): - print("creating Program...") + if ESP: + print("creating Program...") self.program_id = create_program(open(vertex_shader).read(), open(fragment_shader).read()) def use(self): diff --git a/main/Engine2/Mesh.py b/main/Engine2/Mesh.py index 8470cf1..e3a1eea 100644 --- a/main/Engine2/Mesh.py +++ b/main/Engine2/Mesh.py @@ -2,6 +2,7 @@ from .Uniform import * from .Transformations import * from .Texture import * +from .Settings2 import * class Mesh: @@ -25,7 +26,8 @@ def __init__(self, vertices, memory_save_chunk=False, distance_range=12 ): - print("Building Mesh...") + if ESP: + print("Building Mesh...") self.position = translation self.material= material diff --git a/main/Engine2/Screen.py b/main/Engine2/Screen.py index ced4196..7e504f8 100644 --- a/main/Engine2/Screen.py +++ b/main/Engine2/Screen.py @@ -1,6 +1,8 @@ # This file prepares the page with initial processing settings and executes the main loop import datetime import os + +import pygame from pygame.locals import * from .Camera import * from .Settings2 import * @@ -12,7 +14,8 @@ class Screen: Sceeen initialization """ def __init__(self, screen_posX, screen_posY, screen_width, screen_height): - print("Loading Screen...") + if ESP: + print("Loading Screen...") # program window position init os.environ['SDL_VIDEO_WINDOW_POS'] = "%d,%d" % (screen_posX, screen_posY) self.screen_width = screen_width @@ -27,7 +30,7 @@ def __init__(self, screen_posX, screen_posY, screen_width, screen_height): pygame.display.gl_set_attribute(pygame.GL_CONTEXT_PROFILE_MASK, pygame.GL_CONTEXT_PROFILE_CORE) pygame.display.gl_set_attribute(pygame.GL_DEPTH_SIZE, 24) # GPU DEPTH BUFFER SIZE - self.screen = pygame.display.set_mode((screen_width, screen_height), DOUBLEBUF | OPENGL) + self.screen = pygame.display.set_mode((screen_width, screen_height), DOUBLEBUF | OPENGL, pygame.FULLSCREEN) pygame.display.set_caption(SCREEN_CAPTION_LOADING) self.clock = pygame.time.Clock() self.camera = None @@ -50,7 +53,8 @@ def engine_shutdown(self): """ self.stop_time = datetime.datetime.now() - save_report(self.fps_list, self.start_time, self.stop_time, time_based=False) + if ENGINE_REPORT_SAVE: + save_report(self.fps_list, self.start_time, self.stop_time, time_based=False) self.run = False def initialise(self): diff --git a/main/Engine2/Settings2.py b/main/Engine2/Settings2.py index 5e920f3..e89d952 100644 --- a/main/Engine2/Settings2.py +++ b/main/Engine2/Settings2.py @@ -1,5 +1,15 @@ from OpenGL.GL import GL_LINES +# Debug settings +ENGINE_STATUS_PRINT = True +ENGINE_REPORT_SAVE = False +ESP = ENGINE_STATUS_PRINT + +# Culling Settings +DISTANCE_CULLING = True +DISTANCE_CULLING_DISTANCE = 10 +DCD = DISTANCE_CULLING_DISTANCE + # World settings WORLD_COLOR_R = 0.5 WORLD_COLOR_G = 0.5 @@ -20,6 +30,7 @@ CAMERA_MOUSE_SENSITIVITY_X = 0.1 CAMERA_MOUSE_SENSITIVITY_Y = 0.1 CAMERA_MOVE_SENSITIVITY = 0.31 +# CAMERA_MOVE_SENSITIVITY = 0.05 CAMERA_VIEW_ANGLE = 60 CAMERA_NEAR_PLANE = 0.01 CAMERA_FAR_PLANE = 10000 @@ -33,13 +44,13 @@ # SCREEN_POS_Y = 200 SCREEN_POS_X = 100 SCREEN_POS_Y = 30 -# SCREEN_WIDTH = 1000 -# SCREEN_HEIGHT = 800 -SCREEN_WIDTH = 1800 -SCREEN_HEIGHT = 1000 +SCREEN_WIDTH = 1920 +SCREEN_HEIGHT = 1080 +# SCREEN_WIDTH = 1800 +# SCREEN_HEIGHT = 1000 SCREEN_MULTISAMPLEBUFFERS = 1 SCREEN_MULTISAMPLESAMPLES = 4 SCREEN_DEPTH_SIZE = 24 SCREEN_CAPTION_LOADING = "Loading..." -SCREEN_CAPTION = "3DICU V [Any]" +SCREEN_CAPTION = "OpenUniverse V [VANY] from [1.1.1]" SCREEN_MAX_FPS = 60 diff --git a/main/Engine2/Texture.py b/main/Engine2/Texture.py index 33acfb0..96c21fb 100644 --- a/main/Engine2/Texture.py +++ b/main/Engine2/Texture.py @@ -1,10 +1,11 @@ import pygame from OpenGL.GL import * - +from .Settings2 import * class Texture(): def __init__(self, filename=None): - print("Loading Textures...") + if ESP: + print("Loading Textures...") self.surface = None self.texture_id = glGenTextures(1) if filename is not None: diff --git a/main/Engine2/Transformations.py b/main/Engine2/Transformations.py index f0a9d11..9b3e160 100644 --- a/main/Engine2/Transformations.py +++ b/main/Engine2/Transformations.py @@ -4,9 +4,7 @@ class Rotation: - """" - Rotation angle & axis - """ + "Rotation angle & axis" def __init__(self, angle, axis): self.angle = angle self.axis = axis @@ -95,7 +93,7 @@ def scale3(matrix, x, y, z): return matrix @ sc -def rotate(matrix, angle, axis, local=True): +def rotate(matrix, angle, axis, local = True): rot = identity_mat() if axis == "X": rot = rotate_x_mat(angle) @@ -109,7 +107,7 @@ def rotate(matrix, angle, axis, local=True): return rot @ matrix -def rotateA(matrix, angle, axis, local=True): +def rotateA(matrix, angle, axis, local = True): rot = rotate_axis(angle, axis) if local: return matrix @ rot diff --git a/main/Engine2/Utils.py b/main/Engine2/Utils.py index e3cac5f..11715c1 100644 --- a/main/Engine2/Utils.py +++ b/main/Engine2/Utils.py @@ -4,6 +4,7 @@ import platform as pl import numpy as np from OpenGL.GL import * +from .Settings2 import * def format_vertices(coordinates, triangles) -> np.ndarray: @@ -19,7 +20,8 @@ def compile_shader(shader_type, shader_source): """ Shader compiler """ - print("Compile Program...") + if ESP: + print("Compile Program...") shader_id = glCreateShader(shader_type) glShaderSource(shader_id, shader_source) glCompileShader(shader_id) @@ -56,12 +58,14 @@ def create_program(vertex_shader_code, fragment_shader_code): glDeleteShader(vertex_shader_id) glDeleteShader(fragment_shader_id) - print("Program Created, program_id: ", str(program_id)) + if ESP: + print("Program Created, program_id: ", str(program_id)) return program_id def save_report(fps_list, start_time, end_time, time_based=False): - print("Saving Report...") + if ESP: + print("Saving Report...") uname = pl.uname() fps_min = min(fps_list) fps_max = max(fps_list) diff --git a/main/Level/Cactus.py b/main/Level/Cactus.py new file mode 100644 index 0000000..cfd2c09 --- /dev/null +++ b/main/Level/Cactus.py @@ -0,0 +1,185 @@ +from Engine2.Utils import format_vertices + + +class Cactus: + def __init__(self, position, max_height=4, min_height=0, biome="A", img=None, material=None, shematic=None) -> None: + """ + cactus generator + + Args: + position (pcenter_ygame.Vector3): cactus center vertex position + max_height (int): cactus maximum height + min_height (int): cactus minimum depth + biome (str): cactus biome + img (path): texture + shematic (np.array): cactus generation sample + """ + + self.level_name = "tree1" + self.position = position + self.max_height = max_height + self.min_height = min_height + self.biome = biome + self.image = img + self.material = material + self.texture = img + self.colors = [] + self.normals = None + self.leaf_area = [4, 4] + self.shematic = shematic + + self.vertices, self.triangles, uvs, uvs_ind, normals, normals_ind = self.level_maker(self.position) + self.vertices = format_vertices(self.vertices, self.triangles) + self.vertex_uvs = format_vertices(uvs, uvs_ind) + self.normals = format_vertices(normals, normals_ind) + + for _ in range(len(self.vertices)): + self.colors.append(1) + self.colors.append(1) + self.colors.append(1) + + def level_maker(self, center): + """Tree level maker + + Args: + center (pygame.Vector3): chunk center position + + Sample: + [TLU, TRU] \n + [TLD, TRD] \n + | | \n + [BLU, BRU] \n + [BLD, BRD] \n + """ + + level_vertices = [] + level_triangles = [] + level_uvs = [] + level_uvs_ind = [] + level_normals = [] + level_normals_ind = [] + separator = 0 + uv_counter = 0 + normal_counter = 0 + normals = [(0.0, 0.0, 1.0), (0.0, 0.0, 1.0), (0.0, 0.0, 1.0), (0.0, 0.0, 1.0), (0.0, 1.0, 0.0), (0.0, 1.0, 0.0), + (0.0, 1.0, 0.0), (0.0, 1.0, 0.0), (0.0, 0.0, -1.0), (0.0, 0.0, -1.0), (0.0, 0.0, -1.0), + (0.0, 0.0, -1.0), (0.0, -1.0, 0.0), (0.0, -1.0, 0.0), (0.0, -1.0, 0.0), (0.0, -1.0, 0.0), + (1.0, 0.0, 0.0), (1.0, 0.0, 0.0), (1.0, 0.0, 0.0), (1.0, 0.0, 0.0), (-1.0, 0.0, 0.0), + (-1.0, 0.0, 0.0), (-1.0, 0.0, 0.0), (-1.0, 0.0, 0.0)] + + center_y = int(self.shematic[3][3]) + 1 + + # Tree base + for _ in range(0, self.max_height): + # Top vertices + TLU = (center.x - 1, center_y, center.z - 1) + TLD = (center.x - 1, center_y, center.z + 0) + TRU = (center.x + 0, center_y, center.z - 1) + TRD = (center.x + 0, center_y, center.z + 0) + + # Bottom vertices + BLU = (center.x - 1, center_y - 1, center.z - 1) + BLD = (center.x - 1, center_y - 1, center.z + 0) + BRU = (center.x + 0, center_y - 1, center.z - 1) + BRD = (center.x + 0, center_y - 1, center.z + 0) + + level_vertices.extend([TLU, TLD, TRU, TRD, BLU, BLD, BRU, BRD]) + level_triangles.extend([ + 0 + 8 * separator, 1 + 8 * separator, 2 + 8 * separator, # TRIANGLE 1 + 2 + 8 * separator, 1 + 8 * separator, 3 + 8 * separator, # TRIANGLE 2 + 4 + 8 * separator, 5 + 8 * separator, 6 + 8 * separator, # TRIANGLE 3 + 6 + 8 * separator, 5 + 8 * separator, 7 + 8 * separator, # TRIANGLE 4 + 1 + 8 * separator, 5 + 8 * separator, 3 + 8 * separator, # TRIANGLE 5 + 3 + 8 * separator, 5 + 8 * separator, 7 + 8 * separator, # TRIANGLE 6 + 0 + 8 * separator, 4 + 8 * separator, 2 + 8 * separator, # TRINAGLE 7 + 2 + 8 * separator, 4 + 8 * separator, 6 + 8 * separator, # TRIANGLE 8 + 4 + 8 * separator, 0 + 8 * separator, 5 + 8 * separator, # TRIANGLE 9 + 5 + 8 * separator, 0 + 8 * separator, 1 + 8 * separator, # TRIANGLE 10 + 6 + 8 * separator, 2 + 8 * separator, 7 + 8 * separator, # TRIANGLE 11 + 7 + 8 * separator, 2 + 8 * separator, 3 + 8 * separator, # TRIANGLE 12 + ]) + + separator += 1 + center_y += 1 + + # Texture atlas locations + atlas_length = 1 + atlas_height = 1 + HM_F = 0 # Horizontal Multiplier to first border + HM_L = 1 # Horizontal Multiplier to last border + VM_F = 0 # Vertical Multiplier to first border + VM_L = 1 # Vertical Multiplier to last border + BD = 0.0000000099 # border_deficiency + ONE = 1 + BD + + uvs_face = [ + (ONE / atlas_length * HM_F, ONE / atlas_height * VM_F), + (ONE / atlas_length * HM_L, ONE / atlas_height * VM_F), + (ONE / atlas_length * HM_F, ONE / atlas_height * VM_L), + (ONE / atlas_length * HM_L, ONE / atlas_height * VM_L), + (ONE / atlas_length * HM_F, ONE / atlas_height * VM_F), + (ONE / atlas_length * HM_L, ONE / atlas_height * VM_F), + (ONE / atlas_length * HM_F, ONE / atlas_height * VM_L), + (ONE / atlas_length * HM_L, ONE / atlas_height * VM_L), + (ONE / atlas_length * HM_F, ONE / atlas_height * VM_F), + (ONE / atlas_length * HM_L, ONE / atlas_height * VM_F), + (ONE / atlas_length * HM_F, ONE / atlas_height * VM_L), + (ONE / atlas_length * HM_L, ONE / atlas_height * VM_L), + (ONE / atlas_length * HM_F, ONE / atlas_height * VM_F), + (ONE / atlas_length * HM_L, ONE / atlas_height * VM_F), + (ONE / atlas_length * HM_F, ONE / atlas_height * VM_L), + (ONE / atlas_length * HM_L, ONE / atlas_height * VM_L), + (ONE / atlas_length * HM_F, ONE / atlas_height * VM_F), + (ONE / atlas_length * HM_L, ONE / atlas_height * VM_F), + (ONE / atlas_length * HM_F, ONE / atlas_height * VM_L), + (ONE / atlas_length * HM_L, ONE / atlas_height * VM_L), + (ONE / atlas_length * HM_F, ONE / atlas_height * VM_F), + (ONE / atlas_length * HM_L, ONE / atlas_height * VM_F), + (ONE / atlas_length * HM_F, ONE / atlas_height * VM_L), + (ONE / atlas_length * HM_L, ONE / atlas_height * VM_L) + ] + + # UV vertices + for i in range(24): + level_uvs.append(uvs_face[i]) + + # UV triangles + level_uvs_ind.extend([ + 20 + 24 * uv_counter, 21 + 24 * uv_counter, 22 + 24 * uv_counter, # TRIANGLE 1 + 22 + 24 * uv_counter, 21 + 24 * uv_counter, 23 + 24 * uv_counter, # TRIANGLE 2 + 4 + 24 * uv_counter, 5 + 24 * uv_counter, 6 + 24 * uv_counter, # TRIANGLE 3 + 6 + 24 * uv_counter, 5 + 24 * uv_counter, 7 + 24 * uv_counter, # TRIANGLE 4 + 8 + 24 * uv_counter, 9 + 24 * uv_counter, 10 + 24 * uv_counter, # TRIANGLE 5 + 10 + 24 * uv_counter, 9 + 24 * uv_counter, 11 + 24 * uv_counter, # TRIANGLE 6 + 16 + 24 * uv_counter, 17 + 24 * uv_counter, 18 + 24 * uv_counter, # TRIANGLE 7 + 18 + 24 * uv_counter, 17 + 24 * uv_counter, 19 + 24 * uv_counter, # TRIANGLE 8 + 0 + 24 * uv_counter, 1 + 24 * uv_counter, 2 + 24 * uv_counter, # TRIANGLE 9 + 2 + 24 * uv_counter, 1 + 24 * uv_counter, 3 + 24 * uv_counter, # TRIANGLE 10 + 12 + 24 * uv_counter, 13 + 24 * uv_counter, 14 + 24 * uv_counter, # TRIANGLE 11 + 14 + 24 * uv_counter, 13 + 24 * uv_counter, 15 + 24 * uv_counter, # TRIANGLE 12 + ]) + + uv_counter += 1 + + # Normals + for i in range(24): + level_normals.append(normals[i]) + + level_normals_ind.extend([ + 0 + 24 * normal_counter, 1 + 24 * normal_counter, 2 + 24 * normal_counter, + 2 + 24 * normal_counter, 1 + 24 * normal_counter, 3 + 24 * normal_counter, + 4 + 24 * normal_counter, 5 + 24 * normal_counter, 6 + 24 * normal_counter, + 6 + 24 * normal_counter, 5 + 24 * normal_counter, 7 + 24 * normal_counter, + 8 + 24 * normal_counter, 9 + 24 * normal_counter, 10 + 24 * normal_counter, + 10 + 24 * normal_counter, 9 + 24 * normal_counter, 11 + 24 * normal_counter, + 12 + 24 * normal_counter, 13 + 24 * normal_counter, 14 + 24 * normal_counter, + 14 + 24 * normal_counter, 13 + 24 * normal_counter, 15 + 24 * normal_counter, + 16 + 24 * normal_counter, 17 + 24 * normal_counter, 18 + 24 * normal_counter, + 18 + 24 * normal_counter, 17 + 24 * normal_counter, 19 + 24 * normal_counter, + 20 + 24 * normal_counter, 21 + 24 * normal_counter, 22 + 24 * normal_counter, + 22 + 24 * normal_counter, 21 + 24 * normal_counter, 23 + 24 * normal_counter + ]) + + normal_counter += 1 + + return level_vertices, level_triangles, level_uvs, level_uvs_ind, level_normals, level_normals_ind diff --git a/main/Level/Chunk.py b/main/Level/Chunk.py index 66f1b0d..12b8600 100644 --- a/main/Level/Chunk.py +++ b/main/Level/Chunk.py @@ -1,17 +1,27 @@ -from main.Engine2.Utils import format_vertices +import threading +from Engine2.Utils import format_vertices +from Engine2.Mesh import Mesh +from Engine2.Settings2 import * -class Chunk: - def __init__(self, position=None, max_height=10, min_depth=-10, shematic=None, img=None, material=None) -> None: +class Chunk(Mesh): + def __init__(self, biome="jungle", position=None, max_height=10, min_depth=-10, shematic=None, img=None, material=None) -> None: """ Chunk generator Args: + biome (str): chunk type ["jungle", "desert", "snow"] position (pygame.Vector3): chunk center vertex position max_height (int): chunk maximum height min_depth (int): chunk minimum depth + shematic (np.array): chunk generation sample + img (path): texture + material (): if material -> for loop gen """ + self.known_biomes = ["jungle", "desert", "snow"] + self.biome = biome + self.chunk_center = position # for distance culling self.level_name = "chunk" self.material = material self.texture = img @@ -42,13 +52,44 @@ def __init__(self, position=None, max_height=10, min_depth=-10, shematic=None, i self.VM_L = 1 # Vertical Multiplier to last border self.BD = 0.0000099 # border_deficiency self.ONE = 1 - self.BD - - self.vertices, self.triangles, uvs, uvs_ind, normals, normals_ind = self.level_maker(self.position) + + if self.biome in self.known_biomes: + self.vertices, self.triangles, uvs, uvs_ind, normals, normals_ind = self.level_maker(self.position) + else: + if ESP: + print("Biome not found!") + + # t1 = threading.Thread(target=format_vertices, args=(self.vertices, self.triangles)) + # t2 = threading.Thread(target=format_vertices, args=(uvs, uvs_ind)) + # t3 = threading.Thread(target=format_vertices, args=(normals, normals_ind)) + # + # t1.start() + # t2.start() + # t3.start() + # + # self.vertices = t1.join() + # self.vertex_uvs = t2.join() + # self.normals = t3.join() self.vertices = format_vertices(self.vertices, self.triangles) self.vertex_uvs = format_vertices(uvs, uvs_ind) self.normals = format_vertices(normals, normals_ind) - + + if self.material: + for _ in range(len(self.vertices * 3)): + self.colors.append(CHUNK_COLOR_R) + self.colors.append(CHUNK_COLOR_G) + self.colors.append(CHUNK_COLOR_B) + + super().__init__( + vertices=self.vertices, + imagefile=self.texture, + vertex_normals=self.normals, + vertex_uvs=self.vertex_uvs, + vertex_colors=self.colors, + material=self.material + ) + def level_maker(self, center): """ Chunk level maker @@ -152,33 +193,71 @@ def level_maker(self, center): "DIRT_Z": (2, 3, 1, 2), "DIRT_Y": (2, 3, 0, 1) } - + + # for rendering full chunk use [for DEPTH in range(-13, int(self.shematic[COLUMN][ROW]) + 1): # Y] + # for rendering only surface + 2 blocks deep use [temp = int(self.shematic[COLUMN][ROW]) + 1 + # for DEPTH in range(temp-2, temp): # Y] for ROW in range(0, self.shematic_shape[0]): # Z for COLUMN in range(0, self.shematic_shape[1]): # X - for DEPTH in range(-13, int(self.shematic[COLUMN][ROW]) + 1): # Y + temp = int(self.shematic[COLUMN][ROW]) + 1 + for DEPTH in range(temp-4, temp): # Y self.blocks += 1 - if DEPTH <= -5: # SAND - self.HM_F = 0 - self.HM_L = 1 - self.VM_F = 2 - self.VM_L = 3 - elif -4 <= DEPTH < 0: # DIRT - # dirt = True - self.HM_F = 0 - self.HM_L = 1 - self.VM_F = 1 - self.VM_L = 2 - elif 0 <= DEPTH < 15: # GRASS - self.HM_F = 9 - self.HM_L = 10 - self.VM_F = 15 - self.VM_L = 16 - elif DEPTH >= 15: # SNOW - self.HM_F = 15 - self.HM_L = 16 - self.VM_F = 15 - self.VM_L = 16 + if DEPTH <= -5: + if self.biome == "jungle": # Jungle sand + self.HM_F = 0 + self.HM_L = 1 + self.VM_F = 2 + self.VM_L = 3 + elif self.biome == "desert": + self.HM_F = 0 + self.HM_L = 1 + self.VM_F = 2 + self.VM_L = 3 + elif self.biome == "snow": # Snow pure snow + self.HM_F = 15 + self.HM_L = 16 + self.VM_F = 15 + self.VM_L = 16 + elif -4 <= DEPTH < 0: + if self.biome == "jungle": # Jungle dirt + # dirt = True + self.HM_F = 0 + self.HM_L = 1 + self.VM_F = 1 + self.VM_L = 2 + elif self.biome == "desert": + self.HM_F = 5 + self.HM_L = 6 + self.VM_F = 15 + self.VM_L = 16 + elif self.biome == "snow": # Snow pure snow + self.HM_F = 15 + self.HM_L = 16 + self.VM_F = 15 + self.VM_L = 16 + elif 0 <= DEPTH < 15: + if self.biome == "jungle": # Jungle grass + self.HM_F = 9 + self.HM_L = 10 + self.VM_F = 15 + self.VM_L = 16 + elif self.biome == "desert": + self.HM_F = 0 + self.HM_L = 1 + self.VM_F = 1 + self.VM_L = 2 + elif self.biome == "snow": # Snow ice + self.HM_F = 1 + self.HM_L = 2 + self.VM_F = 14 + self.VM_L = 15 + elif DEPTH >= 15: + if self.biome == "jungle": # Jungle snow + self.HM_F = 1 + self.HM_L = 2 + self.VM_F = 14 + self.VM_L = 15 else: print(f"ERROR: Unidentified block detected... ZXY:{ROW}/{COLUMN}/{DEPTH}") diff --git a/main/Level/ChunkAttach.py b/main/Level/ChunkAttach.py deleted file mode 100644 index 10915f9..0000000 --- a/main/Level/ChunkAttach.py +++ /dev/null @@ -1,31 +0,0 @@ -from pygame import Vector3 -from main.Level.Chunk import * -from main.Level.Shematic import Shematic - - -class ChunkAttach: - """ - Attach chunks together ! - - Making Trains ! - """ - - def __init__(self, startX=0, startY=0, startZ=0, numberx=1, numberz=1, shader=None, texture=None) -> None: - print("Attaching Chunks...") - self.terrain = [] - self.shader = shader - self.texture = texture - self.sx = startX - self.sy = startY - self.sz = startZ - self.endx = numberx * 8 + 1 - self.endz = numberz * 8 + 1 - self.shematic = Shematic(numberx) - self.sample = self.shematic.locate(0, 0) - - self.load_terrain() - - def load_terrain(self): - print("Building Chunks (Multiple Level.Chunk Callings)...") - for x in range(self.sx, self.endx, 8): - for z in range(self.sz, self.endz, 8): - self.terrain.append(Chunk(Vector3(x, 0, z), shematic=self.shematic.locate(x, z))) diff --git a/main/Level/ObjectAttach.py b/main/Level/ObjectAttach.py new file mode 100644 index 0000000..51d4ebb --- /dev/null +++ b/main/Level/ObjectAttach.py @@ -0,0 +1,77 @@ +from random import randint +from pygame import Vector3 +from Level.Chunk import * +from Level.Tree import * +from Level.Cactus import * +from Level.Shematic import Shematic +from Engine2.Settings2 import * + + +class ObjectAttach: + """ + Attach objects together ! + """ + + def __init__(self, object_name="chunk", object_type="", start_x=0, start_y=0, start_z=0, number_x=1, number_z=1, + shader=None, texture=None) -> None: + if ESP: + print("Attaching Objects...") + + self.known_objects = ["chunk", "tree", "cactus"] + self.object_name = object_name + self.object_type = object_type + self.layer = [] + self.shader = shader + self.texture = texture + self.sx = start_x + self.sy = start_y + self.sz = start_z + self.end_x = number_x * 8 + 1 + self.end_z = number_z * 8 + 1 + self.shematic = Shematic(number_x) + self.sample = self.shematic.locate(0, 0) + + if self.object_name not in self.known_objects: + if ESP: + print("A binding method is not specified for this object, use force=True to use default method!") + if self.object_name == "chunk": + self.chunk_binding() + elif self.object_name == "tree": + self.tree_binding() + elif object_name == "cactus": + self.cactus_binding() + else: + # Impossible to reach! + pass + + def chunk_binding(self): + if ESP: + print("Building Chunks (Multiple Level.Chunk Callings)...") + for x in range(self.sx, self.end_x, 8): + for z in range(self.sz, self.end_z, 8): + self.layer.append(Chunk(biome=self.object_type, position=Vector3(x, 0, z), + shematic=self.shematic.locate(x, z), material=self.shader, img=self.texture)) + + def tree_binding(self): + if ESP: + print("Building Trees (Multiple Level.Trees Callings)...") + for x in range(self.sx, self.end_x, 8): + for z in range(self.sz, self.end_z, 8): + y = int(self.shematic.locate(x, z)[3][3]) + if y <= 0 or y >= 15: + continue + else: + if randint(0, 2) in [0, 1]: + self.layer.append(Tree(Vector3(x, 0, z), shematic=self.shematic.locate(x, z))) + + def cactus_binding(self): + if ESP: + print("Building Cactus's (Multiple Leve.Cactus Callings)...") + for x in range(self.sx, self.end_x, 8): + for z in range(self.sz, self.end_z, 8): + y = int(self.shematic.locate(x, z)[3][3]) + if y <= 0 or y >= 15: + continue + else: + if randint(0, 2) in [0, 1]: + self.layer.append(Cactus(Vector3(x, 0, z), shematic=self.shematic.locate(x, z))) diff --git a/main/Level/Tree.py b/main/Level/Tree.py index fcdf36f..3ee4934 100644 --- a/main/Level/Tree.py +++ b/main/Level/Tree.py @@ -1,4 +1,4 @@ -from main.Engine2.Utils import format_vertices +from Engine2.Utils import format_vertices from pygame import Vector3 @@ -12,6 +12,8 @@ def __init__(self, position, max_height=4, min_height=0, biome="A", img=None, ma max_height (int): tree maximum height min_height (int): tree minimum depth biome (str): tree biome + img (path): texture + shematic (np.array): tree generation sample """ self.level_name = "tree1" @@ -108,7 +110,7 @@ def level_maker(self, center): HM_L = 1 # Horizontal Multiplier to last border VM_F = 8 # Vertical Multiplier to first border VM_L = 9 # Vertical Multiplier to last border - BD = 0.0000000099 # border_deficiency + BD = 0.0000000099 # border_deficiency ONE = 1 + BD uvs_face = [ @@ -177,7 +179,7 @@ def level_maker(self, center): 6:(-2, -3), 7:(-3, -4) } - + # COLUMNS cs = { 0:(4, 3), @@ -189,7 +191,7 @@ def level_maker(self, center): 6:(-2, -3), 7:(-3, -4) } - + # TRIANGLES tr = { 1:(0, 1, 2), @@ -205,7 +207,7 @@ def level_maker(self, center): 11:(6, 0, 4), 12:(4, 0, 2) } - + self.leaf_position = Vector3(center.x + 1.5, center_y, center.z + 1.5) for ROW in range(0, self.leaf_area[0]): for COLUMN in range(0, self.leaf_area[1]): @@ -214,13 +216,13 @@ def level_maker(self, center): TLD = (self.leaf_position.x - cs.get(COLUMN)[0], self.leaf_position.y, self.leaf_position.z - rs.get(ROW)[1]) TRU = (self.leaf_position.x - cs.get(COLUMN)[1], self.leaf_position.y, self.leaf_position.z - rs.get(ROW)[0]) TRD = (self.leaf_position.x - cs.get(COLUMN)[1], self.leaf_position.y, self.leaf_position.z - rs.get(ROW)[1]) - + # Bottom vertices BLU = (self.leaf_position.x - cs.get(COLUMN)[0], self.leaf_position.y - 1, self.leaf_position.z - rs.get(ROW)[0]) BLD = (self.leaf_position.x - cs.get(COLUMN)[0], self.leaf_position.y - 1, self.leaf_position.z - rs.get(ROW)[1]) BRU = (self.leaf_position.x - cs.get(COLUMN)[1], self.leaf_position.y - 1, self.leaf_position.z - rs.get(ROW)[0]) BRD = (self.leaf_position.x - cs.get(COLUMN)[1], self.leaf_position.y - 1, self.leaf_position.z - rs.get(ROW)[1]) - + level_vertices.extend([TLU, TLD, TRU, TRD, BLU, BLD, BRU, BRD]) level_triangles.extend([ 0 + 8 * separator, 1 + 8 * separator, 2 + 8 * separator, # TRIANGLE 1 @@ -236,7 +238,7 @@ def level_maker(self, center): 6 + 8 * separator, 2 + 8 * separator, 7 + 8 * separator, # TRIANGLE 11 7 + 8 * separator, 2 + 8 * separator, 3 + 8 * separator, # TRIANGLE 12 ]) - + separator += 1 # Texture atlas locations @@ -248,18 +250,18 @@ def level_maker(self, center): VM_L = 16 # Vertical Multiplier to last border BD = 0.0000000099 # border_deficiency ONE = 1 + BD - + uvs_face = [ - (ONE / atlas_length * HM_F, ONE / atlas_height * VM_F), (ONE / atlas_length * HM_L, ONE / atlas_height * VM_F), (ONE / atlas_length * HM_F, ONE / atlas_height * VM_L), - (ONE / atlas_length * HM_L, ONE / atlas_height * VM_L), (ONE / atlas_length * HM_F, ONE / atlas_height * VM_F), (ONE / atlas_length * HM_L, ONE / atlas_height * VM_F), - (ONE / atlas_length * HM_F, ONE / atlas_height * VM_L), (ONE / atlas_length * HM_L, ONE / atlas_height * VM_L), (ONE / atlas_length * HM_F, ONE / atlas_height * VM_F), - (ONE / atlas_length * HM_L, ONE / atlas_height * VM_F), (ONE / atlas_length * HM_F, ONE / atlas_height * VM_L), (ONE / atlas_length * HM_L, ONE / atlas_height * VM_L), - (ONE / atlas_length * HM_F, ONE / atlas_height * VM_F), (ONE / atlas_length * HM_L, ONE / atlas_height * VM_F), (ONE / atlas_length * HM_F, ONE / atlas_height * VM_L), - (ONE / atlas_length * HM_L, ONE / atlas_height * VM_L), (ONE / atlas_length * HM_F, ONE / atlas_height * VM_F), (ONE / atlas_length * HM_L, ONE / atlas_height * VM_F), - (ONE / atlas_length * HM_F, ONE / atlas_height * VM_L), (ONE / atlas_length * HM_L, ONE / atlas_height * VM_L), (ONE / atlas_length * HM_F, ONE / atlas_height * VM_F), - (ONE / atlas_length * HM_L, ONE / atlas_height * VM_F), (ONE / atlas_length * HM_F, ONE / atlas_height * VM_L), (ONE / atlas_length * HM_L, ONE / atlas_height * VM_L) + (ONE / atlas_length * HM_F, ONE / atlas_height * VM_F), (ONE / atlas_length * HM_L, ONE / atlas_height * VM_F), (ONE / atlas_length * HM_F, ONE / atlas_height * VM_L), + (ONE / atlas_length * HM_L, ONE / atlas_height * VM_L), (ONE / atlas_length * HM_F, ONE / atlas_height * VM_F), (ONE / atlas_length * HM_L, ONE / atlas_height * VM_F), + (ONE / atlas_length * HM_F, ONE / atlas_height * VM_L), (ONE / atlas_length * HM_L, ONE / atlas_height * VM_L), (ONE / atlas_length * HM_F, ONE / atlas_height * VM_F), + (ONE / atlas_length * HM_L, ONE / atlas_height * VM_F), (ONE / atlas_length * HM_F, ONE / atlas_height * VM_L), (ONE / atlas_length * HM_L, ONE / atlas_height * VM_L), + (ONE / atlas_length * HM_F, ONE / atlas_height * VM_F), (ONE / atlas_length * HM_L, ONE / atlas_height * VM_F), (ONE / atlas_length * HM_F, ONE / atlas_height * VM_L), + (ONE / atlas_length * HM_L, ONE / atlas_height * VM_L), (ONE / atlas_length * HM_F, ONE / atlas_height * VM_F), (ONE / atlas_length * HM_L, ONE / atlas_height * VM_F), + (ONE / atlas_length * HM_F, ONE / atlas_height * VM_L), (ONE / atlas_length * HM_L, ONE / atlas_height * VM_L), (ONE / atlas_length * HM_F, ONE / atlas_height * VM_F), + (ONE / atlas_length * HM_L, ONE / atlas_height * VM_F), (ONE / atlas_length * HM_F, ONE / atlas_height * VM_L), (ONE / atlas_length * HM_L, ONE / atlas_height * VM_L) ] - + # UV vertices level_uvs.append(uvs_face[0]) level_uvs.append(uvs_face[1]) @@ -285,7 +287,7 @@ def level_maker(self, center): level_uvs.append(uvs_face[21]) level_uvs.append(uvs_face[22]) level_uvs.append(uvs_face[23]) - + # UV triangles level_uvs_ind.extend([ 20 + 24 * uv_counter, 21 + 24 * uv_counter, 22 + 24 * uv_counter, # TRIANGLE 1 @@ -301,7 +303,7 @@ def level_maker(self, center): 12 + 24 * uv_counter, 13 + 24 * uv_counter, 14 + 24 * uv_counter, # TRIANGLE 11 14 + 24 * uv_counter, 13 + 24 * uv_counter, 15 + 24 * uv_counter, # TRIANGLE 12 ]) - + uv_counter += 1 # Normals diff --git a/main/Level/TreeAttach.py b/main/Level/TreeAttach.py deleted file mode 100644 index 6ebe5a9..0000000 --- a/main/Level/TreeAttach.py +++ /dev/null @@ -1,38 +0,0 @@ -import random -from main.Level.Tree import * -from pygame import Vector3 -from main.Level.Shematic import Shematic - - -class TreeAttach: - """ - Attach Trees together ! - - Making Forests ! - """ - - def __init__(self, startX=0, startY=0, startZ=0, numberx=1, numberz= 1, shader=None, texture=None) -> None: - print("Attaching Trees...") - self.forest = [] - self.shader = shader - self.texture = texture - self.sx = startX - self.sy = startY - self.sz = startZ - self.end = numberx * 8 + 1 - self.end = numberz * 8 + 1 - self.shematic = Shematic(numberx) - - random.seed(100) - self.load_forest() - - - def load_forest(self): - print("Building Trees (Multiple Level.Trees Callings)...") - for x in range(self.sx, self.end, 8): - for z in range(self.sz, self.end, 8): - y = int(self.shematic.locate(x, z)[3][3]) - if y <= 0 or y >= 15: - continue - else: - if random.randint(0, 2) in [0, 1]: - self.forest.append(Tree(Vector3(x, 0, z), shematic=self.shematic.locate(x, z))) diff --git a/main/ICU.py b/main/OpenUniverse.py similarity index 71% rename from main/ICU.py rename to main/OpenUniverse.py index b722642..9b7f2b6 100644 --- a/main/ICU.py +++ b/main/OpenUniverse.py @@ -1,12 +1,12 @@ -from main.Engine2.Screen import * -from main.Engine2.LoadObject import * -from main.Engine2.Light import * -from main.Engine2.Material import * -from main.Engine2.Axes import * -from main.Engine2.CellAttach import * -from main.Engine2.Settings2 import * -from main.Level.ChunkAttach import * -from main.Level.TreeAttach import * +from Engine2.Screen import * +from Engine2.LoadObject import * +from Engine2.Light import * +from Engine2.Material import * +from Engine2.Axes import * +from Engine2.CellAttach import * +from Level.ObjectAttach import * +from Engine2.Cullings.DistanceCulling import * +from Level.Shematic import * from time import sleep from datetime import datetime from time import time @@ -15,7 +15,10 @@ class MultiShaders(Screen): def __init__(self): - print("Starting Engine...") + if ESP: + print("Starting Engine...") + print("Project repo: https://github.com/MatinAfzal/OpenUniverse") + start = datetime.now() print("Starting at:" + str(start.now())) @@ -30,6 +33,10 @@ def __init__(self): self.mat = None self.seed = 0 + # Class init + self.culling_distance = DistanceCulling(distance=DCD) + self.shematic = Shematic(1) + # Switching draw types self.draw_types = [GL_POINTS, GL_LINES, GL_TRIANGLES] self.v_counter = 0 @@ -47,9 +54,11 @@ def __init__(self): self.img_texture = r"Textures\texture.png" self.img_icu = r"Textures\ICU.png" self.img_sun = r"Textures\sun.jpeg" + self.img_cactus = r"Textures\cactus.png" # Loads - print("Loading Files...") + if ESP: + print("Loading Files...") # objects self.obj_cube = r"Models\cube.obj" @@ -62,12 +71,14 @@ def __init__(self): vertexcolfrag = r"Shaders/vertexcolfrag.vs" # Shaders - print("Loading Shaders...") + if ESP: + print("Loading Shaders...") self.mat = Material(texturevert, texturefrag) axesmat = Material(vertexcolvert, vertexcolfrag) # Entity - print("Loading Entitis...") + if ESP: + print("Loading Entitis...") self.axes = Axes(pygame.Vector3(0, 0, 0), axesmat) self.light_pos = pygame.Vector3(-30, 60, -30) @@ -80,22 +91,29 @@ def __init__(self): self.sun_start = int(time()) # Object Attach - self.terrain = ChunkAttach(numberx=5, numberz=5) - self.trees = TreeAttach(numberx=5, numberz=5) + self.terrain = ObjectAttach(object_name="chunk", object_type="jungle", number_x=15, number_z=15) + self.trees = ObjectAttach(object_name="tree", number_x=15, number_z=15) + + # self.terrain = ObjectAttach(object_name="chunk", object_type="desert", number_x=10, number_z=10) + # self.trees = ObjectAttach(object_name="cactus", number_x=10, number_z=10) # Cell Attaches cell_start = datetime.now() - print("Cell Attach started at:" + str(cell_start.now())) + if ESP: + print("Cell Attach started at:" + str(cell_start.now())) - self.world = CellAttach(self.terrain.terrain, shader=self.mat, image=self.img_texture) - self.forest = CellAttach(self.trees.forest, shader=self.mat, image=self.img_texture) + self.world = CellAttach(self.terrain.layer, shader=self.mat, image=self.img_texture) + self.forest = CellAttach(self.trees.layer, shader=self.mat, image=self.img_texture) + # self.forest = CellAttach(self.trees.layer, shader=self.mat, image=self.img_cactus) def initialise(self): # Variables - print("Loading Variables...") + if ESP: + print("Loading Variables...") cell_end = datetime.now() - print("Cell Attach ended at:" + str(cell_end.now())) + if ESP: + print("Cell Attach ended at:" + str(cell_end.now())) glEnable(GL_DEPTH_TEST) glEnable(GL_BLEND) @@ -106,7 +124,8 @@ def camera_init(self): def display(self): # glClearColor(0.5, 0.5 ,0.5, 0.5) # Middle gray - glClearColor(0.58, 0.85 ,0.94, 0.5) # Sky blue + glClearColor(0.58, 0.85, 0.94, 0.5) # Sky blue + # glClearColor(0, 0 ,0, 0.5) # Sky night glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) ##### @@ -116,7 +135,8 @@ def display(self): self.v_counter = 0 self.world.world_draw_type = self.draw_types[self.v_counter] self.forest.world_draw_type = self.draw_types[self.v_counter] - print("Draw Type switched...") + if ESP: + print("Draw Type switched...") self.world.load_world() self.forest.load_world() self.v_counter += 1 @@ -127,10 +147,13 @@ def display(self): self.c_counter = 0 if self.c_counter == 0: - print("Cull Face enabled...") + if ESP: + print("Cull Face enabled...") glEnable(GL_CULL_FACE) + else: - print("Cull Face disabled...") + if ESP: + print("Cull Face disabled...") glDisable(GL_CULL_FACE) self.c_counter += 1 @@ -142,9 +165,11 @@ def display(self): self.x_counter = 0 if self.x_counter == 0: - print("World Center axes enabled...") + if ESP: + print("World Center axes enabled...") else: - print("World Center axes disabled...") + if ESP: + print("World Center axes disabled...") sleep(0.3) @@ -156,11 +181,10 @@ def display(self): sleep(0.3) ##### - glPointSize(10) if self.x_counter == 0: self.axes.draw(self.camera, self.light) - + self.world.world.draw(self.camera, self.light) self.forest.world.draw(self.camera, self.light) self.cube0.draw(self.camera, self.light) @@ -189,7 +213,8 @@ def display(self): if __name__ == "__main__": MultiShaders().mainloop() - print("Mainloop Ends...") + if ESP: + print("Mainloop Ends...") end = datetime.now() print("Ended at:" + str(end.now())) print("\n\n\n") diff --git a/main/Textures/cactus.png b/main/Textures/cactus.png new file mode 100644 index 0000000..1dcdb2f Binary files /dev/null and b/main/Textures/cactus.png differ diff --git a/main/test/TestSite.py b/main/test/TestSite.py new file mode 100644 index 0000000..9f969d9 --- /dev/null +++ b/main/test/TestSite.py @@ -0,0 +1,34 @@ +import numpy as np +import pandas as pd +from Engine2.Settings2 import * + + +class TestSite: + """ + format: format_version-chunk_num_x-chunk_num_z-obj_num_x-obj_num_z-chunk_type-object_type-lighting_method + details: + - chunk_type -> [P: Plain, D: Desert, S: Snow] + - object_type -> [T: Tree, C: Cactus] + - lighting_method -> [D: Dynamic Lighting] + + # + test_sample: + - V1-S -> 1: 1-10-10-10-10-P-T-D + + test_method: + - soft: stand still / locked FPS + - normal: move around / locked FPS + - hard: move around / open FPS + - aggressive: move around / look around / open FPS / fast + """ + + def __init__(self, action="view", test_sample="1", test_method="soft"): + + self.known_actions = ["test", "view"] + self.known_settings = ["V1-S, "] + + if action not in self.known_actions: + if ESP: + print("action not found!") + elif action == "test": + pass diff --git a/report/engine_report.txt b/report/engine_report.txt index ac59488..e69de29 100644 --- a/report/engine_report.txt +++ b/report/engine_report.txt @@ -1,21 +0,0 @@ - - $ TIME $ - / START: 2024-05-10 22:04:16.295732 | END: 2024-05-10 22:04:21.461938 - - $ BUILD $ - / CPU: Intel64 Family 6 Model 183 Stepping 1, GenuineIntel | GPU: NVIDIA GeForce RTX 4060 | SYS: Windows | VER: 10.0.22631 | REL: 11 - - $ FPS $ - / MIN: 0 | MAX: 62 | AVE: 57.44897959183673 - - $ CPU $ - / CPU: Intel64 Family 6 Model 183 Stepping 1, GenuineIntel | TOTAL CORES: 20 | PYSICAL CORES: 14 - / INDEX - PERCENT - /USAGE: [(0, 1.6), (1, 0.0), (2, 0.0), (3, 0.0), (4, 0.0), (5, 0.0), (6, 0.0), (7, 0.0), (8, 0.0), (9, 0.0), (10, 3.1), (11, 0.0), (12, 0.0), (13, 1.6), (14, 0.0), (15, 0.0), (16, 0.0), (17, 0.0), (18, 1.6), (19, 0.0)] - - $ GPU $ - / GPU: NVIDIA GeForce RTX 4060 | ID: 0 | TOTAL MEMORY: 8188.0MB | TEMP: 44.0 °C - - $ SYSTEM $ - / NODE: Matin | MACHINE: AMD64 | BOOT: 1714770703.474444 - \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..0cdb1f9 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,9 @@ +GPUtil==1.4.0 +GPUtil==1.4.0 +matplotlib==3.8.2 +numpy==1.26.4 +perlin_noise==1.12 +psutil==5.9.8 +pygame==2.5.2 +PyOpenGL==3.1.7 +PyOpenGL==3.1.7