integer line tracing

This commit is contained in:
Zack Buhman 2026-03-10 23:54:55 -05:00
parent 43134dcdab
commit 48a85671c8
30 changed files with 119664 additions and 92 deletions

2
.gitignore vendored
View File

@ -8,3 +8,5 @@ main
*.dylib *.dylib
__pycache__ __pycache__
minecraft/region*.lights.vtx minecraft/region*.lights.vtx
minecraft/region*.dump
minecraft/gen/map.txt

View File

@ -22,7 +22,10 @@ OBJS = \
src/test.o \ src/test.o \
src/font.o \ src/font.o \
src/window.o \ src/window.o \
src/bresenham.o src/bresenham.o \
src/file.o \
src/world.o \
src/inthash.o
all: test.so all: test.so

14
include/file.h Normal file
View File

@ -0,0 +1,14 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
extern char const * g_source_path;
extern int g_source_path_length;
void * read_file(const char * filename, int * out_size);
#ifdef __cplusplus
}
#endif

6
include/hash.h Normal file
View File

@ -0,0 +1,6 @@
#pragma once
#include <stdint.h>
uint32_t
inthash(const int32_t key);

14
include/inthash.h Normal file
View File

@ -0,0 +1,14 @@
#pragma once
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
uint32_t
inthash(const int32_t key);
#ifdef __cplusplus
}
#endif

View File

@ -4,11 +4,6 @@
extern "C" { extern "C" {
#endif #endif
extern char const * g_source_path;
extern int g_source_path_length;
void * read_file(const char * filename, int * out_size);
unsigned int compile_from_files(const char * vertex_path, unsigned int compile_from_files(const char * vertex_path,
const char * geometry_path, const char * geometry_path,
const char * fragment_path); const char * fragment_path);

23
include/world.h Normal file
View File

@ -0,0 +1,23 @@
#pragma once
#include <stdint.h>
#include <assert.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct global_entry {
int global_index;
uint8_t block_id;
uint8_t block_data;
uint16_t _padding;
} global_entry_t;
static_assert((sizeof (global_entry_t)) == 8);
void load_world();
global_entry_t * const world_lookup(int x, int y, int z);
#ifdef __cplusplus
}
#endif

View File

