last state of the prototype.

* Still has memory issue
* Was last using it to learn some PGA from Lengyel's books
This commit is contained in:
Edward R. Gonzalez 2024-04-08 01:35:53 -04:00
parent 2c84d93249
commit 7162c5a14d
19 changed files with 493 additions and 75 deletions

View File

@ -98,9 +98,9 @@ startup :: proc( prof : ^SpallProfiler, persistent_mem, frame_mem, transient_mem
push( policy_ptr, SlabSizeClass { 2 * Megabyte, 2 * Megabyte, alignment })
push( policy_ptr, SlabSizeClass { 4 * Megabyte, 4 * Megabyte, alignment })
push( policy_ptr, SlabSizeClass { 8 * Megabyte, 8 * Megabyte, alignment })
// push( policy_ptr, SlabSizeClass { 16 * Megabyte, 16 * Megabyte, alignment })
// push( policy_ptr, SlabSizeClass { 32 * Megabyte, 32 * Megabyte, alignment })
// push( policy_ptr, SlabSizeClass { 64 * Megabyte, 64 * Megabyte, alignment })
push( policy_ptr, SlabSizeClass { 16 * Megabyte, 16 * Megabyte, alignment })
push( policy_ptr, SlabSizeClass { 32 * Megabyte, 32 * Megabyte, alignment })
push( policy_ptr, SlabSizeClass { 64 * Megabyte, 64 * Megabyte, alignment })
// push( policy_ptr, SlabSizeClass { 128 * Megabyte, 128 * Megabyte, alignment })
// push( policy_ptr, SlabSizeClass { 256 * Megabyte, 256 * Megabyte, alignment })
// push( policy_ptr, SlabSizeClass { 512 * Megabyte, 512 * Megabyte, alignment })
@ -235,7 +235,6 @@ startup :: proc( prof : ^SpallProfiler, persistent_mem, frame_mem, transient_mem
// Make sure to cleanup transient before continuing...
// From here on, tarnsinet usage has to be done with care.
// For most cases, the frame allocator should be more than enough.
// free_all( transient_allocator() )
}
// For some reason odin's symbols conflict with native foreign symbols...
@ -316,7 +315,10 @@ tick :: proc( host_delta_time : f64, host_delta_ns : Duration ) -> b32
// Setup Frame Slab
{
alloc_error : AllocatorError
frame_slab, alloc_error = slab_init( & default_slab_policy, bucket_reserve_num = 0, allocator = frame_allocator(), dbg_name = Frame_Slab_DBG_Name )
frame_slab, alloc_error = slab_init( & default_slab_policy, bucket_reserve_num = 0,
allocator = frame_allocator(),
dbg_name = Frame_Slab_DBG_Name,
should_zero_buckets = true )
verify( alloc_error == .None, "Failed to allocate frame slab" )
}
@ -389,7 +391,6 @@ clean_frame :: proc()
free_all( frame_allocator() )
transient_clear_elapsed += frametime_delta32()
if transient_clear_elapsed >= transient_clear_time && ! transinet_clear_lock
{

View File

@ -9,14 +9,15 @@ import "base:intrinsics"
type_has_field :: intrinsics.type_has_field
type_elem_type :: intrinsics.type_elem_type
import "base:runtime"
Byte :: runtime.Byte
Kilobyte :: runtime.Kilobyte
Megabyte :: runtime.Megabyte
Gigabyte :: runtime.Gigabyte
Terabyte :: runtime.Terabyte
Petabyte :: runtime.Petabyte
Exabyte :: runtime.Exabyte
resize_non_zeroed :: runtime.non_zero_mem_resize
Byte :: runtime.Byte
Kilobyte :: runtime.Kilobyte
Megabyte :: runtime.Megabyte
Gigabyte :: runtime.Gigabyte
Terabyte :: runtime.Terabyte
Petabyte :: runtime.Petabyte
Exabyte :: runtime.Exabyte
resize_non_zeroed :: runtime.non_zero_mem_resize
SourceCodeLocation :: runtime.Source_Code_Location
import c "core:c/libc"
import "core:dynlib"
import "core:hash"
@ -31,6 +32,7 @@ import fmt_io "core:fmt"
str_fmt_buffer :: fmt_io.bprintf
str_to_file_ln :: fmt_io.fprintln
str_tmp_from_any :: fmt_io.tprint
import "core:math"
import "core:mem"
align_forward_int :: mem.align_forward_int
align_forward_uint :: mem.align_forward_uint
@ -57,8 +59,7 @@ import "core:mem"
tracking_allocator_init :: mem.tracking_allocator_init
import "core:mem/virtual"
VirtualProtectFlags :: virtual.Protect_Flags
import "core:odin"
SourceCodeLocation :: runtime.Source_Code_Location
// import "core:odin"
import "core:os"
FileFlag_Create :: os.O_CREATE
FileFlag_ReadWrite :: os.O_RDWR
@ -107,12 +108,32 @@ add :: proc {
add_range2,
}
bivec :: proc {
bivec_from_f32s,
vec3_to_bivec,
}
cm_to_pixels :: proc {
f32_cm_to_pixels,
vec2_cm_to_pixels,
range2_cm_to_pixels,
}
regress :: proc {
regress_bivec3,
}
cross :: proc {
cross_vec3,
}
dot :: proc {
dot_vec2,
dot_vec3,
dot_v3_unitv3,
dot_unitv3_vs,
}
draw_text :: proc {
draw_text_string,
draw_text_string_cached,
@ -126,6 +147,11 @@ get_bounds :: proc {
view_get_bounds,
}
inverse_mag :: proc {
inverse_mag_vec3,
inverse_mag_rotor3,
}
is_power_of_two :: proc {
is_power_of_two_u32,
is_power_of_two_uintptr,
@ -152,6 +178,25 @@ pop :: proc {
stack_allocator_pop,
}
pow :: proc{
math.pow_f16,
math.pow_f16le,
math.pow_f16be,
math.pow_f32,
math.pow_f32le,
math.pow_f32be,
math.pow_f64,
math.pow_f64le,
math.pow_f64be,
}
pow2 :: proc {
math.pow2_f16,
math.pow2_f32,
math.pow2_f64,
pow2_vec3,
}
pressed :: proc {
btn_pressed,
}
@ -161,12 +206,40 @@ push :: proc {
stack_allocator_push,
}
rotor3 :: proc {
rotor3_via_comps,
rotor3_via_s_bv,
rotor3_via_from_to,
}
released :: proc {
btn_released,
}
sqrt :: proc{
math.sqrt_f16,
math.sqrt_f16le,
math.sqrt_f16be,
math.sqrt_f32,
math.sqrt_f32le,
math.sqrt_f32be,
math.sqrt_f64,
math.sqrt_f64le,
math.sqrt_f64be,
}
inverse_sqrt :: proc {
inverse_sqrt_f32,
}
sub :: proc {
sub_point3,
sub_range2,
sub_bivec3,
}
to_quat128 :: proc {
rotor3_to_quat128,
}
to_rl_rect :: proc {
@ -182,6 +255,17 @@ to_string :: proc {
str_builder_to_string,
}
to_vec3 :: proc {
bivec3_to_vec3,
point3_to_vec3,
pointflat3_to_vec3,
unitvec3_to_vec3,
}
to_vec4 :: proc {
unitvec4_to_vec4,
}
to_writer :: proc {
str_builder_to_writer,
}
@ -190,3 +274,8 @@ ui_set_layout :: proc {
ui_style_set_layout,
ui_style_theme_set_layout,
}
wedge :: proc {
wedge_vec3,
wedge_bivec3,
}

View File

@ -20,7 +20,7 @@ import "core:slice"
HMapZPL_MapProc :: #type proc( $ Type : typeid, key : u64, value : Type )
HMapZPL_MapMutProc :: #type proc( $ Type : typeid, key : u64, value : ^ Type )
HMapZPL_CritialLoadScale :: 0.50
HMapZPL_CritialLoadScale :: 0.70
HMapZPL_HashToEntryRatio :: 1.50
HMapZPL_FindResult :: struct {

View File

@ -25,6 +25,7 @@ Pool :: struct {
PoolHeader :: struct {
backing : Allocator,
zero_bucket : b32,
block_size : uint,
bucket_capacity : uint,
alignment : uint,
@ -47,11 +48,12 @@ Pool_FreeBlock :: struct {
Pool_Check_Release_Object_Validity :: true
pool_init :: proc (
block_size : uint,
bucket_capacity : uint,
bucket_reserve_num : uint = 0,
alignment : uint = mem.DEFAULT_ALIGNMENT,
allocator : Allocator = context.allocator
should_zero_buckets : b32,
block_size : uint,
bucket_capacity : uint,
bucket_reserve_num : uint = 0,
alignment : uint = mem.DEFAULT_ALIGNMENT,
allocator : Allocator = context.allocator
) -> ( pool : Pool, alloc_error : AllocatorError )
{
header_size := align_forward_int( size_of(PoolHeader), int(alignment) )
@ -61,6 +63,7 @@ pool_init :: proc (
if alloc_error != .None do return
pool.header = cast( ^PoolHeader) raw_mem
pool.zero_bucket = should_zero_buckets
pool.backing = allocator
pool.block_size = align_forward_uint(block_size, alignment)
pool.bucket_capacity = bucket_capacity
@ -100,13 +103,21 @@ pool_allocate_buckets :: proc( pool : Pool, num_buckets : uint ) -> AllocatorErr
bucket_size := header_size + pool.bucket_capacity
to_allocate := cast(int) (bucket_size * num_buckets)
log(str_fmt_tmp("Allocating %d bytes for %d buckets with header_size %d bytes & bucket_size %d", to_allocate, num_buckets, header_size, bucket_size ))
// log(str_fmt_tmp("Allocating %d bytes for %d buckets with header_size %d bytes & bucket_size %d", to_allocate, num_buckets, header_size, bucket_size ))
bucket_memory : []byte
alloc_error : AllocatorError
pool_validate( pool )
bucket_memory, alloc_error := alloc_bytes_non_zeroed( to_allocate, int(pool.alignment), pool.backing )
if pool.zero_bucket {
bucket_memory, alloc_error = alloc_bytes( to_allocate, int(pool.alignment), pool.backing )
}
else {
bucket_memory, alloc_error = alloc_bytes_non_zeroed( to_allocate, int(pool.alignment), pool.backing )
}
pool_validate( pool )
log(str_fmt_tmp("Bucket memory size: %d bytes, without header: %d", len(bucket_memory), len(bucket_memory) - int(header_size)))
// log(str_fmt_tmp("Bucket memory size: %d bytes, without header: %d", len(bucket_memory), len(bucket_memory) - int(header_size)))
if alloc_error != .None {
return alloc_error
@ -119,13 +130,12 @@ pool_allocate_buckets :: proc( pool : Pool, num_buckets : uint ) -> AllocatorErr
bucket := cast( ^PoolBucket) next_bucket_ptr
bucket.blocks = memory_after_header(bucket)
bucket.next_block = 0
log( str_fmt_tmp("\tPool (%d) allocated bucket: %p start %p capacity: %d (raw: %d)",
pool.block_size,
raw_data(bucket_memory),
bucket.blocks,
pool.bucket_capacity / pool.block_size,
pool.bucket_capacity
))
// log( str_fmt_tmp("\tPool (%d) allocated bucket: %p start %p capacity: %d (raw: %d)",
// pool.block_size,
// raw_data(bucket_memory),
// bucket.blocks,
// pool.bucket_capacity / pool.block_size,
// pool.bucket_capacity ))
if pool.bucket_list.first == nil {
pool.bucket_list.first = bucket
@ -147,13 +157,11 @@ pool_grab :: proc( pool : Pool, zero_memory := false ) -> ( block : []byte, allo
if pool.current_bucket != nil {
verify( pool.current_bucket.blocks != nil, str_fmt_tmp("(corruption) current_bucket was wiped %p", pool.current_bucket) )
}
// profile(#procedure)
alloc_error = .None
// Check the free-list first for a block
// if pool.free_list_head != nil
if false
if pool.free_list_head != nil
{
head := & pool.free_list_head
@ -163,11 +171,10 @@ pool_grab :: proc( pool : Pool, zero_memory := false ) -> ( block : []byte, allo
pool.free_list_head = pool.free_list_head.next
block = byte_slice( cast([^]byte) last_free, int(pool.block_size) )
log( str_fmt_tmp("\tReturning free block: %p %d", raw_data(block), pool.block_size))
// log( str_fmt_tmp("\tReturning free block: %p %d", raw_data(block), pool.block_size))
if zero_memory {
slice.zero(block)
}
verify(false, "WE SHOULD NEVER BE HERE")
return
}
@ -192,13 +199,13 @@ pool_grab :: proc( pool : Pool, zero_memory := false ) -> ( block : []byte, allo
// if current_bucket.next != nil {
if pool.current_bucket.next != nil {
// current_bucket = current_bucket.next
log( str_fmt_tmp("\tBucket %p exhausted using %p", pool.current_bucket, pool.current_bucket.next))
// log( str_fmt_tmp("\tBucket %p exhausted using %p", pool.current_bucket, pool.current_bucket.next))
pool.current_bucket = pool.current_bucket.next
verify( pool.current_bucket.blocks != nil, "New current_bucket's blocks are null (new current_bucket is corrupted)" )
}
else
{
log( "\tAll previous buckets exhausted, allocating new bucket")
// log( "\tAll previous buckets exhausted, allocating new bucket")
alloc_error := pool_allocate_buckets( pool, 1 )
if alloc_error != .None {
ensure(false, "Failed to allocate bucket")
@ -221,11 +228,11 @@ pool_grab :: proc( pool : Pool, zero_memory := false ) -> ( block : []byte, allo
pool.current_bucket.next_block += pool.block_size
next = uintptr(pool.current_bucket.blocks) + uintptr(pool.current_bucket.next_block)
log( str_fmt_tmp("\tgrabbing block: %p from %p blocks left: %d", raw_data(block), pool.current_bucket.blocks, (end - next) / uintptr(pool.block_size) ))
// log( str_fmt_tmp("\tgrabbing block: %p from %p blocks left: %d", raw_data(block), pool.current_bucket.blocks, (end - next) / uintptr(pool.block_size) ))
if zero_memory {
slice.zero(block)
log( str_fmt_tmp("Zeroed memory - Range(%p to %p)", block_ptr, cast(rawptr) (uintptr(block_ptr) + uintptr(pool.block_size))))
// log( str_fmt_tmp("Zeroed memory - Range(%p to %p)", block_ptr, cast(rawptr) (uintptr(block_ptr) + uintptr(pool.block_size))))
}
return
}
@ -246,6 +253,7 @@ pool_release :: proc( self : Pool, block : []byte, loc := #caller_location )
// ll_push:
new_free_block := cast(^Pool_FreeBlock) raw_data(block)
(new_free_block ^) = {}
new_free_block.next = self.free_list_head
self.free_list_head = new_free_block

View File

@ -58,7 +58,7 @@ slab_allocator :: proc( slab : Slab ) -> ( allocator : Allocator ) {
return
}
slab_init :: proc( policy : ^SlabPolicy, bucket_reserve_num : uint = 0, allocator : Allocator, dbg_name : string = "" ) -> ( slab : Slab, alloc_error : AllocatorError )
slab_init :: proc( policy : ^SlabPolicy, bucket_reserve_num : uint = 0, allocator : Allocator, dbg_name : string = "", should_zero_buckets : b32 = false ) -> ( slab : Slab, alloc_error : AllocatorError )
{
header_size :: size_of( SlabHeader )
@ -69,17 +69,17 @@ slab_init :: proc( policy : ^SlabPolicy, bucket_reserve_num : uint = 0, allocato
slab.header = cast( ^SlabHeader) raw_mem
slab.backing = allocator
slab.dbg_name = dbg_name
alloc_error = slab_init_pools( slab, policy, bucket_reserve_num )
alloc_error = slab_init_pools( slab, policy, bucket_reserve_num, should_zero_buckets )
return
}
slab_init_pools :: proc ( using self : Slab, policy : ^SlabPolicy, bucket_reserve_num : uint = 0 ) -> AllocatorError
slab_init_pools :: proc ( using self : Slab, policy : ^SlabPolicy, bucket_reserve_num : uint = 0, should_zero_buckets : b32 ) -> AllocatorError
{
profile(#procedure)
for id in 0 ..< policy.idx {
using size_class := policy.items[id]
pool, alloc_error := pool_init( block_size, bucket_capacity, bucket_reserve_num, block_alignment, backing )
pool, alloc_error := pool_init( should_zero_buckets, block_size, bucket_capacity, bucket_reserve_num, block_alignment, backing )
if alloc_error != .None do return alloc_error
push( & self.pools, pool )
@ -136,7 +136,7 @@ slab_alloc :: proc( self : Slab,
ensure(false, "Bad block from pool")
return nil, alloc_error
}
log( str_fmt_tmp("%v: Retrieved block: %p %d", self.dbg_name, raw_data(block), len(block) ))
// log( str_fmt_tmp("%v: Retrieved block: %p %d", self.dbg_name, raw_data(block), len(block) ))
data = byte_slice(raw_data(block), size)
if zero_memory {
@ -195,7 +195,7 @@ slab_resize :: proc( using self : Slab,
new_data_ptr := memory_after(data)
new_data = byte_slice( raw_data(data), new_size )
// log( dump_stacktrace() )
log( str_fmt_tmp("%v: Resize via expanding block space allocation %p %d", dbg_name, new_data_ptr, int(new_size - old_size)))
// log( str_fmt_tmp("%v: Resize via expanding block space allocation %p %d", dbg_name, new_data_ptr, int(new_size - old_size)))
if zero_memory && new_size > old_size {
to_zero := byte_slice( new_data_ptr, int(new_size - old_size) )
@ -204,7 +204,7 @@ slab_resize :: proc( using self : Slab,
slice.zero( to_zero )
slab_validate_pools( self )
log( str_fmt_tmp("Zeroed memory - Range(%p to %p)", new_data_ptr, cast(rawptr) (uintptr(new_data_ptr) + uintptr(new_size - old_size))))
// log( str_fmt_tmp("Zeroed memory - Range(%p to %p)", new_data_ptr, cast(rawptr) (uintptr(new_data_ptr) + uintptr(new_size - old_size))))
}
return
}
@ -226,13 +226,13 @@ slab_resize :: proc( using self : Slab,
// TODO(Ed): Reapply this when safe.
if zero_memory {
slice.zero( new_block )
log( str_fmt_tmp("Zeroed memory - Range(%p to %p)", raw_data(new_block), cast(rawptr) (uintptr(raw_data(new_block)) + uintptr(new_size))))
// log( str_fmt_tmp("Zeroed memory - Range(%p to %p)", raw_data(new_block), cast(rawptr) (uintptr(raw_data(new_block)) + uintptr(new_size))))
}
// log( str_fmt_tmp("Resize via new block: %p %d (old : %p $d )", raw_data(new_block), len(new_block), raw_data(data), old_size ))
if raw_data(data) != raw_data(new_block) {
log( str_fmt_tmp("%v: Resize via new block, copying from old data block to new block: (%p %d), (%p %d)", dbg_name, raw_data(data), len(data), raw_data(new_block), len(new_block)))
// log( str_fmt_tmp("%v: Resize via new block, copying from old data block to new block: (%p %d), (%p %d)", dbg_name, raw_data(data), len(data), raw_data(new_block), len(new_block)))
copy_non_overlapping( raw_data(new_block), raw_data(data), int(old_size) )
pool_release( pool_old, data )
}

View File

@ -27,8 +27,9 @@ stack_pop :: proc( using stack : ^StackFixed( $ Type, $ Size ) ) {
}
stack_peek_ref :: proc( using stack : ^StackFixed( $ Type, $ Size ) ) -> ( ^Type) {
last := max( 0, idx - 1 ) if idx > 0 else 0
return & items[last]
last_idx := max( 0, idx - 1 ) if idx > 0 else 0
last := & items[last_idx]
return last
}
stack_peek :: proc ( using stack : ^StackFixed( $ Type, $ Size ) ) -> Type {

View File

@ -61,7 +61,8 @@ str_cache_init :: proc( /*allocator : Allocator*/ ) -> ( cache : StringCache ) {
cache.slab, alloc_error = slab_init( & policy, allocator = persistent_allocator(), dbg_name = dbg_name )
verify(alloc_error == .None, "Failed to initialize the string cache" )
cache.table, alloc_error = zpl_hmap_init_reserve( StringCached, persistent_slab_allocator(), 8 )
cache.table, alloc_error = zpl_hmap_init_reserve( StringCached, persistent_slab_allocator(), 4 * Kilobyte )
// cache.table, alloc_error = zpl_hmap_init_reserve( StringCached, persistent_slab_allocator(), 8 )
return
}

View File

@ -325,6 +325,9 @@ main :: proc()
{
spall.SCOPED_EVENT( & profiler.ctx, & profiler.buffer, "Host Tick" )
// Hot-Reload
sync_sectr_api( & sectr_api, & memory, & logger, & profiler )
running = sectr_api.tick( duration_seconds( delta_ns ), delta_ns )
sectr_api.clean_frame()
@ -332,9 +335,6 @@ main :: proc()
host_tick = time.tick_now()
free_all( arena_allocator( & state.transient))
// Hot-Reload
sync_sectr_api( & sectr_api, & memory, & logger, & profiler )
}
// Determine how the run_cyle completed, if it failed due to an error,

View File

@ -2,6 +2,8 @@
package sectr
import "core:math"
Axis2 :: enum i32 {
Invalid = -1,
X = 0,
@ -9,6 +11,32 @@ Axis2 :: enum i32 {
Count,
}
f32_Infinity :: 0x7F800000
f32_Min :: 0x00800000
// Note(Ed) : I don't see an intrinsict available anywhere for this. So I'll be using the Terathon non-sse impl
// Inverse Square Root
// C++ Source https://github.com/EricLengyel/Terathon-Math-Library/blob/main/TSMath.cpp#L191
inverse_sqrt_f32 :: proc "contextless" ( value : f32 ) -> f32
{
if ( value < f32_Min) {
return f32_Infinity
}
value_u32 := transmute(u32) value
initial_approx := 0x5F375A86 - (value_u32 >> 1)
refined_approx := transmute(f32) initial_approx
// NewtonRaphson method for getting better approximations of square roots
// Done twice for greater accuracy.
refined_approx = refined_approx * (1.5 - value * 0.5 * refined_approx * refined_approx )
refined_approx = refined_approx * (1.5 - value * 0.5 * refined_approx * refined_approx )
// refined_approx = (0.5 * refined_approx) * (3.0 - value * refined_approx * refined_approx)
// refined_approx = (0.5 * refined_approx) * (3.0 - value * refined_approx * refined_approx)
return refined_approx
}
is_power_of_two_u32 :: #force_inline proc "contextless" ( value : u32 ) -> b32
{
return value != 0 && ( value & ( value - 1 )) == 0
@ -28,13 +56,17 @@ mov_avg_exp_f64 := #force_inline proc "contextless" ( alpha, delta_interval, las
import "core:math/linalg"
Vec2 :: linalg.Vector2f32
Vec3 :: linalg.Vector3f32
Quat128 :: quaternion128
Matrix2 :: matrix [2, 2] f32
Vec2i :: [2]i32
Vec3i :: [3]i32
Vec2i :: [2]i32
Vec3i :: [3]i32
vec2i_to_vec2 :: #force_inline proc "contextless" (v : Vec2i) -> Vec2 {return transmute(Vec2) v}
vec3i_to_vec3 :: #force_inline proc "contextless" (v : Vec3i) -> Vec3 {return transmute(Vec3) v}
Range2 :: struct #raw_union{
//region Range2
Range2 :: struct #raw_union {
using min_max : struct {
min, max : Vec2
},
@ -51,6 +83,8 @@ Range2 :: struct #raw_union{
mat : matrix[2, 2] f32,
}
UnitRange2 :: distinct Range2
range2 :: #force_inline proc "contextless" ( a, b : Vec2 ) -> Range2 {
result := Range2 { pts = { a, b } }
return result
@ -78,3 +112,5 @@ equal_range2 :: #force_inline proc "contextless" ( a, b : Range2 ) -> b32 {
size_range2 :: #force_inline proc "contextless" ( value : Range2 ) -> Vec2 {
return { value.p1.x - value.p0.x, value.p0.y - value.p1.y }
}
//endregion Range2

View File

@ -1,3 +0,0 @@
package sectr

34
code/math_pga2.odin Normal file
View File

@ -0,0 +1,34 @@
package sectr
/*
Vec2 : 2D Vector 4D Extension (x, y, z : 0, w : 0)
Bivec2 : 2D Bivector
Transform2 : 3x3 Matrix where 3rd row is always (0, 0, 1)
*/
Vec2 :: [2]f32
Bivec2 :: distinct f32
Tansform2 :: matrix [3, 3] f32
UnitVec2 :: distinct Vec2
Rotor2 :: struct {
bv : Bivec2,
s : f32, // Scalar
}
rotor2_to_complex64 :: #force_inline proc( rotor : Rotor2 ) -> complex64 { return transmute(complex64) rotor; }
dot_vec2 :: proc "contextless" ( a, b : Vec2 ) -> (s : f32) {
x := a.x * b.x
y := a.y + b.y
s = x + y
return
}
/*
PointFlat2 : CGA: 2D flat point (x, y, z)
Line : PGA: 2D line (x, y, z)
*/
Point2 :: distinct Vec2
PointFlat2 :: distinct Vec3
Line2 :: distinct Vec3

225
code/math_pga3.odin Normal file
View File

@ -0,0 +1,225 @@
package sectr
/*
Vec3 : 3D Vector (x, y, z) (3x1) 4D Expression : (x, y, z, 0)
Bivec3 : 3D Bivector (yz, zx, xy) (3x1)
Trivec3 : 3D Trivector (xyz) (1x1)
Rotor3 : 3D Rotation Versor-Transform (4x1)
Motor3 : 3D Rotation & Translation Transform (4x2)
*/
Vec3 :: [3]f32
Vec4 :: [4]f32
Bivec3 :: struct #raw_union {
using _ : struct { yz, zx, xy : f32 },
using xyz : Vec3,
}
Trivec3 :: distinct f32
Rotor3 :: struct {
using bv : Bivec3,
s : f32, // Scalar
}
Shifter3 :: struct {
using bv : Bivec3,
s : f32, // Scalar
}
Motor3 :: struct {
rotor : Rotor3,
md : Shifter3,
}
UnitVec3 :: distinct Vec3
UnitVec4 :: distinct Vec4
UnitBivec3 :: distinct Bivec3
//region Vec3
complement_vec3 :: #force_inline proc "contextless" ( v : Vec3 ) -> Bivec3 {return transmute(Bivec3) v}
cross_vec3 :: proc "contextless" (a, b : Vec3) -> (v : Vec3) {
v = vec3( wedge(a, b))
return
}
dot_vec3 :: proc "contextless" ( a, b : Vec3 ) -> (s : f32) {
mult := a * b // array multiply
s = mult.x + mult.y + mult.z
return
}
inverse_mag_vec3 :: proc "contextless" (v : Vec3) -> (result : f32) {
square := pow2(v)
result = inverse_sqrt( square )
return
}
magnitude_vec3 :: proc "contextless" (v : Vec3) -> (mag : f32) {
square := pow2(v)
mag = sqrt(square)
return
}
normalize_vec3 :: proc "contextless" (v : Vec3) -> (unit_v : UnitVec3) {
unit_v = transmute(UnitVec3) (v * inverse_mag(v))
return
}
pow2_vec3 :: #force_inline proc "contextless" ( v : Vec3 ) -> (s : f32) { return dot(v, v) }
project_vec3 :: proc "contextless" ( a, b : Vec3 ) -> ( a_to_b : Vec3 ) {
return
}
reject_vec3 :: proc "contextless" ( a, b : Vec3 ) -> ( a_from_b : Vec3 ) {
return
}
project_v3_unitv3 :: proc "contextless" ( v : Vec3, u : UnitVec3 ) -> (v_to_u : Vec3) {
inner := dot(v, u)
v_to_u = (transmute(Vec3) u) * inner
return
}
project_unitv3_v3 :: #force_inline proc "contextless" (u : UnitVec3, v : Vec3) -> (u_to_v : Vec3) {
inner := dot(u, v)
u_to_v = v * inner
return
}
regress_vec3 :: proc "contextless" ( a, b : Vec3 ) -> f32 {
return a.x * b.y - a.y *
}
reject_v3_unitv3 :: proc "contextless" ( v : Vec3, u : UnitVec3 ) -> ( v_from_u : Vec3) {
inner := dot(v, u)
v_from_u = (v - (transmute(Vec3) u)) * inner
return
}
reject_unitv3_v3 :: proc "contextless" ( v : Vec3, u : UnitVec3 ) -> ( u_from_v : Vec3) {
inner := dot(u, v)
u_from_v = ((transmute(Vec3) u) - v) * inner
return
}
// Combines the deimensions that are present in a & b
wedge_vec3 :: proc "contextless" (a, b : Vec3) -> (bv : Bivec3) {
yzx_zxy := a.yzx * b.zxy
zxy_yzx := a.zxy * b.yzx
bv = transmute(Bivec3) (yzx_zxy - zxy_yzx)
return
}
//endregion Vec3
//region Bivec3
bivec_from_f32s :: #force_inline proc "contextless" (yz, zx, xy : f32) -> Bivec3 {return { xyz = {yz, zx, xy} }}
complement_bivec3 :: #force_inline proc "contextless" (b : Bivec3) -> Bivec3 {return b.xyz}
//region Operations isomoprhic to vectors
negate_bivec3 :: #force_inline proc "contextless" (b : Bivec3) -> Bivec3 {return transmute(Bivec3) -b.xyz}
add_bivec3 :: #force_inline proc "contextless" (a, b : Bivec3) -> Bivec3 {return transmute(Bivec3) (a.xyz + b.xyz)}
sub_bivec3 :: #force_inline proc "contextless" (a, b : Bivec3) -> Bivec3 {return transmute(Bivec3) (a.xyz - b.xyz)}
mul_bivec3 :: #force_inline proc "contextless" (a, b : Bivec3) -> Bivec3 {return transmute(Bivec3) (a.xyz * b.xyz)}
mul_bivec3_f32 :: #force_inline proc "contextless" (b : Bivec3, s : f32) -> Bivec3 {return transmute(Bivec3) (b.xyz * s)}
mul_f32_bivec3 :: #force_inline proc "contextless" (s : f32, b : Bivec3) -> Bivec3 {return transmute(Bivec3) (s * b.xyz)}
div_bivec3_f32 :: #force_inline proc "contextless" (b : Bivec3, s : f32) -> Bivec3 {return transmute(Bivec3) (b.xyz / s)}
inverse_mag_bivec3 :: #force_inline proc "contextless" (b : Bivec3) -> f32 {return transmute(Bivec3) inverse_mag_vec3(b.xyz)}
magnitude_bivec3 :: #force_inline proc "contextless" (b : Bivec3) -> f32 {return transmute(Bivec3) magnitude_vec3 (b.xyz)}
normalize_bivec3 :: #force_inline proc "contextless" (b : Bivec3) -> UnitBivec3 {return transmute(Bivec3) normalize_vec3 (b.xyz)}
squared_mag_bivec3 :: #force_inline proc "contextless" (b : Bivec3) -> f32 {return transmute(Bivec3) pow_2_vec3 (b.xyz)}
//endregion Operations isomoprhic to vectors
// anti-wedge (Combines dimensions that are absent from a & b)
regress_bivec3 :: #force_inline proc "contextless" ( a, b : Bivec3 ) -> Vec3 {return wedge(vec3(a), vec3(b))}
// regress_bivec3_v :: #force_inline proc "contextless" (b : Bivec3, v : Vec3) -> f32 {return regress(b.xyz, v)}
// regress_v3_bivec3 :: #force_inline proc "contextless" (v : Vec3, b : Bivec3) -> f32 {return regress(b.xyz, v)}
//endregion Bivec3
//region Rotor3
rotor3_via_comps :: proc "contextless" (yz, zx, xy, scalar : f32) -> (rotor : Rotor3) {
rotor = Rotor3 {bivec(yz, zx, xy), scalar}
return
}
rotor3_via_bv_s :: proc "contextless" (bv : Bivec3, scalar : f32) -> (rotor : Rotor3) {
rotor = Rotor3 {bv, scalar}
return
}
rotor3_via_from_to :: proc "contextless" ( from, to : Vec3 ) -> (rotor : Rotor3) {
scalar := 1 + dot( from, to )
return
}
inverse_mag_rotor3 :: proc "contextless" (rotor : Rotor3) -> (s : f32) {
return
}
magnitude_rotor3 :: proc "contextless" (rotor : Rotor3) -> (s : f32) {
return
}
squared_mag :: proc "contextless" (rotor : Rotor3) -> (s : f32) {
return
}
reverse_rotor3 :: proc "contextless" (rotor : Rotor3) -> (reversed : Rotor3) {
reversed = { negate(rotor.bv), rotor.s }
return
}
//endregion Rotor3
//region Flat Projective Geometry
Point3 :: distinct Vec3
PointFlat3 :: distinct Vec4
Line3 :: struct {
weight : Vec3,
bulk : Bivec3,
}
Plane3 :: distinct Vec4 // 4D Anti-vector
// aka: wedge operation for points
join_point3 :: proc "contextless" (p, q : Point3) -> (l : Line3) {
weight := sub(q, p)
bulk := wedge(to_vec3(p), to_vec3(q))
l = {weight, bulk}
return
}
join_pointflat3 :: proc "contextless" (p, q : PointFlat3) -> (l : Line3) {
weight := p.w * q - p * q.w
bulk := wedge(vec3(p), vec3(q))
l = {weight, bulk}
return
}
sub_point3 :: proc "contextless" (a, b : Point3) -> (v : Vec3) {
v = to_vec3(a) - to_vec3(b)
return
}
//endregion Flat Projective Geometry
//region Rational Trig
quadrance :: proc "contextless" (a, b : Point3) -> (q : f32) {
q = pow2( sub(a, b))
return
}
// Assumes the weight component is normalized.
spread :: proc "contextless" (l, m : Line3) -> (s : f32) {
s = dot(l.weight, m.weight)
return
}
//endregion Rational Trig

24
code/math_pga3_grime.odin Normal file
View File

@ -0,0 +1,24 @@
package sectr
// A dump of equivalent symbol generatioon (because the toolchain can't do it)
// Symbol alias tables are in grim.odin
vec3_to_bivec :: #force_inline proc "contextless" (v : Vec3) -> Bivec3 {return transmute(Bivec3) v }
bivec3_to_vec3 :: #force_inline proc "contextless" (bv : Bivec3) -> Vec3 {return transmute(Vec3) bv }
rotor3_to_quat128 :: #force_inline proc "contextless" (rotor : Rotor3) -> Quat128 {return transmute(Quat128) rotor}
unitvec3_to_vec3 :: #force_inline proc "contextless" (v : UnitVec3) -> Vec3 {return transmute(Vec3) v }
unitvec4_to_vec4 :: #force_inline proc "contextless" (v : UnitVec4) -> Vec4 {return transmute(Vec4) v }
plane_to_vec4 :: #force_inline proc "contextless" (p : Plane3) -> Vec4 {return transmute(Vec4) p}
point3_to_vec3 :: #force_inline proc "contextless" (p : Point3) -> Vec3 {return transmute(Vec3) p}
pointflat3_to_vec3 :: #force_inline proc "contextless" (p : PointFlat3) -> Vec3 {return { p.x, p.y, p.z }}
vec3_to_point3 :: #force_inline proc "contextless" (v : Vec3) -> Point3 {return transmute(Point3) v}
cross_v3_unitv3 :: #force_inline proc "contextless" (v : Vec3, u : UnitVec3) -> Vec3 {return cross_vec3(v, transmute(Vec3) u)}
cross_unitv3_vs :: #force_inline proc "contextless" (u : UnitVec3, v : Vec3) -> Vec3 {return cross_vec3(transmute(Vec3) u, v)}
dot_v3_unitv3 :: #force_inline proc "contextless" (v : Vec3, unit_v : UnitVec3) -> f32 {return dot_vec3(v, transmute(Vec3) unit_v)}
dot_unitv3_vs :: #force_inline proc "contextless" (unit_v : UnitVec3, v : Vec3) -> f32 {return dot_vec3(v, transmute(Vec3) unit_v)}
wedge_v3_unitv3 :: #force_inline proc "contextless" (v : Vec3, unit_v : UnitVec3) -> Bivec3 {return wedge_vec3(v, transmute(Vec3) unit_v)}
wedge_unitv3_vs :: #force_inline proc "contextless" (unit_v : UnitVec3, v : Vec3) -> Bivec3 {return wedge_vec3(transmute(Vec3) unit_v, v)}

View File

@ -106,7 +106,7 @@ project_serialize :: proc( project : ^ Project, archive : ^ ArchiveData, is_writ
if is_writting
{
marshal_archive : MarshalArchive
marshal_archive := new(MarshalArchive, frame_slab_allocator())
marshal_archive.version = archive.version
marshal_archive.project = project^
// TODO(Ed): In the future this will be more complicated, as serialization of workspaces and the code database won't be trivial
@ -127,7 +127,7 @@ project_serialize :: proc( project : ^ Project, archive : ^ ArchiveData, is_writ
// Note(Ed) : This works fine for now, but eventually it will most likely break with pointers...
// We'll most likely set things up so that all refs in the project & workspace are handles.
marshal_archive : MarshalArchive
marshal_archive := new(MarshalArchive, frame_slab_allocator())
json.unmarshal( archive.data, & marshal_archive, spec = json.Specification.MJSON, allocator = context.temp_allocator )
if marshal_archive.version == Serializer_Version {
project^ = marshal_archive.project

View File

@ -86,7 +86,7 @@ render_mode_screenspace :: proc ()
rl.DrawCircleV( cursor_pos, 10, Color_White_A125 )
}
ui := project.workspace.ui
ui := & project.workspace.ui
// debug_text("Box Count: %v", ui.built_box_count )

View File

@ -350,8 +350,8 @@ update :: proc( delta_time : f64 ) -> b32
// index := 0
widgets : Array(UI_Widget)
widgets, alloc_error = array_init_reserve( UI_Widget, frame_slab_allocator(), Kilobyte * 64 )
// widgets, alloc_error = array_init_reserve( UI_Widget, frame_slab_allocator(), Kilobyte * 8 )
widgets, alloc_error = array_init_reserve( UI_Widget, frame_slab_allocator(), 8 )
// widgets, alloc_error = array_init_reserve( UI_Widget, frame_slab_allocator(), 4 * Kilobyte )
widgets_ptr := & widgets
label_id := 0

View File

@ -274,7 +274,8 @@ UI_Box :: struct {
UI_Layout_Stack_Size :: 512
UI_Style_Stack_Size :: 512
UI_Parent_Stack_Size :: 512
UI_Built_Boxes_Array_Size :: 8
// UI_Built_Boxes_Array_Size :: 8
UI_Built_Boxes_Array_Size :: 4 * Kilobyte
UI_State :: struct {
// TODO(Ed) : Use these
@ -320,14 +321,15 @@ ui_startup :: proc( ui : ^ UI_State, cache_allocator : Allocator )
ui := ui
ui^ = {}
for cache in (& ui.caches) {
// cache.ref in ui.caches.ref
for & cache in (& ui.caches) {
box_cache, allocation_error := zpl_hmap_init_reserve( UI_Box, cache_allocator, UI_Built_Boxes_Array_Size )
verify( allocation_error == AllocatorError.None, "Failed to allocate box cache" )
cache = box_cache
}
ui.curr_cache = & ui.caches[1]
ui.prev_cache = & ui.caches[0]
ui.curr_cache = (& ui.caches[1])
ui.prev_cache = (& ui.caches[0])
log("ui_startup completed")
}

@ -1 +1 @@
Subproject commit e03fa88e4c70f8078a1516d36d9203b729569954
Subproject commit a1f241e925283d8870cb1ec3d6c32d26119047b4

@ -1 +1 @@
Subproject commit c2097b9dd936c796805dd54e655253d6b7523265
Subproject commit 7449c96e6c20d693a7ada04df743cbb6d468ade5