diff --git a/src/main.jai b/src/main.jai index 87c7e6b..54bf1bc 100644 --- a/src/main.jai +++ b/src/main.jai @@ -3,6 +3,7 @@ #import "Input"; stbi :: #import "stb_image"; +#load "trile.jai"; #load "ui/ui.jai"; #load "editor/editor.jai"; #load "pipelines.jai"; @@ -17,7 +18,7 @@ last_frame_time : float64; delta\ _time : float64; V_MAJOR :: 0; -V_MINOR :: 2; +V_MINOR :: 3; state: struct { pass_action_clear : sg_pass_action; @@ -107,39 +108,9 @@ frame :: () { sgl_matrix_mode_projection(); sgl_ortho(0.0, sapp_widthf(), sapp_heightf(), 0.0, -1.0, +1.0); + draw_trile(); + tick_ui(); - - mvp := create_viewproj(*get_trile_editor_camera()); - vs_params : Vs_Params; - vs_params.mvp = mvp.floats; - - test : [4096]Position_Color; - - for x: 0..15 { - for y: 0..15 { - for z: 0..15 { - test[x * 16 * 16 + y * 16 + z].pos.x = x * (1.0 / 16.0); - test[x * 16 * 16 + y * 16 + z].pos.y = y * (1.0 / 16.0); - test[x * 16 * 16 + y * 16 + z].pos.z = z * (1.0 / 16.0); - test[x * 16 * 16 + y * 16 + z].pos.w = 1.0; - test[x * 16 * 16 + y * 16 + z].col = .{current_color.x, current_color.y, current_color.z, 1.0}; - - } - } - } - - sg_update_buffer(gPipelines.trixel.bind.vertex_buffers[1], *(sg_range.{ - ptr = test.data, - size = size_of(type_of(test)), - })); - - sg_begin_pass(*(sg_pass.{ action = state.pass_action_clear, swapchain = cast,force(sg_swapchain) sglue_swapchain() })); - sg_apply_pipeline(gPipelines.trixel.pipeline); - sg_apply_bindings(*gPipelines.trixel.bind); - sg_apply_uniforms(UB_vs_params, *(sg_range.{ ptr = *vs_params, size = size_of(type_of(vs_params)) })); - sg_draw(0, 36, 4096); - sg_end_pass(); - ui_pass(); input_per_frame_event_and_flag_update(); diff --git a/src/pipelines.jai b/src/pipelines.jai index 6853aac..fb6d13f 100644 --- a/src/pipelines.jai +++ b/src/pipelines.jai @@ -24,6 +24,7 @@ create_pipelines :: () { } TRIXEL_SIZE_HALF : float : 1.0/32.0; +TRIXEL_SIZE : float : 1.0/16.0; gArbtriMem : [100000*3*9]float; diff --git a/src/ray.jai b/src/ray.jai index 7133ac0..0a3b64f 100644 --- a/src/ray.jai +++ b/src/ray.jai @@ -5,44 +5,148 @@ Ray :: struct { get_mouse_ray :: (cam: *Camera) -> Ray { sw, sh := get_window_size(); - normalized_mouse_x := (2.0 * input_mouse_x) / sw - 1.0; - normalized_mouse_y := 1.0 - (2.0 * input_mouse_y) / sh; - ray_clip : Vector4 = .{normalized_mouse_x, normalized_mouse_y, -1.0, 1.0}; + x := (2.0 * input_mouse_x)/sw - 1.0; + y := 1.0 - (2.0 * input_mouse_y)/sh; + z := 1.0; - cam := get_trile_editor_camera(); - - viewmat := create_lookat(*cam); - projmat := create_perspective(*cam); - ray_eye := inverse(projmat) * ray_clip; - ray_eye.z = -1.0; - ray_eye.w = 0.0; + deviceCoords := Vector3.{x,y,z}; - ray_world_4d := (inverse(viewmat) * ray_eye); - ray_world : Vector3 = .{ray_world_4d.x, ray_world_4d.y, ray_world_4d.z}; - ray_world = normalize(ray_world); + matView := create_lookat(cam); + matProj := create_perspective(cam); + + nearPoint := unproject(.{deviceCoords.x, deviceCoords.y, 0.0}, matProj, matView); + farPoint := unproject(.{deviceCoords.x, deviceCoords.y, 1.0}, matProj, matView); + + direction := normalize(farPoint - nearPoint); return .{ - origin = cam.position, - direction = ray_world + cam.position, + direction }; + } + Collision_Cube :: struct { position : Vector3; size : Vector3; }; -does_ray_hit_cube :: (ray: Ray, cube: Collision_Cube) -> bool { - cube_min := cube.position; - cube_max := cube.position + cube.size; - tMin := (cube_min - ray.origin) / ray.direction; - tMax := (cube_max - ray.origin) / ray.direction; - t1 := min(tMin, tMax); - t2 := max(tMin, tMax); - - tNear := max(max(t1.x, t1.y), t1.z); - tFar := min(min(t2.x, t2.y), t2.z); - - return tNear > tFar; +Ray_Collision :: struct { + distance : float = 99999; + hit : bool = false; +} + +// Ported over from Raylib. +does_ray_hit_cube :: (og_ray: Ray, cube: Collision_Cube) -> Ray_Collision { + ray := og_ray; + collision : Ray_Collision; + bmin := cube.position; + bmax := cube.position + cube.size; + + insideBox := (ray.origin.x > bmin.x) && (ray.origin.x < bmax.x) && + (ray.origin.y > bmin.y) && (ray.origin.y < bmax.y) && + (ray.origin.z > bmin.z) && (ray.origin.z < bmax.z); + + t : [11] float; + + t[8] = 1.0/ray.direction.x; + t[9] = 1.0/ray.direction.y; + t[10] = 1.0/ray.direction.z; + + t[0] = (bmin.x - ray.origin.x) * t[8]; + t[1] = (bmax.x - ray.origin.x) * t[8]; + t[2] = (bmin.y - ray.origin.y) * t[9]; + t[3] = (bmax.y - ray.origin.y) * t[9]; + t[4] = (bmin.z - ray.origin.z) * t[10]; + t[5] = (bmax.z - ray.origin.z) * t[10]; + t[6] = max(max(min(t[0], t[1]), min(t[2], t[3])), min(t[4], t[5])); + t[7] = min(min(max(t[0], t[1]), max(t[2], t[3])), max(t[4], t[5])); + + collision.hit = !((t[7] < 0) || (t[6] > t[7])); + collision.distance = t[6]; + + return collision; +} + +unproject :: (source: Vector3, projection: Matrix4, view: Matrix4) -> Vector3 { + result : Vector3; + + // Calculate unprojected matrix (multiply view matrix by projection matrix) and invert it + matViewProj := Matrix4.{ // MatrixMultiply(view, projection); + view.floats[0]*projection.floats[0 ]+ view.floats[1]*projection.floats[4 ]+ view.floats[2]*projection.floats[8 ]+ view.floats[3]*projection.floats[12], + view.floats[0]*projection.floats[1 ]+ view.floats[1]*projection.floats[5 ]+ view.floats[2]*projection.floats[9 ]+ view.floats[3]*projection.floats[13], + view.floats[0]*projection.floats[2 ]+ view.floats[1]*projection.floats[6 ]+ view.floats[2]*projection.floats[10 ]+ view.floats[3]*projection.floats[14], + view.floats[0]*projection.floats[3 ]+ view.floats[1]*projection.floats[7 ]+ view.floats[2]*projection.floats[11 ]+ view.floats[3]*projection.floats[15], + view.floats[4]*projection.floats[0 ]+ view.floats[5]*projection.floats[4 ]+ view.floats[6]*projection.floats[8 ]+ view.floats[7]*projection.floats[12], + view.floats[4]*projection.floats[1 ]+ view.floats[5]*projection.floats[5 ]+ view.floats[6]*projection.floats[9 ]+ view.floats[7]*projection.floats[13], + view.floats[4]*projection.floats[2 ]+ view.floats[5]*projection.floats[6 ]+ view.floats[6]*projection.floats[10 ]+ view.floats[7]*projection.floats[14], + view.floats[4]*projection.floats[3 ]+ view.floats[5]*projection.floats[7 ]+ view.floats[6]*projection.floats[11 ]+ view.floats[7]*projection.floats[15], + view.floats[8]*projection.floats[0 ]+ view.floats[9]*projection.floats[4 ]+ view.floats[10]*projection.floats[8 ]+ view.floats[11]*projection.floats[12], + view.floats[8]*projection.floats[1 ]+ view.floats[9]*projection.floats[5 ]+ view.floats[10]*projection.floats[9 ]+ view.floats[11]*projection.floats[13], + view.floats[8]*projection.floats[2 ]+ view.floats[9]*projection.floats[6 ]+ view.floats[10]*projection.floats[10 ]+ view.floats[11]*projection.floats[14], + view.floats[8]*projection.floats[3 ]+ view.floats[9]*projection.floats[7 ]+ view.floats[10]*projection.floats[11 ]+ view.floats[11]*projection.floats[15], + view.floats[12]*projection.floats[0 ]+ view.floats[13]*projection.floats[4 ]+ view.floats[14]*projection.floats[8 ]+ view.floats[15]*projection.floats[12], + view.floats[12]*projection.floats[1 ]+ view.floats[13]*projection.floats[5 ]+ view.floats[14]*projection.floats[9 ]+ view.floats[15]*projection.floats[13], + view.floats[12]*projection.floats[2 ]+ view.floats[13]*projection.floats[6 ]+ view.floats[14]*projection.floats[10 ]+ view.floats[15]*projection.floats[14], + view.floats[12]*projection.floats[3 ]+ view.floats[13]*projection.floats[7 ]+ view.floats[14]*projection.floats[11 ]+ view.floats[15]*projection.floats[15 ]}; + + // Calculate inverted matrix -> MatrixInvert(matViewProj); + // Cache the matrix values (speed optimization) + a00 := matViewProj.floats[0]; a01 := matViewProj.floats[1]; a02 := matViewProj.floats[2]; a03 := matViewProj.floats[3]; + a10 := matViewProj.floats[4]; a11 := matViewProj.floats[5]; a12 := matViewProj.floats[6]; a13 := matViewProj.floats[7]; + a20 := matViewProj.floats[8]; a21 := matViewProj.floats[9]; a22 := matViewProj.floats[10]; a23 := matViewProj.floats[11]; + a30 := matViewProj.floats[12]; a31 := matViewProj.floats[13]; a32 := matViewProj.floats[14]; a33 := matViewProj.floats[15]; + + b00 := a00*a11 - a01*a10; + b01 := a00*a12 - a02*a10; + b02 := a00*a13 - a03*a10; + b03 := a01*a12 - a02*a11; + b04 := a01*a13 - a03*a11; + b05 := a02*a13 - a03*a12; + b06 := a20*a31 - a21*a30; + b07 := a20*a32 - a22*a30; + b08 := a20*a33 - a23*a30; + b09 := a21*a32 - a22*a31; + b10 := a21*a33 - a23*a31; + b11 := a22*a33 - a23*a32; + + // Calculate the invert determinant (inlined to avoid double-caching) + invDet : float = 1.0/(b00*b11 - b01*b10 + b02*b09 + b03*b08 - b04*b07 + b05*b06); + + matViewProjInv := Matrix4.{ + (a11*b11 - a12*b10 + a13*b09)*invDet, + (-a01*b11 + a02*b10 - a03*b09)*invDet, + (a31*b05 - a32*b04 + a33*b03)*invDet, + (-a21*b05 + a22*b04 - a23*b03)*invDet, + (-a10*b11 + a12*b08 - a13*b07)*invDet, + (a00*b11 - a02*b08 + a03*b07)*invDet, + (-a30*b05 + a32*b02 - a33*b01)*invDet, + (a20*b05 - a22*b02 + a23*b01)*invDet, + (a10*b10 - a11*b08 + a13*b06)*invDet, + (-a00*b10 + a01*b08 - a03*b06)*invDet, + (a30*b04 - a31*b02 + a33*b00)*invDet, + (-a20*b04 + a21*b02 - a23*b00)*invDet, + (-a10*b09 + a11*b07 - a12*b06)*invDet, + (a00*b09 - a01*b07 + a02*b06)*invDet, + (-a30*b03 + a31*b01 - a32*b00)*invDet, + (a20*b03 - a21*b01 + a22*b00)*invDet }; + + // Create quaternion from source point + quat: Quaternion = .{ source.x, source.y, source.z, 1.0 }; + + // Multiply quat point by unprojecte matrix + qtransformed : Quaternion = .{ // QuaternionTransform(quat, matViewProjInv) + matViewProjInv.floats[0]*quat.x + matViewProjInv.floats[4]*quat.y + matViewProjInv.floats[8]*quat.z + matViewProjInv.floats[12]*quat.w, + matViewProjInv.floats[1]*quat.x + matViewProjInv.floats[5]*quat.y + matViewProjInv.floats[9]*quat.z + matViewProjInv.floats[13]*quat.w, + matViewProjInv.floats[2]*quat.x + matViewProjInv.floats[6]*quat.y + matViewProjInv.floats[10]*quat.z + matViewProjInv.floats[14]*quat.w, + matViewProjInv.floats[3]*quat.x + matViewProjInv.floats[7]*quat.y + matViewProjInv.floats[11]*quat.z + matViewProjInv.floats[15]*quat.w }; + + // Normalized world points in vectors + result.x = qtransformed.x/qtransformed.w; + result.y = qtransformed.y/qtransformed.w; + result.z = qtransformed.z/qtransformed.w; + + return result; } diff --git a/src/trile.jai b/src/trile.jai new file mode 100644 index 0000000..13957d8 --- /dev/null +++ b/src/trile.jai @@ -0,0 +1,15 @@ +Material :: struct { + roughness : float = 0.5; + metallic : float = 0; + emittance : float = 0; + color : Vector3 = .{0.5, 1.0, 0.5}; +} + +Trixel :: struct { + material : Material; + empty : bool = false; +}; + +Trile :: struct { + trixels : [16][16][16] Trixel; +};