// File: /workspace/github_cpp_makefile_star2_O3/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 %rbx
subq $0x10, %rsp
movq %rdi, %rbx
movaps %xmm1, %xmm8
mulss %xmm4, %xmm8
movaps %xmm0, %xmm10
mulss %xmm3, %xmm10
addss %xmm8, %xmm10
movaps %xmm2, %xmm9
mulss %xmm5, %xmm9
addss %xmm10, %xmm9
xorps %xmm8, %xmm8
xorps %xmm10, %xmm10
ucomiss %xmm10, %xmm9
jne 0x7b6b
jnp 0x7bed
addss %xmm3, %xmm3
mulss %xmm9, %xmm3
subss %xmm0, %xmm3
xorps %xmm0, %xmm0
cvtss2sd %xmm3, %xmm0
addss %xmm4, %xmm4
mulss %xmm9, %xmm4
subss %xmm1, %xmm4
xorps %xmm1, %xmm1
cvtss2sd %xmm4, %xmm1
addss %xmm5, %xmm5
mulss %xmm9, %xmm5
subss %xmm2, %xmm5
xorps %xmm2, %xmm2
cvtss2sd %xmm5, %xmm2
xorps %xmm3, %xmm3
cvtss2sd %xmm6, %xmm3
mulsd %xmm0, %xmm3
xorps %xmm0, %xmm0
cvtss2sd %xmm7, %xmm0
mulsd %xmm1, %xmm0
addsd %xmm3, %xmm0
xorps %xmm1, %xmm1
cvtss2sd 0x20(%rsp), %xmm1
mulsd %xmm2, %xmm1
addsd %xmm0, %xmm1
xorps %xmm0, %xmm0
cvtsd2ss %xmm1, %xmm0
xorps %xmm1, %xmm1
maxss %xmm0, %xmm1
xorps %xmm8, %xmm8
cvtss2sd %xmm1, %xmm8
movaps %xmm9, %xmm10
xorl %eax, %eax
subl (%rbx), %eax
xorps %xmm0, %xmm0
cvtsi2ss %eax, %xmm0
mulss %xmm10, %xmm0
cvtss2sd %xmm0, %xmm0
movsd %xmm0, 0x8(%rsp)
xorps %xmm0, %xmm0
cvtsi2sdl 0x4(%rbx), %xmm0
movsd %xmm0, (%rsp)
xorps %xmm1, %xmm1
cvtsi2sdl 0xc(%rbx), %xmm1
movaps %xmm8, %xmm0
callq 0x3590
mulsd (%rsp), %xmm0
movl 0x8(%rbx), %eax
xorps %xmm1, %xmm1
cvtsi2sd %eax, %xmm1
addsd 0x8(%rsp), %xmm0
addsd %xmm0, %xmm1
mulsd 0x189a(%rip), %xmm1     # 0x94e0
addl (%rbx), %eax
addl 0x4(%rbx), %eax
xorps %xmm0, %xmm0
cvtsi2sd %eax, %xmm0
divsd %xmm0, %xmm1
addsd 0x1672(%rip), %xmm1     # 0x92d0
cvtsd2ss %xmm1, %xmm1
movss 0x17aa(%rip), %xmm0     # 0x9414
minss %xmm1, %xmm0
addq $0x10, %rsp
popq %rbx
retq