// File: /workspace/github_c_makefile_star2_O2/FredTheDino[P]Fog/src/engine/logic/block_physics.cpp
// Function: Physics::check_overlap(Physics::Body*, Physics::Body*)
Overlap check_overlap(Body *body_a, Body *body_b) {
    // NOTE: If I find that dragging along a surface is jagged,
    // we could try having weighted directions and add a little bit
    // of weight to the ones along the closing velocity. It might
    // help. I don't know.

    Overlap overlap = {body_a, body_b, -1.0f};
    if ((body_a->layer & body_b->layer) == 0) return overlap;

    Shape shape_a = find_shape(body_a->shape);
    Shape shape_b = find_shape(body_b->shape);

    Vec2 center = (body_a->position + body_b->position) * 0.5;

    Vec2 relative_position = (body_b->position) - (body_a->position);

    Vec2 scale = inverse(body_a->scale);
    List<Vec2> normals = shape_a.normals;
    for (u32 n = 0; n < 2; n++) {
        for (u32 i = 0; i < normals.length; i++) {
            Vec2 normal, axis_a, axis_b;
            normal = normals[i];
            normal = normalize(hadamard(normal, scale));

            if (n == 0) {
                f32 rotation = body_a->rotation - body_b->rotation;
                axis_a = normal;
                axis_b = rotate(normal, rotation);
                normal = rotate(normal, body_a->rotation);
                if (debug_view_is_on())
                    Renderer::push_line(MAX_LAYER, body_a->position, body_a->position + normal,
                                        V4(0.6, 0.0, 0.3, 1.0));
            } else {
                f32 rotation = body_b->rotation - body_a->rotation;
                axis_a = rotate(normal, rotation);
                axis_b = normal;
                normal = rotate(normal, body_b->rotation);
                if (debug_view_is_on())
                    Renderer::push_line(MAX_LAYER, body_b->position, body_b->position + normal,
                                        V4(0.0, 0.6, 0.3, 1.0));
            }

#if 0
            Vec2 axis_a, axis_b;
            axis_a = normal;
            axis_b = normal;
#endif

            Limit limit_a, limit_b;
            limit_a = project_shape(shape_a, axis_a, body_a->scale, body_a->offset);
            limit_b = project_shape(shape_b, axis_b, body_b->scale, body_b->offset);

            f32 projected_distance = dot(relative_position, normal);


            f32 depth;
            if (projected_distance > 0)
                depth = limit_a.upper - limit_b.lower - projected_distance;
            else
                depth = limit_b.upper - limit_a.lower + projected_distance;

            if (debug_view_is_on()) {
                Vec2 a1, a2;
                a1 = body_a->position + normal * limit_a.lower;
                a2 = body_a->position + normal * limit_a.upper;
                Renderer::push_line(MAX_LAYER, a1, a2, V4(1, 0, 1, 1));

                Vec2 b1, b2;
                b1 = body_b->position + normal * limit_b.lower;
                b2 = body_b->position + normal * limit_b.upper;
                Renderer::push_line(MAX_LAYER, b1, b2, V4(0, 1, 1, 1));

                //debug_line(body_a->position, body_a->position + axis_a);
                //debug_line(body_b->position, body_b->position + axis_b);
                Vec4 color = depth > 0 ? V4(1, 1, 0, 1) : V4(1, 0, 0, 1);
                Renderer::push_line(MAX_LAYER, center, center + normal * depth, color);
            }

            if (depth < 0)
                return overlap;

            if (depth < overlap.depth || overlap.depth == -1.0f) {
                overlap.depth = depth;
                overlap.normal = normal;
            }
        }

        normals = shape_b.normals;
        scale = inverse(body_b->scale);
    }

    if (debug_view_is_on())
        Renderer::push_line(MAX_LAYER, center, center + overlap.normal * overlap.depth,
                            V4(0, 1, 0, 1));

    if (dot(overlap.normal, relative_position) < 0) {
        // Make sure the normal faces body a
        overlap.normal = -overlap.normal;
    }

    overlap.is_valid = true;
    return overlap;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x1c8, %rsp            # imm = 0x1C8
movq %rdi, %rbx
movq %rsi, (%rdi)
movq %rdx, 0x8(%rdi)
movl $0xbf800000, 0x10(%rdi) # imm = 0xBF800000
andq $0x0, 0x14(%rdi)
movb $0x0, 0x1c(%rdi)
movl 0x4(%rdx), %eax
testl %eax, 0x4(%rsi)
je 0x2336e
movq %rdx, %r14
movq %rsi, %r15
movq %rbx, -0x78(%rbp)
leaq 0x14(%rbx), %r12
movl (%rsi), %esi
leaq -0x1b0(%rbp), %rbx
movq %rbx, %rdi
callq 0x2288a
movl (%r14), %esi
leaq -0x170(%rbp), %rdi
callq 0x2288a
leaq 0x14(%r15), %rax
movq %rax, -0xb0(%rbp)
leaq 0x14(%r14), %rax
movq %rax, -0xb8(%rbp)
movsd 0x14(%r14), %xmm2
movss 0x14(%r15), %xmm1
addss %xmm2, %xmm1
movaps %xmm2, %xmm3
shufps $0x55, %xmm2, %xmm3     # xmm3 = xmm3[1,1],xmm2[1,1]
addss 0x18(%r15), %xmm3
movss 0x813a(%rip), %xmm0     # 0x2b008
mulss %xmm0, %xmm1
mulss %xmm0, %xmm3
movaps %xmm1, -0x100(%rbp)
movaps %xmm3, -0xf0(%rbp)
unpcklps %xmm3, %xmm1            # xmm1 = xmm1[0],xmm3[0],xmm1[1],xmm3[1]
movaps %xmm1, -0xe0(%rbp)
movsd 0x14(%r15), %xmm0
movsd 0x1c(%r15), %xmm1
subps %xmm0, %xmm2
movaps %xmm2, -0x110(%rbp)
movss 0x80f8(%rip), %xmm0     # 0x2b004
movaps %xmm0, %xmm2
divss %xmm1, %xmm2
shufps $0x55, %xmm1, %xmm1     # xmm1 = xmm1[1,1,1,1]
divss %xmm1, %xmm0
unpcklps %xmm0, %xmm2            # xmm2 = xmm2[0],xmm0[0],xmm2[1],xmm0[1]
movaps %xmm2, -0x120(%rbp)
movq 0x20(%rbx), %rax
leaq -0xd0(%rbp), %rcx
movq %rax, 0x10(%rcx)
movups 0x10(%rbx), %xmm0
movaps %xmm0, (%rcx)
movq %r12, -0xa8(%rbp)
movsd (%r12), %xmm0
xorl %r13d, %r13d
movss 0x82d5(%rip), %xmm1     # 0x2b228
pushq $0xe
popq %r12
cmpl $0x2, %r13d
je 0x23383
xorl %ebx, %ebx
movaps %xmm1, -0xa0(%rbp)
movaps %xmm0, -0x70(%rbp)
cmpl -0xcc(%rbp), %ebx
jae 0x23301
leaq -0xd0(%rbp), %rdi
movl %ebx, %esi
callq 0x2a6a8
movsd (%rax), %xmm0
mulps -0x120(%rbp), %xmm0
callq 0x6a2a
testl %r13d, %r13d
movaps %xmm0, -0x40(%rbp)
je 0x232ad
movss 0x10(%r14), %xmm1
subss 0x10(%r15), %xmm1
callq 0x6aaa
movaps %xmm0, -0x60(%rbp)
movss 0x10(%r14), %xmm1
movaps -0x40(%rbp), %xmm0
callq 0x6aaa
movaps %xmm0, -0x50(%rbp)
cmpb $0x0, 0x3c9a1(%rip)     # 0x5f975
movq -0xb8(%rbp), %rax
movsd 0x837d(%rip), %xmm2     # 0x2b360
movaps -0x40(%rbp), %xmm0
movaps %xmm0, -0x90(%rbp)
movaps -0x60(%rbp), %xmm6
je 0x2301b
movsd (%rax), %xmm0
movaps -0x50(%rbp), %xmm1
addps %xmm0, %xmm1
movl %r12d, %edi
movsd 0x8366(%rip), %xmm3     # 0x2b370
movss 0x823e(%rip), %xmm4     # 0x2b250
callq 0x1fd26
movaps -0x60(%rbp), %xmm6
movsd 0x8(%r15), %xmm2
movsd 0x1c(%r15), %xmm1
movups -0x1b0(%rbp), %xmm0
movups -0x1a0(%rbp), %xmm3
movups -0x190(%rbp), %xmm4
movups -0x180(%rbp), %xmm5
movups %xmm5, 0x30(%rsp)
movups %xmm4, 0x20(%rsp)
movups %xmm3, 0x10(%rsp)
movups %xmm0, (%rsp)
movaps %xmm6, %xmm0
callq 0x2297e
movaps %xmm0, -0x40(%rbp)
movsd 0x8(%r14), %xmm2
movsd 0x1c(%r14), %xmm1
movups -0x170(%rbp), %xmm0
movups -0x160(%rbp), %xmm3
movups -0x150(%rbp), %xmm4
movups -0x140(%rbp), %xmm5
movups %xmm5, 0x30(%rsp)
movups %xmm4, 0x20(%rsp)
movups %xmm3, 0x10(%rsp)
movups %xmm0, (%rsp)
movaps -0x90(%rbp), %xmm0
callq 0x2297e
movaps -0x40(%rbp), %xmm7
movaps %xmm0, %xmm6
movaps -0x110(%rbp), %xmm0
movaps %xmm0, %xmm1
movaps -0x50(%rbp), %xmm3
mulps %xmm3, %xmm1
shufps $0x55, %xmm1, %xmm1     # xmm1 = xmm1[1,1,1,1]
mulss %xmm3, %xmm0
addss %xmm1, %xmm0
ucomiss 0x8158(%rip), %xmm0     # 0x2b22c
movaps %xmm6, %xmm5
shufps $0x55, %xmm6, %xmm5     # xmm5 = xmm5[1,1],xmm6[1,1]
movaps %xmm7, %xmm2
shufps $0x55, %xmm7, %xmm2     # xmm2 = xmm2[1,1],xmm7[1,1]
jbe 0x230f1
movaps %xmm2, %xmm4
subss %xmm6, %xmm4
subss %xmm0, %xmm4
jmp 0x230ff
movaps %xmm5, %xmm1
subss %xmm7, %xmm1
addss %xmm1, %xmm0
movaps %xmm0, %xmm4
cmpb $0x0, 0x3c86f(%rip)     # 0x5f975
je 0x23265
movaps %xmm3, %xmm8
shufps $0x55, %xmm3, %xmm8     # xmm8 = xmm8[1,1],xmm3[1,1]
movaps %xmm3, %xmm0
mulss %xmm7, %xmm0
movaps %xmm8, %xmm1
movaps %xmm8, -0x60(%rbp)
mulss %xmm7, %xmm1
movaps %xmm3, %xmm7
movaps %xmm3, -0x50(%rbp)
movss 0x14(%r15), %xmm3
movaps %xmm4, -0x40(%rbp)
movss 0x18(%r15), %xmm4
addss %xmm3, %xmm0
addss %xmm4, %xmm1
unpcklps %xmm1, %xmm0            # xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
movaps %xmm7, %xmm1
mulss %xmm2, %xmm1
mulss %xmm8, %xmm2
addss %xmm3, %xmm1
addss %xmm4, %xmm2
unpcklps %xmm2, %xmm1            # xmm1 = xmm1[0],xmm2[0],xmm1[1],xmm2[1]
movl %r12d, %edi
movss 0x7e97(%rip), %xmm2     # 0x2b004
movaps 0x811c(%rip), %xmm3     # 0x2b290
movss 0x80d4(%rip), %xmm4     # 0x2b250
movaps %xmm5, -0x90(%rbp)
movaps %xmm6, -0x130(%rbp)
callq 0x1fd26
movaps -0x50(%rbp), %xmm5
movaps %xmm5, %xmm0
movaps -0x130(%rbp), %xmm2
mulss %xmm2, %xmm0
movaps -0x60(%rbp), %xmm4
movaps %xmm4, %xmm1
mulss %xmm2, %xmm1
movss 0x14(%r14), %xmm2
movss 0x18(%r14), %xmm3
addss %xmm2, %xmm0
addss %xmm3, %xmm1
unpcklps %xmm1, %xmm0            # xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
movaps %xmm5, %xmm1
movaps -0x90(%rbp), %xmm5
mulss %xmm5, %xmm1
mulss %xmm4, %xmm5
addss %xmm2, %xmm1
addss %xmm3, %xmm5
unpcklps %xmm5, %xmm1            # xmm1 = xmm1[0],xmm5[0],xmm1[1],xmm5[1]
movl %r12d, %edi
movsd 0x8195(%rip), %xmm2     # 0x2b380
movaps 0x809e(%rip), %xmm3     # 0x2b290
movss 0x8056(%rip), %xmm4     # 0x2b250
callq 0x1fd26
movaps -0x40(%rbp), %xmm0
ucomiss 0x8022(%rip), %xmm0     # 0x2b22c
movaps 0x807f(%rip), %xmm2     # 0x2b290
ja 0x2321b
movss 0x7de9(%rip), %xmm2     # 0x2b004
movaps -0x50(%rbp), %xmm1
mulss %xmm0, %xmm1
movaps -0x60(%rbp), %xmm3
mulss %xmm0, %xmm3
addss -0x100(%rbp), %xmm1
addss -0xf0(%rbp), %xmm3
unpcklps %xmm3, %xmm1            # xmm1 = xmm1[0],xmm3[0],xmm1[1],xmm3[1]
movl %r12d, %edi
movaps -0xe0(%rbp), %xmm0
movsd 0x8130(%rip), %xmm3     # 0x2b380
movss 0x7ff8(%rip), %xmm4     # 0x2b250
callq 0x1fd26
movaps -0x40(%rbp), %xmm4
movaps -0x50(%rbp), %xmm3
xorps %xmm0, %xmm0
ucomiss %xmm4, %xmm0
ja 0x23356
movaps -0xa0(%rbp), %xmm2
movaps %xmm2, %xmm0
movss 0x7fa5(%rip), %xmm1     # 0x2b228
cmpeqps %xmm1, %xmm0
movaps %xmm4, %xmm1
cmpltps %xmm2, %xmm1
orps %xmm0, %xmm1
movd %xmm1, %eax
testb $0x1, %al
jne 0x232a0
movaps -0x70(%rbp), %xmm3
movaps %xmm2, %xmm4
incl %ebx
movaps %xmm3, %xmm0
movaps %xmm4, %xmm1
jmp 0x22f63
movss 0x10(%r15), %xmm1
subss 0x10(%r14), %xmm1
callq 0x6aaa
movaps %xmm0, -0x90(%rbp)
movss 0x10(%r15), %xmm1
movaps -0x40(%rbp), %xmm0
callq 0x6aaa
movaps -0x40(%rbp), %xmm6
cmpb $0x0, 0x3c696(%rip)     # 0x5f975
movaps %xmm0, -0x50(%rbp)
movq -0xb0(%rbp), %rax
movss 0x7f66(%rip), %xmm2     # 0x2b258
movaps %xmm6, -0x60(%rbp)
jne 0x22ff4
jmp 0x2301b
leaq -0x170(%rbp), %rcx
movb 0x20(%rcx), %al
movb %al, -0xc0(%rbp)
movups 0x10(%rcx), %xmm0
movaps %xmm0, -0xd0(%rbp)
movsd 0x1c(%r14), %xmm0
movss 0x7cda(%rip), %xmm1     # 0x2b004
movaps %xmm1, %xmm2
divss %xmm0, %xmm2
shufps $0x55, %xmm0, %xmm0     # xmm0 = xmm0[1,1,1,1]
divss %xmm0, %xmm1
unpcklps %xmm1, %xmm2            # xmm2 = xmm2[0],xmm1[0],xmm2[1],xmm1[1]
movaps %xmm2, -0x120(%rbp)
incl %r13d
movaps -0x70(%rbp), %xmm0
movaps -0xa0(%rbp), %xmm1
jmp 0x22f57
movq -0x78(%rbp), %rbx
movaps -0xa0(%rbp), %xmm0
movss %xmm0, 0x10(%rbx)
movaps -0x70(%rbp), %xmm0
movlps %xmm0, 0x14(%rbx)
movq %rbx, %rax
addq $0x1c8, %rsp            # imm = 0x1C8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq -0x78(%rbp), %rbx
movss %xmm1, 0x10(%rbx)
movlps %xmm0, 0x14(%rbx)
cmpb $0x0, 0x3c5de(%rip)     # 0x5f975
movaps %xmm0, %xmm3
je 0x233f1
movaps %xmm3, %xmm0
shufps $0x55, %xmm3, %xmm0     # xmm0 = xmm0[1,1],xmm3[1,1]
movaps %xmm1, %xmm2
mulss %xmm3, %xmm2
mulss %xmm1, %xmm0
movaps -0x100(%rbp), %xmm1
addss %xmm2, %xmm1
movaps -0xf0(%rbp), %xmm2
addss %xmm0, %xmm2
unpcklps %xmm2, %xmm1            # xmm1 = xmm1[0],xmm2[0],xmm1[1],xmm2[1]
movsd 0x7fb1(%rip), %xmm2     # 0x2b380
pushq $0xe
popq %rdi
movss 0x7e76(%rip), %xmm4     # 0x2b250
movaps -0xe0(%rbp), %xmm0
movaps %xmm3, -0x70(%rbp)
movaps %xmm2, %xmm3
callq 0x1fd26
movaps -0x70(%rbp), %xmm3
movaps -0x110(%rbp), %xmm1
movaps %xmm1, %xmm0
mulps %xmm3, %xmm0
shufps $0x55, %xmm0, %xmm0     # xmm0 = xmm0[1,1,1,1]
mulss %xmm3, %xmm1
addss %xmm0, %xmm1
xorps %xmm0, %xmm0
ucomiss %xmm1, %xmm0
jbe 0x23427
movss %xmm3, %xmm3            # xmm3 = xmm3[0,1,2,3]
xorps 0x7c23(%rip), %xmm3     # 0x2b040
movq -0xa8(%rbp), %rax
movlps %xmm3, (%rax)
movb $0x1, 0x1c(%rbx)
jmp 0x2336e