@ -30,7 +30,7 @@ local update = function(time)
test.update(time) test.update(time)
for joystick_index, joystick in ipairs(joysticks) do for joystick_index, joystick in ipairs(joysticks) do
if joystick_index >= 8 then if joystick_index > 8 then
break break
end end
local lx = joystick:getGamepadAxis("leftx") local lx = joystick:getGamepadAxis("leftx")
@ -51,7 +51,7 @@ local update = function(time)
local rightshoulder = joystick:isGamepadDown("rightshoulder") local rightshoulder = joystick:isGamepadDown("rightshoulder")
local start = joystick:isGamepadDown("start") local start = joystick:isGamepadDown("start")
--print("start", i, start) --print("start", i, start)
test.update_joystick(joystick_index, test.update_joystick(joystick_index - 1,
lx, ly, rx, ry, tl, tr, lx, ly, rx, ry, tl, tr,
up, down, left, right, up, down, left, right,
a, b, x, y, a, b, x, y,

15
minecraft/gen/intkeys.py Normal file
View File

@ -0,0 +1,15 @@
import sys
import struct
paths = sys.argv[1:]
def main(path):
with open(path, 'rb') as f:
buf = memoryview(f.read())
for i in range(len(buf) // 8):
global_index, = struct.unpack("<i", buf[i*8:i*8+4])
print(global_index)
for path in paths:
main(path)

View File

@ -67,7 +67,7 @@ def neighbor_exists(level_table, chunk_x, chunk_z, nx, ny, nz):
def block_neighbors(level_table, chunk_x, chunk_z, block_index): def block_neighbors(level_table, chunk_x, chunk_z, block_index):
block_id = level_table[(chunk_x, chunk_z)].blocks[block_index] block_id = level_table[(chunk_x, chunk_z)].blocks[block_index]
if block_id == data.BlockID.AIR: if block_id == data.BlockID.AIR or block_id == data.BlockID.BEDROCK:
return return
block_data = level_table[(chunk_x, chunk_z)].data[block_index // 2] block_data = level_table[(chunk_x, chunk_z)].data[block_index // 2]
@ -213,9 +213,45 @@ all_paths = [
"/home/bilbo/Love2DWorld/region/r.-1.0.mcr", "/home/bilbo/Love2DWorld/region/r.-1.0.mcr",
] ]
g_stride = 512 * 2
def from_global_index(i):
x, y, z = i % g_stride, i // (g_stride * g_stride), (i // g_stride) % g_stride
if x >= 512:
x = -x + 511
if z >= 512:
z = -z + 511
assert x < 512 and z < 512
return x, y, z
def to_global_index(x,y,z):
assert x >= -512 and x < 512, (x, y, z)
assert y >= 0 and y < 128, (x, y, z)
assert z >= -512 and z < 512, (x, y, z)
original_coordinate = (x, y, z)
if x < 0:
x = -(x - 511)
if z < 0:
z = -(z - 511)
assert z >= 0 and x >= 0
value = x + z * g_stride + y * g_stride * g_stride
assert from_global_index(value) == original_coordinate, (original_coordinate, value)
return value
def dump_blocks(blocks):
with open(f"{data_path}.dump", "wb") as f:
for block in blocks:
center_position, block_id, block_data, normal_indices = block
global_index = to_global_index(*center_position)
buf = struct.pack("<iBBBB", global_index, block_id, block_data, 0, 0)
assert(len(buf) == 8)
f.write(buf)
def main2(level_table, level_table_keys): def main2(level_table, level_table_keys):
blocks = devoxelize_region(level_table, level_table_keys) blocks = devoxelize_region(level_table, level_table_keys)
blocks = list(blocks)
dump_blocks(blocks)
build_block_instances(blocks) build_block_instances(blocks)
print("blocks_length:", len(blocks))
def main(mcr_path, data_path): def main(mcr_path, data_path):
assert mcr_path in all_paths assert mcr_path in all_paths

View File

@ -9,3 +9,6 @@ $PYTHON mc.py ~/Love2DWorld/region/r.-1.0.mcr ../region.-1.0 &
wait wait
cat ../region*.lights.vtx > ../global.lights.vtx cat ../region*.lights.vtx > ../global.lights.vtx
cat ../region*.dump > ../global.dump
$PYTHON intkeys.py ../global.dump | ~/nbperf/nbperf -I -a bpz -c 1.24 -m map.txt > ../../src/inthash.c

BIN
minecraft/global.dump Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -8,6 +8,7 @@ uniform float Linear;
uniform float Quadratic; uniform float Quadratic;
uniform vec3 Eye; uniform vec3 Eye;
uniform vec3 MousePosition; uniform vec3 MousePosition;
uniform vec3 MousePosition2;
layout (location = 0) out vec4 Color; layout (location = 0) out vec4 Color;
@ -38,8 +39,12 @@ void main()
} }
vec3 light_direction = normalize(Eye.xyz - position.xyz); vec3 light_direction = normalize(Eye.xyz - position.xyz);
float diffuse = max(dot(normal.xyz, light_direction), 0.0); float diffuse = max(dot(normal.xyz, light_direction), 0.0);
if (floor(MousePosition + 0.5) == floor(position.xyz + 0.5)) //if (floor(MousePosition + 0.5) == floor(position.xyz + 0.5))
diffuse = 1.5; //diffuse = 1.5;
//if (round(MousePosition2) == round(position.xyz))
//color.xyz = vec3(0.75, 1.25, 0.75);
out_color = color.xyz * diffuse; out_color = color.xyz * diffuse;
Color = vec4(out_color, 1.0); Color = vec4(out_color, 1.0);
} }

View File

