// File: intheswim[P]FractalTubes/m3d.cpp
// Function: M3DDrawer::CalcBrightness(float, float, float, float, float, float, float, float, float)
float M3DDrawer::CalcBrightness (float light_x, float light_y, float light_z,
                      float x_norm, float y_norm, float z_norm,
                      float view_x, float view_y, float view_z)
{
	float cosg, cosf, bright = 0; // brightness
        
	cosf = (light_x * x_norm + light_y * y_norm + light_z * z_norm);
    
	if (cosf == 0)
    {
		cosf = cosg = 0;
    }
	else
    {
		// in generic case:
		// Refl_vector = -Light_vector + 2 * Norm_vector * (light_v * norm_v)
		// but light_v * norm_v is already calculated : it is cosf
		// Refl_vector = -Light_vector + 2 * Norm_vector * cosf
		// cosg is Refl_vector * viewpoint_vector (which by default is (0,0,1))
		// so :
		double refl_x, refl_y, refl_z;
		refl_x = -light_x + (2 * x_norm * cosf);
		refl_y = -light_y + (2 * y_norm * cosf);
		refl_z = -light_z + (2 * z_norm * cosf);
		cosg = (refl_x * view_x) + (refl_y * view_y) + (refl_z * view_z);
        
		// this assumes that viewpoint vector is (0, 0, 1)
        //	cosg = 2 * z_norm * cosf - light_z;
		if (cosg < 0)
            cosg=0;
    }
    //	if (cosf < 0)
    //	cosf = 0;
	// 	now, let's figure out the brightness at a given point:
	// 	k1 is diffuse reflection coefficient for Lambert's component (how well surface
	// 	is illuminated. If light is opposite to the normal
	// 	then illumination is maximal
	// 	k2 is specular reflection coefficient (Phong component) it depends on the viewer's eye point
	// 	which translates into v - vectior (0, 0, 1)
	// 	k3 is ambient light coefficient
    
	bright = 10 + 180 * (-k1 * (cosf) + k2 * pow((cosg), k_pow) + k3) / (k1+k2+k3);
	if (bright > 150) 
        bright = 150;
    
	return bright ;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x70, %rsp
movss 0x10(%rbp), %xmm8
movq %rdi, -0x8(%rbp)
movss %xmm0, -0xc(%rbp)
movss %xmm1, -0x10(%rbp)
movss %xmm2, -0x14(%rbp)
movss %xmm3, -0x18(%rbp)
movss %xmm4, -0x1c(%rbp)
movss %xmm5, -0x20(%rbp)
movss %xmm6, -0x24(%rbp)
movss %xmm7, -0x28(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x58(%rbp)
xorps %xmm0, %xmm0
movss %xmm0, -0x34(%rbp)
movss -0xc(%rbp), %xmm1
movss -0x18(%rbp), %xmm2
movss -0x10(%rbp), %xmm0
mulss -0x1c(%rbp), %xmm0
mulss %xmm2, %xmm1
addss %xmm0, %xmm1
movss -0x14(%rbp), %xmm0
movss -0x20(%rbp), %xmm2
mulss %xmm2, %xmm0
addss %xmm1, %xmm0
movss %xmm0, -0x30(%rbp)
movss -0x30(%rbp), %xmm0
xorps %xmm1, %xmm1
ucomiss %xmm1, %xmm0
jne 0xad41
jp 0xad41
xorps %xmm0, %xmm0
movss %xmm0, -0x2c(%rbp)
xorps %xmm0, %xmm0
movss %xmm0, -0x30(%rbp)
jmp 0xae3a
movss -0xc(%rbp), %xmm0
movd %xmm0, %eax
xorl $0x80000000, %eax       # imm = 0x80000000
movd %eax, %xmm1
movss 0x3675(%rip), %xmm0     # 0xe3d0
mulss -0x18(%rbp), %xmm0
movss -0x30(%rbp), %xmm2
mulss %xmm2, %xmm0
addss %xmm1, %xmm0
cvtss2sd %xmm0, %xmm0
movsd %xmm0, -0x40(%rbp)
movss -0x10(%rbp), %xmm0
movd %xmm0, %eax
xorl $0x80000000, %eax       # imm = 0x80000000
movd %eax, %xmm1
movss 0x3640(%rip), %xmm0     # 0xe3d0
mulss -0x1c(%rbp), %xmm0
movss -0x30(%rbp), %xmm2
mulss %xmm2, %xmm0
addss %xmm1, %xmm0
cvtss2sd %xmm0, %xmm0
movsd %xmm0, -0x48(%rbp)
movss -0x14(%rbp), %xmm0
movd %xmm0, %eax
xorl $0x80000000, %eax       # imm = 0x80000000
movd %eax, %xmm1
movss 0x360b(%rip), %xmm0     # 0xe3d0
mulss -0x20(%rbp), %xmm0
movss -0x30(%rbp), %xmm2
mulss %xmm2, %xmm0
addss %xmm1, %xmm0
cvtss2sd %xmm0, %xmm0
movsd %xmm0, -0x50(%rbp)
movsd -0x40(%rbp), %xmm1
movss -0x24(%rbp), %xmm0
cvtss2sd %xmm0, %xmm2
movsd -0x48(%rbp), %xmm0
movss -0x28(%rbp), %xmm3
cvtss2sd %xmm3, %xmm3
mulsd %xmm3, %xmm0
mulsd %xmm2, %xmm1
addsd %xmm0, %xmm1
movsd -0x50(%rbp), %xmm0
movss 0x10(%rbp), %xmm2
cvtss2sd %xmm2, %xmm2
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, -0x2c(%rbp)
xorps %xmm0, %xmm0
ucomiss -0x2c(%rbp), %xmm0
jbe 0xae38
xorps %xmm0, %xmm0
movss %xmm0, -0x2c(%rbp)
jmp 0xae3a
movq -0x58(%rbp), %rax
xorl %ecx, %ecx
subl (%rax), %ecx
cvtsi2ss %ecx, %xmm0
mulss -0x30(%rbp), %xmm0
cvtss2sd %xmm0, %xmm0
movsd %xmm0, -0x68(%rbp)
cvtsi2sdl 0x4(%rax), %xmm0
movsd %xmm0, -0x60(%rbp)
movss -0x2c(%rbp), %xmm0
movl 0xc(%rax), %edi
callq 0xb240
movsd -0x68(%rbp), %xmm1
movq -0x58(%rbp), %rcx
movaps %xmm0, %xmm2
movsd -0x60(%rbp), %xmm0
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
cvtsi2sdl 0x8(%rcx), %xmm1
addsd %xmm1, %xmm0
movsd 0x3413(%rip), %xmm1     # 0xe2a8
mulsd %xmm0, %xmm1
movl (%rcx), %eax
addl 0x4(%rcx), %eax
addl 0x8(%rcx), %eax
cvtsi2sd %eax, %xmm0
divsd %xmm0, %xmm1
movsd 0x340f(%rip), %xmm0     # 0xe2c0
addsd %xmm1, %xmm0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, -0x34(%rbp)
movss -0x34(%rbp), %xmm0
movss 0x3509(%rip), %xmm1     # 0xe3d4
ucomiss %xmm1, %xmm0
jbe 0xaedd
movss 0x34fc(%rip), %xmm0     # 0xe3d4
movss %xmm0, -0x34(%rbp)
movss -0x34(%rbp), %xmm0
addq $0x70, %rsp
popq %rbp
retq
nopl (%rax,%rax)