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