@ -2,6 +2,7 @@
in VS_OUT { in VS_OUT {
vec3 Position; // world coordinates vec3 Position; // world coordinates
vec3 BlockPosition;
vec3 Normal; vec3 Normal;
vec2 Texture; vec2 Texture;
flat int BlockID; flat int BlockID;
@ -13,6 +14,8 @@ layout (location = 1) out vec3 Normal;
layout (location = 2) out vec3 Color; layout (location = 2) out vec3 Color;
uniform sampler2D TerrainSampler; uniform sampler2D TerrainSampler;
uniform vec3 MousePosition;
uniform vec3 MousePosition2;
layout (std140) uniform TextureID layout (std140) uniform TextureID
{ {
@ -61,5 +64,11 @@ void main()
Position = fs_in.Position.xzy; Position = fs_in.Position.xzy;
Normal = normalize(fs_in.Normal.xzy); Normal = normalize(fs_in.Normal.xzy);
if (length(fs_in.BlockPosition - floor(MousePosition.xzy)) < 1)
Color = vec3(0, 1, 0);
else if (length(fs_in.BlockPosition - floor(MousePosition.xzy)) <= 1)
Color = vec3(0, 0.5, 0);
else
Color = texture_color.xyz; Color = texture_color.xyz;
} }

View File

@ -11,6 +11,7 @@ in float Data;
out VS_OUT { out VS_OUT {
vec3 Position; vec3 Position;
vec3 BlockPosition;
vec3 Normal; vec3 Normal;
vec2 Texture; vec2 Texture;
flat int BlockID; flat int BlockID;
@ -24,6 +25,7 @@ void main()
vec3 position = Position + BlockPosition; // world coordinates vec3 position = Position + BlockPosition; // world coordinates
vs_out.Position = position; vs_out.Position = position;
vs_out.BlockPosition = BlockPosition;
vs_out.Normal = Normal; vs_out.Normal = Normal;
vs_out.Texture = Texture; vs_out.Texture = Texture;
vs_out.BlockID = int(BlockID); vs_out.BlockID = int(BlockID);

70
src/file.c Normal file
View File

@ -0,0 +1,70 @@
#include <stddef.h>
#include <string.h>
#include <assert.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include "file.h"
char const * g_source_path = NULL;
int g_source_path_length = 0;
char const * join_path(char * buf, const char * filename)
{
if (filename[0] == '/')
return filename;
int filename_length = strlen(filename);
assert(filename_length + g_source_path_length + 2 < 1024);
memcpy(buf, g_source_path, g_source_path_length);
buf[g_source_path_length] = '/';
memcpy(&buf[g_source_path_length + 1], filename, filename_length);
buf[g_source_path_length + 1 + filename_length] = 0;
return buf;
}
void * read_file(const char * r_filename, int * out_size)
{
char tmp[1024];
char const * filename = join_path(tmp, r_filename);
FILE * f = fopen(filename, "rb");
if (f == NULL) {
fprintf(stderr, "fopen(%s): %s\n", filename, strerror(errno));
return NULL;
}
int fseek_end_ret = fseek(f, 0, SEEK_END);
if (fseek_end_ret < 0) {
fprintf(stderr, "fseek(%s, SEEK_END): %s\n", filename, strerror(errno));
return NULL;
}
long size = ftell(f);
if (size < 0) {
fprintf(stderr, "ftell(%s): %s\n", filename, strerror(errno));
return NULL;
}
int fseek_set_ret = fseek(f, 0, SEEK_SET);
if (fseek_set_ret < 0) {
fprintf(stderr, "lseek(%s, SEEK_SET): %s\n", filename, strerror(errno));
return NULL;
}
rewind(f);
void * buf = malloc(size);
size_t read_size = fread(buf, 1, size, f);
if (read_size != size) {
fprintf(stderr, "fread(%s): %s\n", filename, strerror(errno));
return NULL;
}
*out_size = size;
return buf;
}

View File

@ -5,6 +5,7 @@
#include "directxmath/directxmath.h" #include "directxmath/directxmath.h"
#include "glad/gl.h" #include "glad/gl.h"
#include "opengl.h" #include "opengl.h"
#include "file.h"
#include "font.h" #include "font.h"
#include "window.h" #include "window.h"

59655
src/hash.c Normal file

File diff suppressed because it is too large Load Diff

59655
src/inthash.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -6,68 +6,7 @@
#include "glad/gl.h" #include "glad/gl.h"
#include "opengl.h" #include "opengl.h"
#include "file.h"
char const * g_source_path = NULL;
int g_source_path_length = 0;
char const * join_path(char * buf, const char * filename)
{
if (filename[0] == '/')
return filename;
int filename_length = strlen(filename);
assert(filename_length + g_source_path_length + 2 < 1024);
memcpy(buf, g_source_path, g_source_path_length);
buf[g_source_path_length] = '/';
memcpy(&buf[g_source_path_length + 1], filename, filename_length);
buf[g_source_path_length + 1 + filename_length] = 0;
return buf;
}
void * read_file(const char * r_filename, int * out_size)
{
char tmp[1024];
char const * filename = join_path(tmp, r_filename);
FILE * f = fopen(filename, "rb");
if (f == NULL) {
fprintf(stderr, "fopen(%s): %s\n", filename, strerror(errno));
return NULL;
}
int fseek_end_ret = fseek(f, 0, SEEK_END);
if (fseek_end_ret < 0) {
fprintf(stderr, "fseek(%s, SEEK_END): %s\n", filename, strerror(errno));
return NULL;
}
long size = ftell(f);
if (size < 0) {
fprintf(stderr, "ftell(%s): %s\n", filename, strerror(errno));
return NULL;
}
int fseek_set_ret = fseek(f, 0, SEEK_SET);
if (fseek_set_ret < 0) {
fprintf(stderr, "lseek(%s, SEEK_SET): %s\n", filename, strerror(errno));
return NULL;
}
rewind(f);
void * buf = malloc(size);
size_t read_size = fread(buf, 1, size, f);
if (read_size != size) {
fprintf(stderr, "fread(%s): %s\n", filename, strerror(errno));
return NULL;
}
*out_size = size;
return buf;
}
unsigned int compile(const char * vertex_source, unsigned int compile(const char * vertex_source,
int vertex_source_size, int vertex_source_size,

View File

@ -9,6 +9,8 @@
#include "font.h" #include "font.h"
#include "window.h" #include "window.h"
#include "bresenham.h" #include "bresenham.h"
#include "file.h"
#include "world.h"
#include "data.inc" #include "data.inc"
@ -24,6 +26,7 @@ struct test_location {
struct { struct {
unsigned int transform; unsigned int transform;
unsigned int terrain_sampler; unsigned int terrain_sampler;
unsigned int mouse_position;
unsigned int texture_id; unsigned int texture_id;
} uniform; } uniform;
@ -67,6 +70,7 @@ struct lighting_location {
unsigned int linear; unsigned int linear;
unsigned int eye; unsigned int eye;
unsigned int mouse_position; unsigned int mouse_position;
unsigned int mouse_position2;
unsigned int lights; unsigned int lights;
} uniform; } uniform;
@ -116,6 +120,7 @@ static unsigned int quad_index_buffer = -1;
static XMFLOAT3 mouse_position; static XMFLOAT3 mouse_position;
static bool mouse_position_sample = true; static bool mouse_position_sample = true;
static XMVECTOR mouse_ray_position;
static float current_time; static float current_time;
static float last_frame_time; static float last_frame_time;
@ -161,10 +166,12 @@ void load_test_program()
test_location.uniform.transform = glGetUniformLocation(program, "Transform"); test_location.uniform.transform = glGetUniformLocation(program, "Transform");
test_location.uniform.terrain_sampler = glGetUniformLocation(program, "TerrainSampler"); test_location.uniform.terrain_sampler = glGetUniformLocation(program, "TerrainSampler");
test_location.uniform.texture_id = glGetUniformBlockIndex(program, "TextureID"); test_location.uniform.texture_id = glGetUniformBlockIndex(program, "TextureID");
printf(" uniforms:\n transform %u\n terrain_sampler %u\n texture_id %u\n", test_location.uniform.mouse_position = glGetUniformLocation(program, "MousePosition");
printf(" uniforms:\n transform %u\n terrain_sampler %u\n texture_id %u\n mouse_position %u\n",
test_location.uniform.transform, test_location.uniform.transform,
test_location.uniform.terrain_sampler, test_location.uniform.terrain_sampler,
test_location.uniform.texture_id); test_location.uniform.texture_id,
test_location.uniform.mouse_position);
test_location.binding.texture_id = 0; test_location.binding.texture_id = 0;
glUniformBlockBinding(program, test_location.uniform.texture_id, test_location.binding.texture_id); glUniformBlockBinding(program, test_location.uniform.texture_id, test_location.binding.texture_id);
@ -199,6 +206,7 @@ void load_lighting_program()
lighting_location.uniform.linear = glGetUniformLocation(program, "Linear"); lighting_location.uniform.linear = glGetUniformLocation(program, "Linear");
lighting_location.uniform.eye = glGetUniformLocation(program, "Eye"); lighting_location.uniform.eye = glGetUniformLocation(program, "Eye");
lighting_location.uniform.mouse_position = glGetUniformLocation(program, "MousePosition"); lighting_location.uniform.mouse_position = glGetUniformLocation(program, "MousePosition");
lighting_location.uniform.mouse_position2 = glGetUniformLocation(program, "MousePosition2");
lighting_location.uniform.lights = glGetUniformBlockIndex(program, "Lights"); lighting_location.uniform.lights = glGetUniformBlockIndex(program, "Lights");
fprintf(stderr, "lighting program:\n"); fprintf(stderr, "lighting program:\n");
@ -480,15 +488,17 @@ static int line_point_ix = 0;
void append_line_point(int x, int y, int z) void append_line_point(int x, int y, int z)
{ {
if (line_point_ix >= 128) if (line_point_ix == 1)
return; return;
printf("%d %d %d\n", x, y, z); global_entry * const entry = world_lookup(x, y, z);
if (entry != NULL) {
line_points[line_point_ix].x = x; line_points[line_point_ix].x = x;
line_points[line_point_ix].y = y; line_points[line_point_ix].y = y;
line_points[line_point_ix].z = z; line_points[line_point_ix].z = z;
line_point_ix += 1; line_point_ix += 1;
} }
}
void load_line_program() void load_line_program()
{ {
@ -636,6 +646,12 @@ void load(const char * source_path)
load_line_vertex_attributes(); load_line_vertex_attributes();
glGenBuffers(1, &line_instance_buffer); glGenBuffers(1, &line_instance_buffer);
//////////////////////////////////////////////////////////////////////
// world
//////////////////////////////////////////////////////////////////////
load_world();
} }
float _ry = 0.0; float _ry = 0.0;
@ -806,23 +822,33 @@ void draw_hud()
XMVECTOR position = XMLoadFloat3(&mouse_position); XMVECTOR position = XMLoadFloat3(&mouse_position);
y = draw_vector(ter_best, buf, y, "mouse_position", position); y = draw_vector(ter_best, buf, y, "mouse_position", position);
y = draw_vector(ter_best, buf, y, "mouse_ray_position", mouse_ray_position);
labeled_value<float>(buf, "frame_rate_avg: ", "%.2f", 1.0f / update_average(current_time - last_frame_time)); labeled_value<float>(buf, "frame_rate_avg: ", "%.2f", 1.0f / update_average(current_time - last_frame_time));
font::draw_string(ter_best, buf, 10, y); font::draw_string(ter_best, buf, 10, y);
y += ter_best.desc->glyph_height; y += ter_best.desc->glyph_height;
} }
XMMATRIX current_view_projection() static inline XMMATRIX current_projection()
{ {
XMVECTOR at = XMVectorAdd(view_state.eye, view_state.direction);
XMMATRIX view = XMMatrixLookAtRH(view_state.eye, at, view_state.up);
float fov_angle_y = XMConvertToRadians(45 * view_state.fov); float fov_angle_y = XMConvertToRadians(45 * view_state.fov);
float aspect_ratio = g_window_width / g_window_height; float aspect_ratio = g_window_width / g_window_height;
float near_z = 1.0; float near_z = 1.0;
float far_z = 0.1; float far_z = 0.1;
XMMATRIX projection = XMMatrixPerspectiveFovRH(fov_angle_y, aspect_ratio, near_z, far_z); XMMATRIX projection = XMMatrixPerspectiveFovRH(fov_angle_y, aspect_ratio, near_z, far_z);
XMMATRIX transform = view * projection; return projection;
return transform; }
static inline XMMATRIX current_view()
{
XMVECTOR at = XMVectorAdd(view_state.eye, view_state.direction);
XMMATRIX view = XMMatrixLookAtRH(view_state.eye, at, view_state.up);
return view;
}
static inline XMMATRIX current_view_projection()
{
return current_view() * current_projection();
} }
void draw_minecraft() void draw_minecraft()
@ -849,6 +875,9 @@ void draw_minecraft()
//glCullFace(GL_FRONT); //glCullFace(GL_FRONT);
//glFrontFace(GL_CCW); //glFrontFace(GL_CCW);
XMFLOAT3 position2 = {(float)line_points[0].x, (float)line_points[0].z, (float)line_points[0].y};
glUniform3fv(test_location.uniform.mouse_position, 1, (float*)&position2);
glBindVertexArray(vertex_array_object); glBindVertexArray(vertex_array_object);
glBindVertexBuffer(0, per_vertex_buffer, 0, per_vertex_size); glBindVertexBuffer(0, per_vertex_buffer, 0, per_vertex_size);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer);
@ -934,6 +963,11 @@ void draw_lighting()
XMStoreFloat3(&eye, view_state.eye); XMStoreFloat3(&eye, view_state.eye);
glUniform3fv(lighting_location.uniform.eye, 1, (float*)&eye); glUniform3fv(lighting_location.uniform.eye, 1, (float*)&eye);
glUniform3fv(lighting_location.uniform.mouse_position, 1, (float*)&mouse_position); glUniform3fv(lighting_location.uniform.mouse_position, 1, (float*)&mouse_position);
/*
printf("m0: %f %f %f\nm1: %f %f %f\n",
mouse_position.x, mouse_position.y, mouse_position.z,
position2.x, position2.y, position2.z);
*/
glBindBufferBase(GL_UNIFORM_BUFFER, lighting_location.binding.lights, light_uniform_buffer); glBindBufferBase(GL_UNIFORM_BUFFER, lighting_location.binding.lights, light_uniform_buffer);
@ -952,7 +986,7 @@ void draw_line()
glBlendFunc(GL_ONE, GL_ZERO); glBlendFunc(GL_ONE, GL_ZERO);
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_GREATER); glDepthFunc(GL_ALWAYS);
XMMATRIX transform = current_view_projection(); XMMATRIX transform = current_view_projection();
glUniformMatrix4fv(line_location.uniform.transform, 1, false, (float *)&transform); glUniformMatrix4fv(line_location.uniform.transform, 1, false, (float *)&transform);
@ -971,7 +1005,10 @@ void draw_line()
int element_count = 6 * popcount(configuration); int element_count = 6 * popcount(configuration);
const void * indices = (void *)((ptrdiff_t)index_buffer_configuration_offsets[configuration]); // index into configuration.idx const void * indices = (void *)((ptrdiff_t)index_buffer_configuration_offsets[configuration]); // index into configuration.idx
int instance_count = line_point_ix; int instance_count = line_point_ix;
glDrawElementsInstanced(GL_TRIANGLES, element_count, GL_UNSIGNED_BYTE, indices, instance_count); int base_instance = 0;
if (instance_count - base_instance <= 0)
return;
glDrawElementsInstancedBaseInstance(GL_TRIANGLES, element_count, GL_UNSIGNED_BYTE, indices, instance_count - base_instance, base_instance);
} }
int clamp(int n, int high) int clamp(int n, int high)
@ -1000,6 +1037,42 @@ void update_mouse(int x, int y)
GL_RGB, GL_RGB,
GL_FLOAT, GL_FLOAT,
(void*)&mouse_position); (void*)&mouse_position);
{
float mx = (2.0f * (float)x) / geometry_buffer_pnc.width - 1.0f;
float my = 1.0f - (2.0f * (float)y) / geometry_buffer_pnc.height;
/*
XMVECTOR mouse_world = XMVector3Transform(mouse_clip, inverse);
XMVECTOR ray = XMVector3Normalize(mouse_world - view_state.eye);
mouse_ray_position = ray;
XMVECTOR ray_start = view_state.eye;
XMVECTOR ray_end = ray_start + ray * 20.0f;
*/
XMVECTOR mouse_clip = XMVectorSet(mx, my, -1, 0);
XMMATRIX projection_inverse = XMMatrixInverse(NULL, current_projection());
XMMATRIX view_inverse = XMMatrixInverse(NULL, current_view());
XMVECTOR mouse_view = XMVector3Transform(mouse_clip, projection_inverse);
mouse_ray_position = mouse_view;
mouse_view = XMVectorSetZ(mouse_view, -1);
XMVECTOR ray = XMVector3Normalize(XMVector3TransformNormal(mouse_view, view_inverse));
XMVECTOR ray_start = view_state.eye;
XMVECTOR ray_end = ray_start + ray * 20.0f;
line_state.point[0].x = roundf(XMVectorGetX(ray_start));
line_state.point[0].z = roundf(XMVectorGetY(ray_start));
line_state.point[0].y = roundf(XMVectorGetZ(ray_start));
line_state.point[1].x = roundf(XMVectorGetX(ray_end));
line_state.point[1].z = roundf(XMVectorGetY(ray_end));
line_state.point[1].y = roundf(XMVectorGetZ(ray_end));
load_line();
}
} }
void draw() void draw()
@ -1011,7 +1084,7 @@ void draw()
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
draw_minecraft(); draw_minecraft();
draw_line(); //draw_line();
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

