// File: /workspace/github_cpp_makefile_star2_O2/FreeSlave[P]vhlt/hlrad/mathutil.cpp
// Function: CalcSightArea(float const*, float const*, Winding const*, int, float, float)
vec_t CalcSightArea (const vec3_t receiver_origin, const vec3_t receiver_normal, const Winding *emitter_winding, int skylevel
	#ifdef HLRAD_DIVERSE_LIGHTING
					, vec_t lighting_power, vec_t lighting_scale
	#endif
					)
{
	// maybe there are faster ways in calculating the weighted area, but at least this way is not bad.
	vec_t area = 0.0;

	int numedges = emitter_winding->m_NumPoints;
	vec3_t *edges = (vec3_t *)malloc (numedges * sizeof (vec3_t));
	hlassume (edges != NULL, assume_NoMemory);
	bool error = false;
	for (int x = 0; x < numedges; x++)
	{
		vec3_t v1, v2, normal;
		VectorSubtract (emitter_winding->m_Points[x], receiver_origin, v1);
		VectorSubtract (emitter_winding->m_Points[(x + 1) % numedges], receiver_origin, v2);
		CrossProduct (v1, v2, normal); // pointing inward
		if (!VectorNormalize (normal))
		{
			error = true;
		}
		VectorCopy (normal, edges[x]);
	}
	if (!error)
	{
		int i, j;
		vec3_t *pnormal;
		vec_t *psize;
		vec_t dot;
		vec3_t *pedge;
		for (i = 0, pnormal = g_skynormals[skylevel], psize = g_skynormalsizes[skylevel]; i < g_numskynormals[skylevel]; i++, pnormal++, psize++)
		{
			dot = DotProduct (*pnormal, receiver_normal);
			if (dot <= 0)
				continue;
			for (j = 0, pedge = edges; j < numedges; j++, pedge++)
			{
				if (DotProduct (*pnormal, *pedge) <= 0)
				{
					break;
				}
			}
			if (j < numedges)
			{
				continue;
			}
	#ifdef HLRAD_DIVERSE_LIGHTING
			if (lighting_power != 1.0)
			{
				dot = pow (dot, lighting_power);
			}
	#endif
			area += dot * (*psize);
		}
		area = area * 4 * Q_PI; // convert to absolute sphere area
	}
	free (edges);
#ifdef HLRAD_DIVERSE_LIGHTING
	area *= lighting_scale;
#endif
	return area;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x48, %rsp
movss %xmm1, 0x24(%rsp)
movss %xmm0, 0x14(%rsp)
movl %ecx, 0x20(%rsp)
movq %rsi, 0x38(%rsp)
movq %rdi, %r12
movq %rdx, 0x8(%rsp)
movslq 0x8(%rdx), %r15
imulq $0xc, %r15, %rdi
callq 0x4420
movq %rax, %rbx
xorl %edi, %edi
testq %rax, %rax
setne %dil
pushq $0x1
popq %r13
movl %r13d, %esi
callq 0x92cb
xorl %r14d, %r14d
testl %r15d, %r15d
movl $0x0, %eax
movq %r15, 0x18(%rsp)
cmovgl %r15d, %eax
movq %rax, 0x40(%rsp)
imulq $0xc, %rax, %r15
xorl %ebp, %ebp
cmpq %r14, %r15
je 0x22746
movq 0x8(%rsp), %rax
movq 0x10(%rax), %rcx
movss (%rcx,%r14), %xmm0
movss (%r12), %xmm2
subss %xmm2, %xmm0
movl %r13d, %eax
cltd
idivl 0x18(%rsp)
imulq $0xc, %rdx, %rax
movss 0x4(%rcx,%rax), %xmm3
movsd 0x4(%rcx,%r14), %xmm1
movsd 0x4(%r12), %xmm4
subps %xmm4, %xmm1
subss %xmm4, %xmm3
movss (%rcx,%rax), %xmm5
movss 0x8(%rcx,%rax), %xmm6
unpcklps %xmm5, %xmm6            # xmm6 = xmm6[0],xmm5[0],xmm6[1],xmm5[1]
shufps $0xd4, %xmm4, %xmm2     # xmm2 = xmm2[0,1],xmm4[1,3]
shufps $0x52, %xmm4, %xmm2     # xmm2 = xmm2[2,0],xmm4[1,1]
subps %xmm2, %xmm6
movaps %xmm0, %xmm2
shufps $0xd4, %xmm1, %xmm2     # xmm2 = xmm2[0,1],xmm1[1,3]
shufps $0x52, %xmm1, %xmm2     # xmm2 = xmm2[2,0],xmm1[1,1]
mulss %xmm3, %xmm0
unpcklps %xmm6, %xmm3            # xmm3 = xmm3[0],xmm6[0],xmm3[1],xmm6[1]
mulps %xmm2, %xmm3
movaps %xmm1, %xmm2
mulps %xmm6, %xmm2
subps %xmm3, %xmm2
movlps %xmm2, 0x28(%rsp)
shufps $0x55, %xmm6, %xmm6     # xmm6 = xmm6[1,1,1,1]
mulss %xmm1, %xmm6
subss %xmm6, %xmm0
movss %xmm0, 0x30(%rsp)
leaq 0x28(%rsp), %rdi
callq 0xc021
ucomiss 0xf95a(%rip), %xmm0     # 0x32070
setnp %al
sete %cl
andb %al, %cl
orb %cl, %bpl
movsd 0x28(%rsp), %xmm0
movsd %xmm0, (%rbx,%r14)
movss 0x30(%rsp), %xmm0
movss %xmm0, 0x8(%rbx,%r14)
addq $0xc, %r14
incl %r13d
jmp 0x2266e
xorps %xmm0, %xmm0
testb $0x1, %bpl
jne 0x2286e
movslq 0x20(%rsp), %rsi
leaq 0x4f4c1c1(%rip), %rax   # 0x4f6e920
movq (%rax,%rsi,8), %r12
leaq 0x4f4c206(%rip), %rax   # 0x4f6e970
movq (%rax,%rsi,8), %r13
xorl %ebp, %ebp
xorps %xmm8, %xmm8
leaq 0x4f4c175(%rip), %r15   # 0x4f6e8f0
xorps %xmm7, %xmm7
movss 0x14(%rsp), %xmm1
movq 0x38(%rsp), %r14
movq %rsi, 0x18(%rsp)
cmpl (%r15,%rsi,4), %ebp
jge 0x22856
movss (%r12), %xmm6
movss 0x4(%r12), %xmm2
movss 0x4(%r14), %xmm0
mulss %xmm2, %xmm0
movss (%r14), %xmm4
mulss %xmm6, %xmm4
addss %xmm0, %xmm4
movss 0x8(%r12), %xmm3
movss 0x8(%r14), %xmm0
mulss %xmm3, %xmm0
addss %xmm4, %xmm0
ucomiss %xmm0, %xmm8
jae 0x22847
movq 0x40(%rsp), %rax
movq %rbx, %rcx
subl $0x1, %eax
jb 0x22812
movss 0x4(%rcx), %xmm4
mulss %xmm2, %xmm4
movss (%rcx), %xmm5
mulss %xmm6, %xmm5
addss %xmm4, %xmm5
movss 0x8(%rcx), %xmm4
mulss %xmm3, %xmm4
addss %xmm5, %xmm4
ucomiss %xmm4, %xmm8
jae 0x22847
addq $0xc, %rcx
jmp 0x227df
ucomiss 0xf84b(%rip), %xmm1     # 0x32064
jne 0x2281d
jnp 0x2283d
movss %xmm7, 0x8(%rsp)
callq 0x4520
movq 0x18(%rsp), %rsi
xorps %xmm8, %xmm8
movss 0x8(%rsp), %xmm7
movss 0x14(%rsp), %xmm1
mulss (%r13), %xmm0
addss %xmm0, %xmm7
incl %ebp
addq $0xc, %r12
addq $0x4, %r13
jmp 0x2278e
mulss 0x14292(%rip), %xmm7    # 0x36af0
cvtss2sd %xmm7, %xmm0
mulsd 0xf81e(%rip), %xmm0     # 0x32088
cvtsd2ss %xmm0, %xmm0
movss %xmm0, 0x8(%rsp)
movq %rbx, %rdi
callq 0x4380
movss 0x8(%rsp), %xmm0
mulss 0x24(%rsp), %xmm0
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq