I have been trying to add greedy meshing to my voxel engine:
vertex shader:
#version 330 core
// Uniforms for camera transformations
uniform mat4 projection;
uniform mat4 view;
// Vertex attributes
layout(location = 0) in vec3 position; // Vertex position
layout(location = 1) in vec3 normal; // Vertex normal
layout(location = 2) in vec4 instancePosition; // Instance position (pass this in the buffer)
// Function to reconstruct the transformation matrix from the instance data
mat4 reconstructMatrix(vec4 instancePosition) {
mat4 model = mat4(1.0);
model[3] = instancePosition; // Set translation using instance position
return model;
}
void main() {
// Reconstruct the model matrix for this instance
mat4 model = reconstructMatrix(instancePosition);
// Calculate final position
gl_Position = projection * view * model * vec4(position, 1.0);
}
fragment shader:
#version 330 core
out vec4 fragColor;
void main() {
fragColor = vec4(0.0, 1.0, 0.0, 1.0); // Green color
}
load_shaders.py
from OpenGL.GL import *
from OpenGL.GLUT import *
SHADER_CACHE = {}
def load_shader(filename, shader_type):
"""Load and compile shader from file."""
with open(filename, 'r') as file:
shader_source = file.read()
shader = glCreateShader(shader_type)
glShaderSource(shader, shader_source)
glCompileShader(shader)
# Error checking after compilation
if glGetShaderiv(shader, GL_COMPILE_STATUS) != GL_TRUE:
error_message = glGetShaderInfoLog(shader)
raise RuntimeError(f"Shader compilation failed: {error_message}")
return shader
def create_shader_program(vertex_shader_file, fragment_shader_file):
"""Create shader program and cache it."""
cache_key = (vertex_shader_file, fragment_shader_file)
if cache_key in SHADER_CACHE:
return SHADER_CACHE[cache_key]
vertex_shader = load_shader(vertex_shader_file, GL_VERTEX_SHADER)
fragment_shader = load_shader(fragment_shader_file, GL_FRAGMENT_SHADER)
program = glCreateProgram()
glAttachShader(program, vertex_shader)
glAttachShader(program, fragment_shader)
glLinkProgram(program)
# Error checking after linking
if glGetProgramiv(program, GL_LINK_STATUS) != GL_TRUE:
error_message = glGetProgramInfoLog(program)
raise RuntimeError(f"Program linking failed: {error_message}")
glDeleteShader(vertex_shader)
glDeleteShader(fragment_shader)
SHADER_CACHE[cache_key] = program
return program
main file: voxel.py
import pygame
from OpenGL.GL import *
from OpenGL.GLUT import *
import numpy as np
import chunk_system
import camera_system
import pstats
from pyrr import Vector3
import input_system
import cProfile
import ctypes
import load_shaders
from math import *
last_projection_matrix = None
last_view_matrix = None
MATRIX_UPDATE_THRESHOLD = 1e-6
def set_projection_matrix(matrix):
global last_projection_matrix
if last_projection_matrix is None or not np.allclose(last_projection_matrix, matrix, atol=MATRIX_UPDATE_THRESHOLD):
glUniformMatrix4fv(glGetUniformLocation(shader_program, "projection"), 1, GL_TRUE, matrix)
last_projection_matrix = matrix.copy()
def set_view_matrix(matrix):
global last_view_matrix
if last_view_matrix is None or not np.allclose(last_view_matrix, matrix, atol=MATRIX_UPDATE_THRESHOLD):
glUniformMatrix4fv(glGetUniformLocation(shader_program, "view"), 1, GL_TRUE, matrix)
last_view_matrix = matrix.copy()
def set_shader_uniforms(shader_program, camera):
"""Sets shader uniforms for rendering."""
projection = camera.get_projection_matrix()
view_matrix = camera.get_view_matrix()
set_projection_matrix(projection)
set_view_matrix(view_matrix)
# Set model matrix
model = np.identity(4, dtype=np.float32)
glUniformMatrix4fv(glGetUniformLocation(shader_program, "model"), 1, GL_TRUE, model)
def matrices_are_different(mat1, mat2, threshold=1e-5):
return np.linalg.norm(mat1 - mat2) > threshold
def initialize_pygame(display_size):
"""Initializes Pygame and sets up the OpenGL context."""
pygame.init()
screen = pygame.display.set_mode(display_size, pygame.OPENGL | pygame.DOUBLEBUF)
pygame.mouse.set_visible(False)
return screen
def initialize_opengl(display_size):
"""Configures OpenGL settings."""
glViewport(0, 0, display_size[0], display_size[1])
glClearColor(0, 0, 0, 1)
glEnable(GL_DEPTH_TEST)
glDepthFunc(GL_LESS)
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)
CHUNK_SIZE = 4
VIEW_DISTANCE = 2
class ChunkRenderer:
def __init__(self):
self.vao = glGenVertexArrays(1)
self.vbo = glGenBuffers(1)
self.ebo = glGenBuffers(1)
self.instance_vbo = glGenBuffers(1)
# Preallocate data buffers with realistic sizes based on typical usage
self.vertex_data = np.zeros((87380, 6), dtype=np.float32)
self.index_data = np.zeros(43690, dtype=np.uint32)
self.instance_data = np.zeros((1024, 4), dtype=np.float32)
self.vertex_count = 0
self.index_count = 0
self.instance_count = 0
# Persistent mapping pointers
self.vertex_ptr = None
self.index_ptr = None
self.instance_ptr = None
# Hashes to track data changes
self.vertex_data_hash = None
self.index_data_hash = None
self.instance_data_hash = None
def setup_buffers(self):
MAX_VERTEX_BUFFER_SIZE = 4 * 1024 * 1024 # 4 MB
MAX_INDEX_BUFFER_SIZE = 2 * 1024 * 1024 # 2 MB
MAX_INSTANCE_BUFFER_SIZE = 2 * 1024 * 1024 # 2 MB
glBindVertexArray(self.vao)
version = glGetString(GL_VERSION).decode('utf-8')
major, minor = map(int, version.split(' ')[0].split('.')[:2])
persistent_mapping_supported = (major > 4) or (major == 4 and minor >= 4)
buffer_flags = GL_DYNAMIC_STORAGE_BIT
if persistent_mapping_supported:
buffer_flags |= GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT
def allocate_buffer(buffer_type, buffer, size, flags):
glBindBuffer(buffer_type, buffer)
glBufferStorage(buffer_type, size, None, flags)
buffer_size = glGetBufferParameteriv(buffer_type, GL_BUFFER_SIZE)
if buffer_size == 0:
raise RuntimeError(f"Buffer allocation failed for {buffer_type} with size {size}.")
# Allocate buffers
allocate_buffer(GL_ARRAY_BUFFER, self.vbo, MAX_VERTEX_BUFFER_SIZE, buffer_flags)
allocate_buffer(GL_ELEMENT_ARRAY_BUFFER, self.ebo, MAX_INDEX_BUFFER_SIZE, buffer_flags)
allocate_buffer(GL_ARRAY_BUFFER, self.instance_vbo, MAX_INSTANCE_BUFFER_SIZE, buffer_flags)
# Set up vertex attributes
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * 4, ctypes.c_void_p(0))
glEnableVertexAttribArray(0)
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * 4, ctypes.c_void_p(3 * 4))
glEnableVertexAttribArray(1)
# Instance data attributes
for i in range(4):
glVertexAttribPointer(2 + i, 4, GL_FLOAT, GL_FALSE, 16 * 4, ctypes.c_void_p(i * 4 * 4))
glEnableVertexAttribArray(2 + i)
glVertexAttribDivisor(2 + i, 1)
glBindVertexArray(0)
print("Buffers setup successfully.")
def update_buffers(self, vertices, indices, instance_data):
def update_buffer(buffer_type, data, data_hash, ptr):
new_hash = hash(data.tobytes())
if data_hash != new_hash:
print(f"Updating {buffer_type} data")
if ptr is not None:
ctypes.memmove(ptr, data.ctypes.data_as(ctypes.POINTER(ctypes.c_float)), data.nbytes)
return new_hash, True
return data_hash, False
# Update vertex, index, and instance buffers separately
glBindBuffer(GL_ARRAY_BUFFER, self.vbo)
self.vertex_data_hash, updated_vertices = update_buffer(GL_ARRAY_BUFFER, vertices, self.vertex_data_hash,
self.vertex_ptr)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, self.ebo)
self.index_data_hash, updated_indices = update_buffer(GL_ELEMENT_ARRAY_BUFFER, indices, self.index_data_hash,
self.index_ptr)
glBindBuffer(GL_ARRAY_BUFFER, self.instance_vbo)
self.instance_data_hash, updated_instances = update_buffer(GL_ARRAY_BUFFER, instance_data,
self.instance_data_hash, self.instance_ptr)
# Update only if any of the buffers have changed
if updated_vertices or updated_indices or updated_instances:
print("Buffers updated successfully.")
def draw_chunks(self):
print(f"VAO: {self.vao}, VBO: {self.vbo}, EBO: {self.ebo}, Instance VBO: {self.instance_vbo}")
glBindVertexArray(self.vao)
glDrawElementsInstanced(GL_TRIANGLES, self.index_count, GL_UNSIGNED_INT, None, self.instance_count)
glBindVertexArray(0)
def delete_buffers(self):
if self.vertex_ptr:
glUnmapBuffer(GL_ARRAY_BUFFER)
if self.index_ptr:
glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER)
glDeleteBuffers(3, [self.vbo, self.ebo, self.instance_vbo])
glDeleteVertexArrays(1, [self.vao])
self.vertex_ptr = None
self.index_ptr = None
self.instance_ptr = None
# Define voxel face offsets and directions
face_offsets = np.array([
[0, 0, 0], [1, 0, 0], [1, 1, 0], [0, 1, 0], # Front face (0)
[0, 0, 1], [1, 0, 1], [1, 1, 1], [0, 1, 1] # Back face (1)
], dtype=np.int32)
# Normals for each of the 6 cube faces
face_normals = np.array([
[0, 0, -1], # Front
[0, 0, 1], # Back
[0, 1, 0], # Top
[0, -1, 0], # Bottom
[-1, 0, 0], # Left
[1, 0, 0] # Right
], dtype=np.int32)
# Combining positions and normals for cube faces
positions = np.concatenate([face_offsets[indices] for indices in [
[0, 1, 2, 3], # Front face
[4, 5, 6, 7], # Back face
[3, 2, 6, 7], # Top face
[0, 1, 5, 4], # Bottom face
[0, 3, 7, 4], # Left face
[1, 2, 6, 5] # Right face
]])
# Repeating the normals for each of the 4 vertices of a cube face
normals = np.repeat(face_normals, 4, axis=0)
# Now combine position and normal into the final vertices
cube_vertices = np.hstack((positions, normals))
# Constants
NEIGHBORS = [(0, 0, -1), (0, 0, 1), (0, 1, 0), (0, -1, 0), (-1, 0, 0), (1, 0, 0)]
# Precompute face normals
FACE_NORMALS = np.array(NEIGHBORS, dtype=np.float32)
# Make sure to clear memory after use:
def clear_memory():
global positions, normals, FACE_NORMALS
print("Debug: Clearing memory for positions, normals, and FACE_NORMALS.")
del positions
del normals
del FACE_NORMALS
# Efficient bitmask-based face exposure check
def get_exposed_faces(chunk_data, x, y, z):
neighbor_offsets = np.array(NEIGHBORS, dtype=np.int32)
neighbor_coords = np.array([x, y, z]) + neighbor_offsets
valid_neighbors = np.all((neighbor_coords >= 0) & (neighbor_coords < chunk_data.shape), axis=1)
neighbors = np.zeros(len(NEIGHBORS), dtype=bool)
neighbors[valid_neighbors] = chunk_data[tuple(neighbor_coords[valid_neighbors].T)] == 0
face_bitmask = np.packbits(neighbors.astype(np.uint8))[0]
return face_bitmask
# Precompute chunk transformations
def precompute_chunk_transform(chunk_pos, chunk_size):
print(f"Debug: Precomputing chunk transform for position {chunk_pos} and size {chunk_size}")
chunk_transform = np.eye(4, dtype=np.float32)
chunk_transform[:3, 3] = np.array(chunk_pos) * chunk_size # Position adjustment
return chunk_transform
def add_vertices_bulk(vertices_block, vertices, vertex_map, vertex_count, tol=1e-6):
vertex_positions = np.round(vertices_block[:, :3], decimals=6) # Round positions to prevent floating-point errors
unique_vertices, indices = np.unique(vertex_positions, axis=0, return_inverse=True)
# Iterate through unique vertices and add them if not already in the map
for i, pos in enumerate(unique_vertices):
pos_tuple = tuple(pos) # Convert to tuple for immutability and fast lookup in vertex_map
if pos_tuple not in vertex_map:
vertex_map[pos_tuple] = vertex_count
vertices[vertex_count] = vertices_block[indices == i][0] # Add the first matching vertex
vertex_count += 1
# Map the vertices' positions to their indices
vertex_indices = np.array([vertex_map[tuple(pos)] for pos in vertex_positions], dtype=np.uint32)
return vertex_indices, vertex_count
# Generate quad indices
def generate_quad_indices(vertex_ids):
# Ensure there are at least 4 vertices, and only create quads if there are enough vertices
if len(vertex_ids) < 4:
raise ValueError("Insufficient vertex count for generating quad indices.")
quads = np.array([
[vertex_ids[0], vertex_ids[1], vertex_ids[2]],
[vertex_ids[0], vertex_ids[2], vertex_ids[3]]
], dtype=np.uint32)
return quads.flatten()
# Example: Precompute exposure mask more efficiently
def compute_exposure_mask(chunk_data):
padded_chunk = np.pad(chunk_data, pad_width=1, mode='constant', constant_values=0)
exposure_mask = np.zeros((*chunk_data.shape, len(NEIGHBORS)), dtype=bool)
for i, (dx, dy, dz) in enumerate(NEIGHBORS):
exposure_mask[..., i] = padded_chunk[1 + dx:1 + dx + chunk_data.shape[0],
1 + dy:1 + dy + chunk_data.shape[1],
1 + dz:1 + dz + chunk_data.shape[2]] == 0
return exposure_mask
# Global counters to accumulate counts across all chunks
total_vertex_count = 0
total_indices_count = 0
total_quad_count = 0
# Reuse memory for `quad_vertices` and `vertex_map`:
def greedy_mesh_faces(chunk_data, chunk_pos, chunk_size, vertices, indices, index_pointer):
global total_vertex_count, total_indices_count, total_quad_count
exposure_mask = compute_exposure_mask(chunk_data)
vertex_map = {}
quad_vertices = np.zeros((4, 6),
dtype=np.float32) # Prepare space for 4 vertices with 6 values (x, y, z, u, v, face_index)
for face_index in range(6):
direction_bit = 1 << face_index
dx, dy, dz = NEIGHBORS[face_index] # Get direction offsets for the face
for z in range(chunk_size):
for y in range(chunk_size):
row_exposure = exposure_mask[:, y, z, face_index] # Row exposure for the given face
start_x = None
for x, exposed in enumerate(row_exposure):
if exposed:
if start_x is None:
start_x = x
elif start_x is not None:
# Now we know a quad exists from start_x to x
# Assign the coordinates for the quad
quad_vertices[0] = [start_x, y, z, 0, 0, face_index] # Bottom-left corner
quad_vertices[1] = [x, y, z, 1, 0, face_index] # Bottom-right corner
quad_vertices[2] = [x, y + dy, z + dz, 1, 1, face_index] # Top-right corner
quad_vertices[3] = [start_x, y + dy, z + dz, 0, 1, face_index] # Top-left corner
# Add vertices to the vertex list
vertex_ids, vertex_count = add_vertices_bulk(quad_vertices, vertices, vertex_map,
total_vertex_count)
# Generate the quad indices
quad_indices = generate_quad_indices(vertex_ids)
# Store the indices in the index array
indices[index_pointer:index_pointer + 6] = quad_indices
index_pointer += 6
# Update the total vertex count
total_vertex_count += len(quad_vertices)
total_indices_count += len(quad_indices)
total_quad_count += 1
# Reset start_x for the next exposed region
start_x = None
return vertices, indices, index_pointer
# Efficient chunk data handling (reuse buffers)
def build_buffers_for_chunks(chunks, chunk_size, chunk_renderer):
print("Debug: Starting geometry creation for chunks")
index_pointer = 0
instance_data = []
if not chunks:
return
# Process each chunk
for chunk_pos, chunk_data in chunks.items():
try:
vertices, indices, index_pointer = greedy_mesh_faces(
chunk_data, chunk_pos, chunk_size, chunk_renderer.vertex_data, chunk_renderer.index_data, index_pointer
)
except Exception as e:
print(f"Debug: Error during greedy meshing: {e}")
return
print(f"Debug: Number of vertices generated: {len(vertices)}")
print(f"Debug: Number of indices generated: {len(indices)}")
chunk_renderer.vertex_count = max(chunk_renderer.vertex_count, index_pointer)
chunk_renderer.index_count = index_pointer
chunk_transform = precompute_chunk_transform(chunk_pos, chunk_size)
instance_data.append(chunk_transform)
print("Debug: Finished geometry creation")
chunk_renderer.update_buffers(chunk_renderer.vertex_data, chunk_renderer.index_data,
np.array(instance_data, dtype=np.float32))
chunk_renderer.instance_count = len(instance_data)
print(f"Debug: Instance count updated to {chunk_renderer.instance_count}")
def chunk_pos_to_screen_rect(chunk_pos):
x, y, z = chunk_pos
screen_x = x * CHUNK_SIZE # Convert chunk x to screen x
screen_y = y * CHUNK_SIZE # Convert chunk y to screen y
return pygame.Rect(screen_x, screen_y, CHUNK_SIZE, CHUNK_SIZE)
def update_chunks(chunk_manager, chunk_renderer, dirty_manager):
for chunk_pos, chunk_data in chunk_manager.get_updated_chunks():
screen_rect = chunk_pos_to_screen_rect(chunk_pos)
dirty_manager.add_dirty_rect(screen_rect)
build_buffers_for_chunks({chunk_pos: chunk_data}, CHUNK_SIZE, chunk_renderer)
LOG2_CHUNK_SIZE = int(log2(CHUNK_SIZE)) # Calculate the base-2 logarithm of CHUNK_SIZE
def determine_visible_chunks(chunk_manager, camera, render_distance):
"""Determines which chunks are visible based on the camera's position."""
visible_chunks = {}
camera_pos = Vector3(camera.position.xyz)
camera_chunk = (camera_pos // CHUNK_SIZE).astype(int)
render_vector = Vector3([render_distance] * 3)
# Define range for chunk positions
min_chunk = camera_chunk - render_vector
max_chunk = camera_chunk + render_vector
# Vectorized computation of all chunk positions in the render distance
x_range, y_range, z_range = (np.arange(start, end + 1) for start, end in zip(min_chunk, max_chunk))
positions = np.stack(np.meshgrid(x_range, y_range, z_range, indexing='ij'), axis=-1).reshape(-1, 3)
# Process chunk positions
for chunk_pos_tuple in map(tuple, positions):
chunk = chunk_manager.loaded_chunks.get(chunk_pos_tuple)
if chunk is None:
chunk = chunk_manager.chunk_cache.get(chunk_pos_tuple)
if chunk is None:
chunk_manager.async_generate_chunk(*chunk_pos_tuple)
else:
visible_chunks[chunk_pos_tuple] = chunk
else:
visible_chunks[chunk_pos_tuple] = chunk
return visible_chunks
class DirtyRectangleManager:
def __init__(self):
self.dirty_rects = []
def add_dirty_rect(self, rect):
"""Add a rectangle to the list of dirty regions."""
self.dirty_rects.append(rect)
def clear_dirty_rects(self):
"""Clear the list of dirty regions."""
self.dirty_rects = []
def get_dirty_rects(self):
"""Return the list of dirty regions."""
return self.dirty_rects
def main():
global shader_program
display_size = (600, 600)
center_x, center_y = display_size[0] // 2, display_size[1] // 2
screen = initialize_pygame(display_size)
initialize_opengl(display_size)
shader_program = load_shaders.create_shader_program("vertex_shader.glsl", "fragment_shader.glsl")
glUseProgram(shader_program)
camera = camera_system.Camera(position=[0, 0, -5], orientation=[0, 90], near=0.5, far=5000000000.0)
camera.aspect_ratio = display_size[0] / display_size[1]
# Chunk system setup
chunk_manager = chunk_system.ChunkManager(camera)
chunk_renderer = ChunkRenderer()
chunk_renderer.setup_buffers()
dirty_manager = DirtyRectangleManager()
# Input handler setup
input_handler = input_system.InputHandler(camera, screen, center_x, center_y)
surface = pygame.Surface(display_size)
previous_visible_chunks = set() # Track visible chunks from the previous frame
previous_camera_position = camera.position[:] # Copy initial position
try:
while True:
if camera.position != previous_camera_position:
dirty_manager.add_dirty_rect(pygame.Rect(100, 100, 200, 200))
previous_camera_position = camera.position[:] # Update the previous position
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
chunk_manager.update()
chunk_manager.process_chunk_queue()
visible_chunks = determine_visible_chunks(chunk_manager, camera, VIEW_DISTANCE)
visible_chunks_set = set(visible_chunks)
if visible_chunks_set != previous_visible_chunks:
update_chunks(chunk_manager, chunk_renderer, dirty_manager)
build_buffers_for_chunks(visible_chunks, CHUNK_SIZE, chunk_renderer)
dirty_manager.add_dirty_rect(pygame.Rect(100, 100, 200, 200))
previous_visible_chunks = visible_chunks_set
set_shader_uniforms(shader_program, camera)
surface.lock()
pixels = pygame.surfarray.pixels3d(surface)
# Draw only dirty regions
for rect in dirty_manager.get_dirty_rects():
glViewport(rect.x, rect.y, rect.width, rect.height)
# Here you'd draw the scene or objects within this rect
chunk_renderer.draw_chunks()
glViewport(0, 0, display_size[0], display_size[1])
# Example of pixel manipulation: gradient fill
pixels = pygame.surfarray.pixels3d(surface)
x_indices = np.arange(display_size[0])
y_indices = np.arange(display_size[1])
x_grid, y_grid = np.meshgrid(x_indices, y_indices, indexing='ij')
# Create a gradient using broadcasting
pixels[:, :, 0] = x_grid % 256
pixels[:, :, 1] = y_grid % 256
pixels[:, :, 2] = (x_grid + y_grid) % 256
del pixels # Explicitly delete the pixel reference
surface.unlock()
# Blit the surface onto the screen
screen.blit(surface, (0, 0))
# Handle input
paused = input_handler.process_input_events()
if paused:
break # Exit the loop if paused
# Update the display
pygame.display.flip()
# Clear the dirty regions for the next frame
dirty_manager.clear_dirty_rects()
except KeyboardInterrupt:
print("Exiting the application...")
finally:
chunk_renderer.delete_buffers()
pygame.quit()
if __name__ == "__main__":
cProfile.run('main()', 'output.prof')
stats = pstats.Stats('output.prof')
stats.sort_stats('time').print_stats(20)
camera.py
import numpy as np
from pyrr import Vector3, vector
VIEW_DISTANCE = 2
# Camera Class
class Camera:
def __init__(self, position, orientation, near, far, fov=45, aspect_ratio=1):
self.position = Vector3(position, dtype=np.float32)
self.orientation = np.array(orientation, dtype=np.float32)
self.fov = fov
self.aspect_ratio = aspect_ratio
self.near = near
self.far = far
self.update_vectors()
def update_vectors(self):
"""Update the camera's forward, right, and up vectors."""
yaw_rad = np.radians(self.orientation[1])
pitch_rad = np.radians(self.orientation[0])
self.forward = Vector3([
np.cos(pitch_rad) * np.sin(yaw_rad),
-np.sin(pitch_rad),
np.cos(pitch_rad) * np.cos(yaw_rad)
], dtype=np.float32)
self.forward = vector.normalize(self.forward)
world_up = Vector3([0, 1, 0], dtype=np.float32)
self.right = vector.normalize(np.cross(world_up, self.forward))
self.up = vector.normalize(np.cross(self.forward, self.right))
def rotate(self, pitch_delta, yaw_delta, sensitivity=0.5):
"""Rotate the camera based on mouse movement."""
self.orientation[0] = np.clip(self.orientation[0] + pitch_delta * sensitivity, -89.0, 89.0)
self.orientation[1] = (self.orientation[1] + yaw_delta * sensitivity) % 360
self.update_vectors()
def get_view_matrix(self):
"""Get the camera's view matrix."""
target_position = self.position + self.forward
z_axis = self.position - target_position
z_axis /= np.linalg.norm(z_axis)
x_axis = np.cross(self.up, z_axis)
x_axis /= np.linalg.norm(x_axis)
y_axis = np.cross(z_axis, x_axis)
return np.array([
[x_axis[0], x_axis[1], x_axis[2], -np.dot(x_axis, self.position)],
[y_axis[0], y_axis[1], y_axis[2], -np.dot(y_axis, self.position)],
[z_axis[0], z_axis[1], z_axis[2], -np.dot(z_axis, self.position)],
[0, 0, 0, 1]
], dtype=np.float32)
def get_projection_matrix(self):
"""Get the camera's projection matrix."""
projection = np.zeros((4, 4), dtype=np.float32)
tan_half_fov = np.tan(np.radians(self.fov / 2))
projection[0, 0] = 1 / (self.aspect_ratio * tan_half_fov)
projection[1, 1] = 1 / tan_half_fov
projection[2, 2] = -(self.far + self.near) / (self.far - self.near)
projection[2, 3] = -1
projection[3, 2] = -(2 * self.far * self.near) / (self.far - self.near)
return projection
…and no matter what i do i can’t seem to get it to render anything anymore:
i’ve tried to deubug by printing out the vertices, indices and instance data to see if there was anything that seemed to be wrong, i’ve added print flags to try and find out if it wasn’t for some reason reaching different stages
Alden Tabor is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
0
Sinh nhật phong cách metal
Tổ chức sinh nhật tại nhà jazz
Dịch vụ sinh nhật xuất sắc hơn
Tiệc sinh nhật cho nhà ngôn ngữ học
Thuê nhóm nhảy metal sinh nhật
Sinh nhật chủ đề sang trọng
Tổ chức sinh nhật tại nhà pop
Dịch vụ sinh nhật hoàn mỹ hơn
Tiệc sinh nhật cho nhà văn học
Trang trí sinh nhật bằng đồ garnet
Sinh nhật phong cách punk rock
Tổ chức sinh nhật tại nhà reggae
Dịch vụ sinh nhật tuyệt vời hơn nữa
Tiệc sinh nhật cho nhà khảo cổ học
Thuê nhóm nhảy punk sinh nhật
Sinh nhật chủ đề ấm cúng
Tổ chức sinh nhật tại nhà blues
Dịch vụ sinh nhật đỉnh cao hơn nữa
Tiệc sinh nhật cho nhà địa lý học
Trang trí sinh nhật bằng đồ aquamarine
Sinh nhật phong cách alternative
Tổ chức sinh nhật tại nhà country
Dịch vụ sinh nhật chất lượng hơn
Tiệc sinh nhật cho nhà thiên văn học
Thuê nhóm nhảy alternative sinh nhật
Sinh nhật chủ đề lãng mạn
Tổ chức sinh nhật tại nhà folk
Dịch vụ sinh nhật sáng chói hơn nữa
Tiệc sinh nhật cho nhà triết học
Trang trí sinh nhật bằng đồ citrine
Sinh nhật phong cách ska
Tổ chức sinh nhật tại nhà techno
Dịch vụ sinh nhật rực rỡ hơn nữa
Tiệc sinh nhật cho nhà kinh tế học
Thuê nhóm nhảy ska sinh nhật
Sinh nhật chủ đề truyền thống
Tổ chức sinh nhật tại nhà electronic
Dịch vụ sinh nhật lung linh hơn nữa
Tiệc sinh nhật cho nhà sử học
Trang trí sinh nhật bằng đồ peridot
Sinh nhật phong cách R&B
Tổ chức sinh nhật tại nhà disco
Dịch vụ sinh nhật đẹp hơn nữa
Tiệc sinh nhật cho nhà nhân học
Thuê nhóm nhảy R&B sinh nhật
Sinh nhật chủ đề phá cách
Tổ chức sinh nhật tại nhà funk
Dịch vụ sinh nhật hoàn toàn hơn nữa
Tiệc sinh nhật cho nhà luật học
Trang trí sinh nhật bằng đồ moonstone
Sinh nhật phong cách gospel
Tổ chức sinh nhật tại nhà soul
Dịch vụ sinh nhật độc đáo hơn nữa
Tiệc sinh nhật cho nhà chính trị học
Thuê nhóm nhảy gospel sinh nhật
Sinh nhật chủ đề nghệ thuật
Tổ chức sinh nhật tại nhà rap
Dịch vụ sinh nhật xuất sắc hơn nữa
Tiệc sinh nhật cho nhà tài chính học
Trang trí sinh nhật bằng đồ onyx
Sinh nhật phong cách hip hop dance
Tổ chức sinh nhật tại nhà indie
Dịch vụ sinh nhật hoàn mỹ hơn nữa
Tiệc sinh nhật cho nhà quản trị học
Thuê nhóm nhảy hip hop sinh nhật
Sinh nhật chủ đề đồng quê
Tổ chức sinh nhật tại nhà acoustic
Dịch vụ sinh nhật tuyệt vời hơn hết
Tiệc sinh nhật cho nhà kỹ thuật học
Trang trí sinh nhật bằng đồ jade
Sinh nhật phong cách breakdance
Tổ chức sinh nhật tại nhà chill
Dịch vụ sinh nhật đỉnh cao hơn hết
Tiệc sinh nhật cho nhà công nghệ học
Thuê nhóm nhảy breakdance sinh nhật
Sinh nhật chủ đề hoàng gia
Tổ chức sinh nhật tại nhà lounge
Dịch vụ sinh nhật chất lượng hơn hết
Tiệc sinh nhật cho nhà nghiên cứu học
Trang trí sinh nhật bằng đồ lapis lazuli
Sinh nhật phong cách street dance
Tổ chức sinh nhật tại nhà classical
Dịch vụ sinh nhật sáng chói hơn hết
Tiệc sinh nhật cho nhà phân tích học
Thuê nhóm nhảy street sinh nhật
Sinh nhật chủ đề huyền bí
Tổ chức sinh nhật tại nhà grunge
Dịch vụ sinh nhật rực rỡ hơn hết
Tiệc sinh nhật cho nhà xã hội học
Trang trí sinh nhật bằng đồ malachite
Sinh nhật phong cách contemporary
Tổ chức sinh nhật tại nhà metal
Dịch vụ sinh nhật lung linh hơn hết
Tiệc sinh nhật cho nhà giáo dục học
Thuê nhóm nhảy contemporary sinh nhật
Sinh nhật chủ đề nhiệt đới
Tổ chức sinh nhật tại nhà punk rock
Dịch vụ sinh nhật đẹp hơn hết
Tiệc sinh nhật cho nhà tâm lý học
Trang trí sinh nhật bằng đồ amber
Sinh nhật phong cách ballet
Tổ chức sinh nhật tại nhà alternative
Dịch vụ sinh nhật hoàn toàn hơn hết
Tiệc sinh nhật cho nhà ngôn ngữ học
Thuê nhóm nhảy ballet sinh nhật
Sinh nhật chủ đề mùa đông
Tổ chức sinh nhật tại nhà ska
Dịch vụ sinh nhật độc đáo hơn hết
Trợ lý AI thông minh nhất cho bạn
Khám phá công nghệ AI tại đây
Trải nghiệm trợ lý ảo tuyệt vời
Công cụ AI hỗ trợ mọi công việc
Tăng năng suất với AI thông minh
AI thay đổi cách bạn làm việc
Trợ lý ảo đáng tin cậy nhất
Khám phá tương lai với AI
Công nghệ AI tiên tiến cho bạn
Hỗ trợ thông minh từ trợ lý AI
AI giúp bạn tiết kiệm thời gian
Trợ lý ảo tốt nhất hiện nay
Công nghệ AI đỉnh cao
Khám phá sức mạnh của AI
Trợ lý AI hỗ trợ 24/7
Công cụ AI cho mọi nhu cầu
AI thông minh, nhanh chóng
Trợ lý ảo dẫn đầu xu hướng
Công nghệ AI dành cho bạn
Hỗ trợ công việc với AI
Trợ lý AI tối ưu hóa công việc
Khám phá AI hiện đại
Công cụ AI đáng kinh ngạc
Trợ lý ảo thông minh vượt trội
AI giúp bạn thành công
Công nghệ AI đáng tin cậy
Trợ lý ảo cho tương lai
Khám phá công cụ AI mới
AI hỗ trợ mọi lúc mọi nơi
Trợ lý ảo thông minh hàng đầu
Công nghệ AI thay đổi cuộc sống
Hỗ trợ tối đa với AI
Trợ lý AI sáng tạo nhất
Công cụ AI mạnh mẽ
Khám phá trợ lý ảo AI
AI thông minh cho mọi người
Trợ lý ảo tối ưu nhất
Công nghệ AI vượt trội
Hỗ trợ công việc bằng AI
Trợ lý AI cho mọi ngành
Khám phá sức mạnh AI
Công cụ AI thông minh nhất
Trợ lý ảo dẫn dắt tương lai
AI hỗ trợ không giới hạn
Công nghệ AI sáng tạo
Trợ lý ảo hiệu quả nhất
Khám phá công nghệ AI đỉnh cao
AI giúp bạn tỏa sáng
Trợ lý ảo thông minh toàn diện
Công cụ AI thay đổi mọi thứ
Trợ lý AI giúp bạn làm việc nhanh hơn
Công nghệ AI hiện đại nhất hiện nay
Trải nghiệm AI thông minh vượt bậc
Công cụ AI hỗ trợ sáng tạo
Trợ lý ảo dành cho mọi nhà
AI tối ưu hóa công việc hàng ngày
Khám phá trợ lý AI tiên tiến
Công nghệ AI cho doanh nghiệp
Trợ lý ảo giúp bạn tiết kiệm sức lực
AI thông minh hỗ trợ cá nhân
Công cụ AI cho tương lai gần
Trợ lý ảo tối ưu mọi tác vụ
Khám phá công nghệ AI độc đáo
AI giúp bạn đạt hiệu quả cao
Trợ lý ảo thông minh và thân thiện
Công nghệ AI dành cho mọi ngành
Trợ lý AI hỗ trợ liên tục
Khám phá sức mạnh AI vượt trội
Công cụ AI giúp bạn nổi bật
Trợ lý ảo cho công việc hiện đại
AI thông minh dẫn đầu thời đại
Công nghệ AI hỗ trợ toàn diện
Trợ lý ảo giúp bạn sáng tạo hơn
Khám phá AI thông minh hàng đầu
Công cụ AI tối ưu cho bạn
Trợ lý AI thay đổi cách làm việc
Công nghệ AI mạnh mẽ và linh hoạt
Trợ lý ảo thông minh cho mọi người
AI hỗ trợ công việc hiệu quả
Khám phá công cụ AI sáng tạo
Trợ lý ảo giúp bạn thành công hơn
Công nghệ AI dẫn dắt tương lai
Trợ lý AI tối ưu cho doanh nghiệp
AI thông minh hỗ trợ mọi lúc
Công cụ AI dành cho sáng tạo
Trợ lý ảo giúp bạn tiết kiệm chi phí
Khám phá trợ lý AI độc quyền
Công nghệ AI thay đổi mọi ngành
Trợ lý AI thông minh cho cuộc sống
AI hỗ trợ công việc nhóm
Công cụ AI hiện đại và mạnh mẽ
Trợ lý ảo tối ưu hóa thời gian
Khám phá sức mạnh AI thông minh
Công nghệ AI cho mọi nhu cầu
Trợ lý AI giúp bạn đi trước thời đại
AI thông minh hỗ trợ cá nhân hóa
Công cụ AI tối ưu cho công việc
Trợ lý ảo dẫn đầu công nghệ
Khám phá AI vượt xa mong đợi
Công nghệ AI sáng tạo không ngừng
Trợ lý AI thông minh và hiệu quả
AI hỗ trợ bạn mọi lúc mọi nơi
Công cụ AI thay đổi cách sống
Trợ lý ảo tối ưu cho tương lai
Khám phá công nghệ AI tiên phong
Công nghệ AI giúp bạn tỏa sáng
Trợ lý AI hỗ trợ công việc sáng tạo
AI thông minh cho mọi lĩnh vực
Công cụ AI dẫn đầu xu hướng
Trợ lý ảo giúp bạn phát triển
Khám phá trợ lý AI mạnh mẽ
Công nghệ AI hỗ trợ không ngừng
Trợ lý AI thông minh cho doanh nhân
AI tối ưu hóa mọi quy trình
Công cụ AI sáng tạo và thông minh
Trợ lý ảo giúp bạn quản lý thời gian
Khám phá sức mạnh của công nghệ AI
Công nghệ AI thay đổi cách nghĩ
Trợ lý AI hỗ trợ mọi dự án
AI thông minh cho cuộc sống hiện đại
Công cụ AI giúp bạn đi xa hơn
Trợ lý ảo tối ưu cho sáng tạo
Khám phá AI thông minh vượt trội
Công nghệ AI dành cho tương lai
Trợ lý AI giúp bạn thành công lớn
AI hỗ trợ công việc hiệu quả hơn
Công cụ AI thông minh và linh hoạt
Trợ lý ảo dẫn đầu mọi xu hướng
Khám phá công nghệ AI sáng tạo
Công nghệ AI tối ưu hóa cuộc sống
Trợ lý AI thông minh cho mọi ngành
AI giúp bạn quản lý công việc
Công cụ AI dành cho thành công
Trợ lý ảo hỗ trợ không giới hạn
Khám phá trợ lý AI thông minh nhất
Công nghệ AI thay đổi mọi thứ
Trợ lý AI tối ưu cho doanh nghiệp
AI thông minh hỗ trợ sáng tạo
Công cụ AI giúp bạn tiết kiệm thời gian
Trợ lý ảo dẫn dắt tương lai
Khám phá sức mạnh AI hiện đại
Công nghệ AI cho mọi người
Trợ lý AI thông minh và đáng tin cậy
AI hỗ trợ bạn vượt qua thử thách
Công cụ AI tối ưu hóa công việc
Trợ lý ảo giúp bạn phát triển nhanh
Khám phá công nghệ AI tiên tiến
Công nghệ AI sáng tạo cho bạn
Trợ lý AI hỗ trợ mọi nhu cầu
AI thông minh thay đổi cuộc chơi
Công cụ AI dẫn đầu mọi lĩnh vực
Trợ lý ảo tối ưu cho mọi tác vụ
Khám phá trợ lý AI vượt trội
Công nghệ AI giúp bạn thành công
Trợ lý AI thông minh cho tương lai
AI hỗ trợ công việc sáng tạo
Công cụ AI thông minh vượt bậc
Trợ lý ảo giúp bạn quản lý hiệu quả
Khám phá sức mạnh AI sáng tạo
Công nghệ AI tối ưu cho cuộc sống
Trợ lý AI thông minh và hiện đại
AI giúp bạn đi trước xu hướng
Công cụ AI hỗ trợ không ngừng
Trợ lý ảo dẫn đầu công nghệ AI
Khám phá công nghệ AI thông minh
Công nghệ AI thay đổi cách làm việc
Trợ lý AI tối ưu hóa sáng tạo
AI thông minh cho mọi công việc
Công cụ AI giúp bạn phát triển
Trợ lý ảo hỗ trợ mọi lúc
Khám phá trợ lý AI tiên phong
Công nghệ AI sáng tạo vượt trội
Trợ lý AI thông minh cho doanh nghiệp
AI giúp bạn tối ưu hóa thời gian
Công cụ AI mạnh mẽ cho bạn
Trợ lý ảo dẫn dắt mọi ngành
Khám phá sức mạnh AI thông minh
Công nghệ AI hỗ trợ toàn diện
Trợ lý AI tối ưu cho sáng tạo
AI thông minh thay đổi tương lai
Công cụ AI giúp bạn thành công hơn
Trợ lý ảo hỗ trợ không giới hạn
Khám phá công nghệ AI hiện đại
Công nghệ AI sáng tạo cho mọi người
Trợ lý AI thông minh vượt mong đợi
AI giúp bạn quản lý công việc tốt hơn
Công cụ AI tối ưu cho doanh nghiệp
Trợ lý ảo dẫn đầu xu hướng công nghệ
Khám phá trợ lý AI sáng tạo
Công nghệ AI hỗ trợ mọi lĩnh vực
Trợ lý AI thông minh cho cuộc sống
AI tối ưu hóa công việc hàng ngày
Công cụ AI giúp bạn đi xa hơn
Trợ lý ảo hỗ trợ mọi nhu cầu
Khám phá sức mạnh AI vượt trội
Công nghệ AI thay đổi cách sống
Trợ lý AI tối ưu cho tương lai
AI thông minh hỗ trợ sáng tạo
Công cụ AI dẫn đầu mọi xu hướng
Trợ lý ảo giúp bạn phát triển nhanh
Khám phá công nghệ AI tiên phong
Công nghệ AI sáng tạo không ngừng
Trợ lý AI thông minh cho doanh nhân
AI giúp bạn tối ưu hóa hiệu suất
Công cụ AI mạnh mẽ và hiệu quả
Trợ lý ảo dẫn dắt tương lai
Khám phá trợ lý AI thông minh
Công nghệ AI hỗ trợ không giới hạn
Trợ lý AI tối ưu cho mọi ngành
AI thông minh thay đổi mọi thứ
Công cụ AI giúp bạn thành công lớn
Trợ lý ảo hỗ trợ mọi lúc mọi nơi
Khám phá sức mạnh AI hiện đại
Công nghệ AI sáng tạo cho bạn
Trợ lý AI thông minh vượt trội
AI giúp bạn quản lý thời gian tốt hơn
Công cụ AI tối ưu hóa sáng tạo
Trợ lý ảo dẫn đầu công nghệ
Khám phá công nghệ AI vượt bậc
Công nghệ AI hỗ trợ mọi công việc
Trợ lý AI thông minh cho mọi người
AI tối ưu hóa cuộc sống hàng ngày
Công cụ AI giúp bạn phát triển
Trợ lý ảo hỗ trợ không ngừng
Khám phá trợ lý AI tiên tiến
Công nghệ AI sáng tạo và mạnh mẽ
Trợ lý AI thông minh cho doanh nghiệp
AI giúp bạn đi trước thời đại
Công cụ AI tối ưu cho mọi nhu cầu
Trợ lý ảo dẫn dắt mọi xu hướng
Khám phá sức mạnh AI sáng tạo
Công nghệ AI thay đổi cách làm việc
Trợ lý AI thông minh và hiệu quả
AI hỗ trợ bạn vượt qua khó khăn
Công cụ AI giúp bạn tỏa sáng
Trợ lý ảo tối ưu cho công việc
Khám phá công nghệ AI thông minh
Công nghệ AI sáng tạo không giới hạn
Trợ lý AI thông minh cho tương lai
AI giúp bạn quản lý hiệu quả hơn
Công cụ AI tối ưu hóa sáng tạo
Trợ lý ảo dẫn đầu mọi lĩnh vực
Khám phá trợ lý AI vượt trội
Công nghệ AI hỗ trợ toàn diện
Trợ lý AI thông minh cho mọi ngành
AI tối ưu hóa công việc sáng tạo
Công cụ AI giúp bạn thành công
Trợ lý ảo hỗ trợ mọi lúc
Khám phá sức mạnh AI tiên phong
Công nghệ AI sáng tạo vượt bậc
Trợ lý AI thông minh và mạnh mẽ
AI giúp bạn tối ưu hóa thời gian
Công cụ AI dẫn đầu công nghệ
Trợ lý ảo tối ưu cho doanh nghiệp
Khám phá công nghệ AI hiện đại
Công nghệ AI hỗ trợ không ngừng
Trợ lý AI thông minh cho cuộc sống
AI tối ưu hóa mọi công việc
Công cụ AI giúp bạn phát triển nhanh
Trợ lý ảo dẫn dắt tương lai
Khám phá trợ lý AI sáng tạo
Công nghệ AI thay đổi mọi ngành
Trợ lý AI thông minh vượt trội
AI giúp bạn quản lý công việc
Công cụ AI tối ưu cho sáng tạo
Trợ lý ảo hỗ trợ mọi nhu cầu
Khám phá sức mạnh AI thông minh
Công nghệ AI sáng tạo cho bạn
Trợ lý AI thông minh và hiệu quả
AI tối ưu hóa cuộc sống hiện đại
Công cụ AI giúp bạn đi trước xu hướng
Trợ lý ảo dẫn đầu mọi xu hướng
Khám phá công nghệ AI tiên tiến
Công nghệ AI hỗ trợ toàn diện
Trợ lý AI thông minh cho doanh nghiệp
AI giúp bạn tối ưu hóa công việc
Công cụ AI sáng tạo và mạnh mẽ
Trợ lý ảo tối ưu cho tương lai
Khám phá trợ lý AI vượt bậc
Công nghệ AI thay đổi cách sống
Trợ lý AI thông minh cho mọi người
AI hỗ trợ bạn thành công lớn
Công cụ AI giúp bạn phát triển
Trợ lý ảo dẫn dắt mọi lĩnh vực
Khám phá sức mạnh AI sáng tạo
Công nghệ AI tối ưu cho bạn
Trợ lý AI thông minh và đáng tin cậy
AI giúp bạn quản lý thời gian
Công cụ AI hỗ trợ không giới hạn
Trợ lý ảo tối ưu hóa sáng tạo
Khám phá công nghệ AI thông minh
Công nghệ AI sáng tạo vượt trội
Trợ lý AI thông minh cho doanh nhân
AI tối ưu hóa mọi quy trình
Công cụ AI giúp bạn tỏa sáng
Trợ lý ảo dẫn đầu công nghệ
Khám phá trợ lý AI tiên phong
Công nghệ AI hỗ trợ mọi lúc
Trợ lý AI thông minh vượt mong đợi
AI giúp bạn đi trước thời đại
Công cụ AI tối ưu cho công việc
Trợ lý ảo hỗ trợ không ngừng
Khám phá sức mạnh AI hiện đại
Công nghệ AI sáng tạo cho mọi ngành
Trợ lý AI thông minh và hiệu quả
AI tối ưu hóa cuộc sống hàng ngày
Công cụ AI giúp bạn phát triển nhanh
Trợ lý ảo dẫn dắt tương lai
Khám phá công nghệ AI vượt trội
Công nghệ AI hỗ trợ toàn diện
Trợ lý AI thông minh cho mọi người
AI giúp bạn quản lý công việc
Công cụ AI tối ưu hóa sáng tạo
Trợ lý ảo hỗ trợ mọi nhu cầu
Khám phá trợ lý AI sáng tạo
Công nghệ AI thay đổi mọi thứ
Trợ lý AI thông minh vượt bậc
AI tối ưu hóa công việc hiệu quả
Công cụ AI giúp bạn thành công
Trợ lý ảo dẫn đầu mọi xu hướng
Khám phá sức mạnh AI thông minh
Công nghệ AI sáng tạo không ngừng
Trợ lý AI thông minh cho doanh nghiệp
AI giúp bạn tối ưu hóa thời gian
Công cụ AI hỗ trợ không giới hạn
Trợ lý ảo tối ưu cho tương lai
Khám phá công nghệ AI tiên tiến
Công nghệ AI sáng tạo vượt trội
Trợ lý AI thông minh và mạnh mẽ
AI tối ưu hóa mọi công việc
Công cụ AI giúp bạn phát triển
Trợ lý ảo dẫn dắt mọi lĩnh vực
Khám phá trợ lý AI vượt trội
Công nghệ AI hỗ trợ toàn diện
Trợ lý AI thông minh cho mọi ngành
AI giúp bạn quản lý hiệu quả
Công cụ AI tối ưu hóa sáng tạo
Trợ lý ảo hỗ trợ không ngừng
Khám phá sức mạnh AI hiện đại
Công nghệ AI sáng tạo cho bạn
Trợ lý AI thông minh vượt mong đợi
AI tối ưu hóa cuộc sống hiện đại
Công cụ AI giúp bạn đi trước xu hướng
Trợ lý ảo dẫn đầu công nghệ
Khám phá công nghệ AI thông minh
Công nghệ AI hỗ trợ mọi lúc
Trợ lý AI thông minh cho doanh nhân
AI giúp bạn tối ưu hóa công việc
Công cụ AI sáng tạo và hiệu quả
Trợ lý ảo tối ưu cho mọi người
Khám phá trợ lý AI tiên phong
Công nghệ AI thay đổi cách sống
Trợ lý AI thông minh vượt trội
AI tối ưu hóa mọi quy trình
Công cụ AI giúp bạn thành công lớn
Trợ lý ảo dẫn dắt tương lai
Khám phá sức mạnh AI sáng tạo
Công nghệ AI hỗ trợ không giới hạn
Trợ lý AI thông minh cho mọi ngành
AI giúp bạn quản lý thời gian
Công cụ AI tối ưu cho sáng tạo
Trợ lý ảo hỗ trợ mọi nhu cầu
Khám phá công nghệ AI vượt bậc
Công nghệ AI sáng tạo cho bạn
Trợ lý AI thông minh và hiệu quả
AI tối ưu hóa công việc hàng ngày
Công cụ AI giúp bạn phát triển
Trợ lý ảo dẫn đầu mọi xu hướng
Khám phá trợ lý AI thông minh
Công nghệ AI hỗ trợ toàn diện
Trợ lý AI thông minh vượt mong đợi
AI giúp bạn đi trước thời đại
Công cụ AI tối ưu cho doanh nghiệp
Trợ lý ảo hỗ trợ không ngừng
Khám phá sức mạnh AI hiện đại
Công nghệ AI sáng tạo không ngừng
Trợ lý AI thông minh cho mọi người
AI tối ưu hóa mọi công việc
Công cụ AI giúp bạn thành công
Trợ lý ảo dẫn dắt mọi lĩnh vực
Khám phá công nghệ AI tiên tiến
Công nghệ AI hỗ trợ mọi lúc
Trợ lý AI thông minh vượt trội
AI giúp bạn quản lý hiệu quả
Công cụ AI tối ưu hóa sáng tạo
Trợ lý ảo hỗ trợ không giới hạn
Khám phá trợ lý AI sáng tạo
Công nghệ AI thay đổi cách sống
Trợ lý AI thông minh cho doanh nghiệp
AI tối ưu hóa công việc sáng tạo
Công cụ AI giúp bạn phát triển nhanh
Trợ lý ảo dẫn đầu công nghệ
Khám phá sức mạnh AI vượt bậc
Công nghệ AI sáng tạo cho bạn
Trợ lý AI thông minh và hiệu quả
AI giúp bạn đi trước xu hướng
Công cụ AI tối ưu cho mọi người
Trợ lý ảo hỗ trợ mọi lúc mọi nơi
Khám phá công nghệ AI thông minh
Công nghệ AI hỗ trợ không ngừng
Trợ lý AI thông minh vượt mong đợi
AI tối ưu hóa cuộc sống hiện đại
Công cụ AI giúp bạn thành công lớn
Trợ lý ảo dẫn dắt tương lai
Khám phá trợ lý AI tiên phong
Công nghệ AI sáng tạo vượt trội
Trợ lý AI thông minh cho doanh nhân
AI giúp bạn quản lý thời gian
Công cụ AI tối ưu hóa công việc
Trợ lý ảo hỗ trợ không giới hạn
Khám phá sức mạnh AI sáng tạo
Công nghệ AI thay đổi mọi ngành
Trợ lý AI thông minh và mạnh mẽ
AI tối ưu hóa mọi quy trình
Công cụ AI giúp bạn phát triển
Trợ lý ảo dẫn đầu mọi xu hướng
Khám phá công nghệ AI vượt trội
Công nghệ AI hỗ trợ toàn diện
Trợ lý AI thông minh cho mọi người
AI giúp bạn đi trước thời đại
Công cụ AI tối ưu cho sáng tạo
Trợ lý ảo hỗ trợ mọi lúc
Khám phá trợ lý AI thông minh
Công nghệ AI sáng tạo không ngừng
Trợ lý AI thông minh vượt bậc
AI tối ưu hóa công việc hiệu quả
Công cụ AI giúp bạn thành công
Trợ lý ảo dẫn dắt mọi lĩnh vực
Khám phá sức mạnh AI tiên phong
Công nghệ AI hỗ trợ không giới hạn
Trợ lý AI thông minh cho doanh nghiệp
AI giúp bạn quản lý hiệu quả
Công cụ AI tối ưu hóa sáng tạo
Trợ lý ảo hỗ trợ mọi nhu cầu
Khám phá công nghệ AI hiện đại
Công nghệ AI sáng tạo cho bạn
Trợ lý AI thông minh và hiệu quả
AI tối ưu hóa cuộc sống hàng ngày
Công cụ AI giúp bạn phát triển nhanh
Trợ lý ảo dẫn đầu công nghệ
Khám phá trợ lý AI vượt trội
Công nghệ AI hỗ trợ toàn diện
Trợ lý AI thông minh vượt mong đợi
AI giúp bạn đi trước xu hướng
Công cụ AI tối ưu cho doanh nghiệp
Trợ lý ảo hỗ trợ không ngừng
Khám phá sức mạnh AI sáng tạo
Công nghệ AI thay đổi mọi thứ
Trợ lý AI thông minh cho mọi người
AI tối ưu hóa mọi công việc
Công cụ AI giúp bạn thành công lớn
Trợ lý ảo dẫn dắt tương lai
Khám phá công nghệ AI tiên phong
Công nghệ AI sáng tạo vượt trội
Trợ lý AI thông minh và mạnh mẽ
AI giúp bạn quản lý thời gian
Công cụ AI tối ưu hóa công việc
Trợ lý ảo hỗ trợ không giới hạn
Khám phá trợ lý AI thông minh
Công nghệ AI hỗ trợ mọi lúc
Trợ lý AI thông minh vượt bậc
AI tối ưu hóa cuộc sống hiện đại
Công cụ AI giúp bạn phát triển
Trợ lý ảo dẫn đầu mọi xu hướng
Khám phá sức mạnh AI vượt trội
Công nghệ AI sáng tạo cho bạn
Trợ lý AI thông minh và hiệu quả
AI giúp bạn đi trước thời đại
Công cụ AI tối ưu cho sáng tạo
Trợ lý ảo hỗ trợ mọi nhu cầu
Khám phá công nghệ AI hiện đại
Công nghệ AI hỗ trợ không ngừng
Trợ lý AI thông minh vượt mong đợi
AI tối ưu hóa mọi quy trình
Công cụ AI giúp bạn thành công
Trợ lý ảo dẫn dắt mọi lĩnh vực
Khám phá trợ lý AI tiên phong
Công nghệ AI sáng tạo vượt trội
Trợ lý AI thông minh cho doanh nghiệp
AI giúp bạn quản lý hiệu quả
Công cụ AI tối ưu hóa sáng tạo
Trợ lý ảo hỗ trợ không giới hạn
Khám phá sức mạnh AI thông minh
Công nghệ AI thay đổi cách sống
Trợ lý AI thông minh và mạnh mẽ
AI tối ưu hóa công việc hàng ngày
Công cụ AI giúp bạn phát triển nhanh
Trợ lý ảo dẫn đầu công nghệ
Khám phá công nghệ AI vượt bậc
Công nghệ AI sáng tạo cho bạn
Trợ lý AI thông minh vượt trội
AI giúp bạn đi trước xu hướng
Công cụ AI tối ưu cho mọi người
Trợ lý ảo hỗ trợ mọi lúc mọi nơi
Khám phá trợ lý AI thông minh
Công nghệ AI hỗ trợ không ngừng
Trợ lý AI thông minh vượt mong đợi
AI tối ưu hóa cuộc sống hiện đại
Công cụ AI giúp bạn thành công lớn
Trợ lý ảo dẫn dắt tương lai
Khám phá sức mạnh AI tiên phong
Công nghệ AI sáng tạo vượt trội
Trợ lý AI thông minh cho doanh nhân
AI giúp bạn quản lý thời gian
Công cụ AI tối ưu hóa công việc
Trợ lý ảo hỗ trợ không giới hạn
Khám phá công nghệ AI hiện đại
Công nghệ AI hỗ trợ mọi lúc
Trợ lý AI thông minh vượt bậc
AI tối ưu hóa mọi quy trình
Công cụ AI giúp bạn phát triển
Trợ lý ảo dẫn đầu mọi xu hướng
Khám phá trợ lý AI thông minh
Công nghệ AI sáng tạo không ngừng
Trợ lý AI thông minh vượt trội
AI giúp bạn đi trước thời đại
Công cụ AI tối ưu cho sáng tạo
Trợ lý ảo hỗ trợ mọi nhu cầu
Khám phá sức mạnh AI vượt bậc
Công nghệ AI thay đổi cách sống
Trợ lý AI thông minh và hiệu quả
AI tối ưu hóa công việc hàng ngày
Công cụ AI giúp bạn thành công
Trợ lý ảo dẫn dắt mọi lĩnh vực
Khám phá công nghệ AI tiên phong
Công nghệ AI sáng tạo vượt trội
Trợ lý AI thông minh cho doanh nghiệp
AI giúp bạn quản lý hiệu quả
Công cụ AI tối ưu hóa sáng tạo
Trợ lý ảo hỗ trợ không ngừng
Khám phá trợ lý AI thông minh
Công nghệ AI hỗ trợ toàn diện
Trợ lý AI thông minh vượt mong đợi
AI tối ưu hóa mọi công việc
Công cụ AI giúp bạn phát triển nhanh
Trợ lý ảo dẫn đầu công nghệ
Khám phá sức mạnh AI sáng tạo
Công nghệ AI thay đổi mọi ngành
Trợ lý AI thông minh và mạnh mẽ
AI giúp bạn đi trước xu hướng
Công cụ AI tối ưu cho mọi người
Trợ lý ảo hỗ trợ mọi lúc mọi nơi
Khám phá công nghệ AI vượt trội
Công nghệ AI sáng tạo không ngừng
Trợ lý AI thông minh vượt bậc
AI tối ưu hóa cuộc sống hiện đại
Công cụ AI giúp bạn thành công lớn
Trợ lý ảo dẫn dắt tương lai
Khám phá trợ lý AI tiên phong
Công nghệ AI hỗ trợ không giới hạn
Trợ lý AI thông minh cho doanh nhân
AI giúp bạn quản lý thời gian
Công cụ AI tối ưu hóa công việc
Trợ lý ảo hỗ trợ mọi nhu cầu
Khám phá sức mạnh AI thông minh
Công nghệ AI sáng tạo cho bạn
Trợ lý AI thông minh và hiệu quả
AI tối ưu hóa mọi quy trình
Công cụ AI giúp bạn phát triển
Trợ lý ảo dẫn đầu mọi xu hướng
Khám phá công nghệ AI hiện đại
Công nghệ AI hỗ trợ toàn diện
Trợ lý AI thông minh vượt trội
AI giúp bạn đi trước thời đại
Công cụ AI tối ưu cho sáng tạo
Trợ lý ảo hỗ trợ không ngừng
Khám phá trợ lý AI thông minh
Công nghệ AI sáng tạo vượt bậc
Trợ lý AI thông minh cho doanh nghiệp
AI tối ưu hóa công việc hàng ngày
Công cụ AI giúp bạn thành công
Trợ lý ảo dẫn dắt mọi lĩnh vực
Khám phá sức mạnh AI tiên phong
Công nghệ AI hỗ trợ mọi lúc
Trợ lý AI thông minh vượt mong đợi
AI giúp bạn quản lý hiệu quả
Công cụ AI tối ưu hóa sáng tạo
Trợ lý ảo hỗ trợ không giới hạn
Khám phá công nghệ AI vượt trội
Công nghệ AI sáng tạo cho bạn
Trợ lý AI thông minh và mạnh mẽ
AI tối ưu hóa mọi công việc
Công cụ AI giúp bạn phát triển nhanh
Trợ lý ảo dẫn đầu công nghệ
Khám phá trợ lý AI thông minh
Công nghệ AI hỗ trợ không ngừng
Trợ lý AI thông minh vượt bậc
AI giúp bạn đi trước xu hướng
Công cụ AI tối ưu cho mọi người
Trợ lý ảo hỗ trợ mọi lúc mọi nơi
Khám phá sức mạnh AI sáng tạo
Công nghệ AI thay đổi cách sống
Trợ lý AI thông minh vượt trội
AI tối ưu hóa cuộc sống hiện đại
Công cụ AI giúp bạn thành công lớn
Trợ lý ảo dẫn dắt tương lai
Khám phá công nghệ AI tiên phong
Công nghệ AI sáng tạo không ngừng
Trợ lý AI thông minh cho doanh nhân
AI giúp bạn quản lý thời gian
Công cụ AI tối ưu hóa công việc
Trợ lý ảo hỗ trợ không giới hạn
Khám phá trợ lý AI thông minh
Công nghệ AI hỗ trợ mọi lúc
Trợ lý AI thông minh vượt mong đợi
AI tối ưu hóa mọi quy trình
Công cụ AI giúp bạn phát triển
Trợ lý ảo dẫn đầu mọi xu hướng
Khám phá sức mạnh AI vượt trội
Công nghệ AI sáng tạo cho bạn
Trợ lý AI thông minh và hiệu quả
AI giúp bạn đi trước thời đại
Công cụ AI tối ưu cho sáng tạo
Trợ lý ảo hỗ trợ mọi nhu cầu
Khám phá công nghệ AI hiện đại
Công nghệ AI hỗ trợ không ngừng
Trợ lý AI thông minh vượt bậc
AI tối ưu hóa công việc hàng ngày
Công cụ AI giúp bạn thành công
Trợ lý ảo dẫn dắt mọi lĩnh vực
Khám phá trợ lý AI tiên phong
Công nghệ AI sáng tạo vượt trội
Trợ lý AI thông minh cho doanh nghiệp
AI giúp bạn quản lý hiệu quả
Công cụ AI tối ưu hóa sáng tạo
Trợ lý ảo hỗ trợ không giới hạn
Khám phá sức mạnh AI thông minh
Công nghệ AI thay đổi cách sống
Trợ lý AI thông minh và mạnh mẽ
AI tối ưu hóa mọi công việc
Công cụ AI giúp bạn phát triển nhanh
Trợ lý ảo dẫn đầu công nghệ
Khám phá công nghệ AI vượt trội
Công nghệ AI sáng tạo cho bạn
Trợ lý AI thông minh vượt mong đợi
AI giúp bạn đi trước xu hướng
Công cụ AI tối ưu cho mọi người
Trợ lý ảo hỗ trợ mọi lúc mọi nơi
Khám phá trợ lý AI thông minh
Công nghệ AI hỗ trợ không ngừng
Trợ lý AI thông minh vượt bậc
AI tối ưu hóa cuộc sống hiện đại
Công cụ AI giúp bạn thành công lớn
Trợ lý ảo dẫn dắt tương lai
Khám phá sức mạnh AI tiên phong
Công nghệ AI sáng tạo vượt trội
Trợ lý AI thông minh cho doanh nhân
AI giúp bạn quản lý thời gian
Công cụ AI tối ưu hóa công việc
Trợ lý ảo hỗ trợ không giới hạn
Khám phá công nghệ AI hiện đại
Công nghệ AI hỗ trợ mọi lúc
Trợ lý AI thông minh vượt mong đợi
AI tối ưu hóa mọi quy trình
Công cụ AI giúp bạn phát triển
Trợ lý ảo dẫn đầu mọi xu hướng
Khám phá trợ lý AI thông minh
Công nghệ AI sáng tạo không ngừng
Trợ lý AI thông minh vượt trội
AI giúp bạn đi trước thời đại
Công cụ AI tối ưu cho sáng tạo
Trợ lý ảo hỗ trợ mọi nhu cầu
Khám phá sức mạnh AI vượt bậc
Công nghệ AI thay đổi cách sống
Trợ lý AI thông minh và hiệu quả
AI tối ưu hóa công việc hàng ngày
Công cụ AI giúp bạn thành công
Trợ lý ảo dẫn dắt mọi lĩnh vực
Khám phá công nghệ AI tiên phong
Công nghệ AI sáng tạo vượt trội
Trợ lý AI thông minh cho doanh nghiệp
AI giúp bạn quản lý hiệu quả
Công cụ AI tối ưu hóa sáng tạo
Trợ lý ảo hỗ trợ không giới hạn
Khám phá trợ lý AI thông minh
Công nghệ AI hỗ trợ toàn diện
Trợ lý AI thông minh vượt mong đợi
AI tối ưu hóa mọi công việc
Công cụ AI giúp bạn phát triển nhanh
Trợ lý ảo dẫn đầu công nghệ
Khám phá sức mạnh AI sáng tạo
Công nghệ AI thay đổi mọi ngành
Trợ lý AI thông minh và mạnh mẽ
AI giúp bạn đi trước xu hướng
Công cụ AI tối ưu cho mọi người
Trợ lý ảo hỗ trợ mọi lúc mọi nơi
Khám phá công nghệ AI vượt trội
Công nghệ AI sáng tạo không ngừng
Trợ lý AI thông minh vượt bậc
AI tối ưu hóa cuộc sống hiện đại
Công cụ AI giúp bạn thành công lớn
Trợ lý ảo dẫn dắt tương lai
Khám phá trợ lý AI tiên phong
Công nghệ AI hỗ trợ không giới hạn
Trợ lý AI thông minh cho doanh nhân
AI giúp bạn quản lý thời gian
Xổ số miền Nam Kết quả xổ số miền Nam XSMN hôm nay KQXS miền Nam XSMN trực tiếp KQXS hôm nay Xổ số kiến thiết miền Nam Dự đoán XSMN Xổ số miền Nam 24h XSMN chuẩn Kết quả xổ số nhanh Xổ số miền Nam hôm qua XSMN VIP Xổ số miền Nam 7 ngày Xổ số miền Nam chính xác XSMN 3 miền XSMN mới nhất Trực tiếp xổ số miền Nam Xổ số miền Nam hôm nay KQXS miền Nam chính xác Xổ số miền Nam hàng ngày Xổ số miền Nam nhanh nhất Dò vé số miền Nam Xổ số miền Nam chính thống Xổ số kiến thiết Kết quả xổ số miền Nam mới nhất XSMN cực nhanh Thống kê XSMN Dò xổ số miền Nam Xổ số online miền Nam KQXS hôm qua Xổ số nhanh nhất XSMN uy tín KQXS hôm nay nhanh nhất Dự đoán KQXS miền Nam Xổ số siêu tốc Xổ số VIP Xổ số miền Nam 30 ngày Lịch mở thưởng XSMN Xổ số hôm nay XSMN 2025 Dò vé số hôm nay Xổ số miền Nam miễn phí Trực tiếp KQXS miền Nam Dò xổ số nhanh Dự đoán XSMN chuẩn Xổ số 3 miền chính xác Thống kê xổ số miền Nam Dự đoán lô đề XSMN Kết quả XSMN online Kết quả xổ số 3 miền Dò xổ số VIP XSMN miễn phí Xổ số dễ trúng Xổ số miền Nam mỗi ngày Dự đoán XSMN hôm nay Thống kê kết quả XSMN Xổ số miền Nam hôm nay nhanh nhất Xổ số miền Nam mới nhất Xổ số miền Nam hôm qua Dự đoán xổ số miền Nam