52
src/world.c Normal file
View File

@ -0,0 +1,52 @@
#include <assert.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "inthash.h"
#include "file.h"
#include "world.h"
static global_entry_t * global_entry_table = NULL;
static int global_entry_table_length = 0;
void load_world()
{
int global_size;
global_entry_t * entry = (global_entry_t *)read_file("minecraft/global.dump", &global_size);
assert(entry != NULL);
global_entry_table_length = global_size / (sizeof (global_entry_t));
global_entry_table = calloc(global_entry_table_length, (sizeof (global_entry_t)));
for (int i = 0; i < global_entry_table_length; i++) {
uint32_t ix = inthash(entry[i].global_index);
assert(global_entry_table[ix].global_index == 0);
memcpy(&global_entry_table[ix], &entry[i], (sizeof (global_entry_t)));
}
free(entry);
}
static inline int global_index_from_xyz(int x, int y, int z)
{
const int g_stride = 512 * 2;
if (x < 0)
x = -(x - 511);
if (z < 0)
z = -(z - 511);
return x + z * g_stride + y * g_stride * g_stride;
}
global_entry_t * const world_lookup(int x, int y, int z)
{
int global_index = global_index_from_xyz(x, y, z);
int table_index = inthash(global_index);
if (table_index < 0 || table_index >= global_entry_table_length)
return NULL;
global_entry_t * const entry = &global_entry_table[table_index];
if (entry->global_index != global_index)
return NULL;
return entry;
}