glg.c

来自「游戏编程精粹6第中关于粒子的实时流体仿真系统,对入门的游戏开发者很有帮助.」· C语言 代码 · 共 938 行 · 第 1/2 页

C
938
字号
            /* rotate only around y-axis */
            MAT4(m, 0, 0) = c;
            MAT4(m, 2, 2) = c;
            if (y < 0.0F)
            {
                MAT4(m, 0, 2) = -s;
                MAT4(m, 2, 0) = s;
            }
            else
            {
                MAT4(m, 0, 2) = s;
                MAT4(m, 2, 0) = -s;
            }
        }
    }
    else if (y == 0.0F)
    {
        if (z == 0.0F)
        {
            optimized = GLG_TRUE;
            /* rotate only around x-axis */
            MAT4(m, 1, 1) = c;
            MAT4(m, 2, 2) = c;
            if (x < 0.0F)
            {
                MAT4(m, 1, 2) = s;
                MAT4(m, 2, 1) = -s;
            }
            else
            {
                MAT4(m, 1, 2) = -s;
                MAT4(m, 2, 1) = s;
            }
        }
    }

    if (!optimized)
    {
        const Real mag = glg_sqrt(x * x + y * y + z * z);

        if (mag <= 1.0e-4)
        {
            /* no rotation, leave mat as-is */
            return;
        }

        x /= mag;
        y /= mag;
        z /= mag;

        xx = x * x;
        yy = y * y;
        zz = z * z;
        xy = x * y;
        yz = y * z;
        zx = z * x;
        xs = x * s;
        ys = y * s;
        zs = z * s;
        one_c = 1.0F - c;

        /* We already hold the identity-matrix so we can skip some statements */
        MAT4(m, 0,0) = (one_c * xx) + c;
        MAT4(m, 0,1) = (one_c * xy) - zs;
        MAT4(m, 0,2) = (one_c * zx) + ys;
        /*    M(0,3) = 0.0F;
        */

        MAT4(m, 1, 0) = (one_c * xy) + zs;
        MAT4(m, 1,1) = (one_c * yy) + c;
        MAT4(m, 1,2) = (one_c * yz) - xs;
        /*    M(1,3) = 0.0F;
        */

        MAT4(m, 2,0) = (one_c * zx) - ys;
        MAT4(m, 2,1) = (one_c * yz) + xs;
        MAT4(m, 2,2) = (one_c * zz) + c;
        /*    M(2,3) = 0.0F;
        */

        /*
        MAT4(m, 3,0) = 0.0F;
        MAT4(m, 3,1) = 0.0F;
        MAT4(m, 3,2) = 0.0F;
        MAT4(m, 3,3) = 1.0F;
          */
    }
}

void mat4_mul(matrix4* dst, const matrix4* m0, const matrix4* m1)
{
    int row;
    int col;
    int i;
	matrix4 result;

    mat4_set_zero(&result);

    for (row = 0; row < 4; row++)
        for (col = 0; col < 4; col++)
            for (i = 0; i < 4; i++)
                MAT4(&result, row, col) += MAT4(m0, row, i)*MAT4(m1, i, col);
	mat4_copy(dst, &result);
}


void mat4_set_rotate_around(matrix4* dst, Real angle, const vector3* v){	Real s;	Real c;	Real _c;	Real x;	Real y;	Real z;	s = (Real)sin(angle*DEG2RAD);	c = (Real)cos(angle*DEG2RAD);	_c = 1 - c;	x = v->x;	y = v->y;	z = v->z;	mat4_set(dst,		c + x*x*_c, x*y*_c - z*s, x*z*_c + y*s, 0,		x*y*_c + z*s, c + y*y*_c, y*z*_c - x*s, 0,		x*z*_c - y*s, y*z*_c + x*s, c + z*z*_c, 0,		0, 0, 0, 1);}

void mat4_mulr_rotate(matrix4* dst, Real angle, Real x, Real y, Real z)
{
	matrix4 tmp;
	matrix4 result;
	mat4_set_rotate(&tmp, angle, x, y, z);
	mat4_mul(&result, dst, &tmp);
	mat4_copy(dst, &result);
}

void mat4_mull_rotate(matrix4* dst, Real angle, Real x, Real y, Real z)
{
	matrix4 tmp;
	matrix4 result;
	mat4_set_rotate(&tmp, angle, x, y, z);
	mat4_mul(&result, &tmp, dst);
	mat4_copy(dst, &result);
}

void mat4_translate(matrix4* dst, Real x, Real y, Real z){	matrix4 tmp;
	matrix4 result;
	mat4_set_translate(&tmp, x, y, z);
	mat4_mul(&result, dst, &tmp);
	mat4_copy(dst, &result);}
void mat4_invert(matrix4* dst, const matrix4* m)
{
	Real d = mat4_determinant(m);
	Real r;
	matrix4 ret;

	if (d == 0)
	    return;
	
	r = 1/d;

	MAT4(&ret, 0, 0) = r*(MAT4(m, 1, 1)*(MAT4(m, 2, 2)*MAT4(m, 3, 3) - MAT4(m, 2, 3)*MAT4(m, 3, 2)) + MAT4(m, 1, 2)*(MAT4(m, 2, 3)*MAT4(m, 3, 1) - MAT4(m, 2, 1)*MAT4(m, 3, 3)) + MAT4(m, 1, 3)*(MAT4(m, 2, 1)*MAT4(m, 3, 2) - MAT4(m, 2, 2)*MAT4(m, 3, 1)));
	MAT4(&ret, 0, 1) = r*(MAT4(m, 2, 1)*(MAT4(m, 0, 2)*MAT4(m, 3, 3) - MAT4(m, 0, 3)*MAT4(m, 3, 2)) + MAT4(m, 2, 2)*(MAT4(m, 0, 3)*MAT4(m, 3, 1) - MAT4(m, 0, 1)*MAT4(m, 3, 3)) + MAT4(m, 2, 3)*(MAT4(m, 0, 1)*MAT4(m, 3, 2) - MAT4(m, 0, 2)*MAT4(m, 3, 1)));
	MAT4(&ret, 0, 2) = r*(MAT4(m, 3, 1)*(MAT4(m, 0, 2)*MAT4(m, 1, 3) - MAT4(m, 0, 3)*MAT4(m, 1, 2)) + MAT4(m, 3, 2)*(MAT4(m, 0, 3)*MAT4(m, 1, 1) - MAT4(m, 0, 1)*MAT4(m, 1, 3)) + MAT4(m, 3, 3)*(MAT4(m, 0, 1)*MAT4(m, 1, 2) - MAT4(m, 0, 2)*MAT4(m, 1, 1)));
	MAT4(&ret, 0, 3) = r*(MAT4(m, 0, 1)*(MAT4(m, 1, 3)*MAT4(m, 2, 2) - MAT4(m, 1, 2)*MAT4(m, 2, 3)) + MAT4(m, 0, 2)*(MAT4(m, 1, 1)*MAT4(m, 2, 3) - MAT4(m, 1, 3)*MAT4(m, 2, 1)) + MAT4(m, 0, 3)*(MAT4(m, 1, 2)*MAT4(m, 2, 1) - MAT4(m, 1, 1)*MAT4(m, 2, 2)));
		     
	MAT4(&ret, 1, 0) = r*(MAT4(m, 1, 2)*(MAT4(m, 2, 0)*MAT4(m, 3, 3) - MAT4(m, 2, 3)*MAT4(m, 3, 0)) + MAT4(m, 1, 3)*(MAT4(m, 2, 2)*MAT4(m, 3, 0) - MAT4(m, 2, 0)*MAT4(m, 3, 2)) + MAT4(m, 1, 0)*(MAT4(m, 2, 3)*MAT4(m, 3, 2) - MAT4(m, 2, 2)*MAT4(m, 3, 3)));
	MAT4(&ret, 1, 1) = r*(MAT4(m, 2, 2)*(MAT4(m, 0, 0)*MAT4(m, 3, 3) - MAT4(m, 0, 3)*MAT4(m, 3, 0)) + MAT4(m, 2, 3)*(MAT4(m, 0, 2)*MAT4(m, 3, 0) - MAT4(m, 0, 0)*MAT4(m, 3, 2)) + MAT4(m, 2, 0)*(MAT4(m, 0, 3)*MAT4(m, 3, 2) - MAT4(m, 0, 2)*MAT4(m, 3, 3)));
	MAT4(&ret, 1, 2) = r*(MAT4(m, 3, 2)*(MAT4(m, 0, 0)*MAT4(m, 1, 3) - MAT4(m, 0, 3)*MAT4(m, 1, 0)) + MAT4(m, 3, 3)*(MAT4(m, 0, 2)*MAT4(m, 1, 0) - MAT4(m, 0, 0)*MAT4(m, 1, 2)) + MAT4(m, 3, 0)*(MAT4(m, 0, 3)*MAT4(m, 1, 2) - MAT4(m, 0, 2)*MAT4(m, 1, 3)));
	MAT4(&ret, 1, 3) = r*(MAT4(m, 0, 2)*(MAT4(m, 1, 3)*MAT4(m, 2, 0) - MAT4(m, 1, 0)*MAT4(m, 2, 3)) + MAT4(m, 0, 3)*(MAT4(m, 1, 0)*MAT4(m, 2, 2) - MAT4(m, 1, 2)*MAT4(m, 2, 0)) + MAT4(m, 0, 0)*(MAT4(m, 1, 2)*MAT4(m, 2, 3) - MAT4(m, 1, 3)*MAT4(m, 2, 2)));
	    
	MAT4(&ret, 2, 0) = r*(MAT4(m, 1, 3)*(MAT4(m, 2, 0)*MAT4(m, 3, 1) - MAT4(m, 2, 1)*MAT4(m, 3, 0)) + MAT4(m, 1, 0)*(MAT4(m, 2, 1)*MAT4(m, 3, 3) - MAT4(m, 2, 3)*MAT4(m, 3, 1)) + MAT4(m, 1, 1)*(MAT4(m, 2, 3)*MAT4(m, 3, 0) - MAT4(m, 2, 0)*MAT4(m, 3, 3)));
	MAT4(&ret, 2, 1) = r*(MAT4(m, 2, 3)*(MAT4(m, 0, 0)*MAT4(m, 3, 1) - MAT4(m, 0, 1)*MAT4(m, 3, 0)) + MAT4(m, 2, 0)*(MAT4(m, 0, 1)*MAT4(m, 3, 3) - MAT4(m, 0, 3)*MAT4(m, 3, 1)) + MAT4(m, 2, 1)*(MAT4(m, 0, 3)*MAT4(m, 3, 0) - MAT4(m, 0, 0)*MAT4(m, 3, 3)));
	MAT4(&ret, 2, 2) = r*(MAT4(m, 3, 3)*(MAT4(m, 0, 0)*MAT4(m, 1, 1) - MAT4(m, 0, 1)*MAT4(m, 1, 0)) + MAT4(m, 3, 0)*(MAT4(m, 0, 1)*MAT4(m, 1, 3) - MAT4(m, 0, 3)*MAT4(m, 1, 1)) + MAT4(m, 3, 1)*(MAT4(m, 0, 3)*MAT4(m, 1, 0) - MAT4(m, 0, 0)*MAT4(m, 1, 3)));
	MAT4(&ret, 2, 3) = r*(MAT4(m, 0, 3)*(MAT4(m, 1, 1)*MAT4(m, 2, 0) - MAT4(m, 1, 0)*MAT4(m, 2, 1)) + MAT4(m, 0, 0)*(MAT4(m, 1, 3)*MAT4(m, 2, 1) - MAT4(m, 1, 1)*MAT4(m, 2, 3)) + MAT4(m, 0, 1)*(MAT4(m, 1, 0)*MAT4(m, 2, 3) - MAT4(m, 1, 3)*MAT4(m, 2, 0)));
	    
	MAT4(&ret, 3, 0) = r*(MAT4(m, 1, 0)*(MAT4(m, 2, 2)*MAT4(m, 3, 1) - MAT4(m, 2, 1)*MAT4(m, 3, 2)) + MAT4(m, 1, 1)*(MAT4(m, 2, 0)*MAT4(m, 3, 2) - MAT4(m, 2, 2)*MAT4(m, 3, 0)) + MAT4(m, 1, 2)*(MAT4(m, 2, 1)*MAT4(m, 3, 0) - MAT4(m, 2, 0)*MAT4(m, 3, 1)));
	MAT4(&ret, 3, 1) = r*(MAT4(m, 2, 0)*(MAT4(m, 0, 2)*MAT4(m, 3, 1) - MAT4(m, 0, 1)*MAT4(m, 3, 2)) + MAT4(m, 2, 1)*(MAT4(m, 0, 0)*MAT4(m, 3, 2) - MAT4(m, 0, 2)*MAT4(m, 3, 0)) + MAT4(m, 2, 2)*(MAT4(m, 0, 1)*MAT4(m, 3, 0) - MAT4(m, 0, 0)*MAT4(m, 3, 1)));
	MAT4(&ret, 3, 2) = r*(MAT4(m, 3, 0)*(MAT4(m, 0, 2)*MAT4(m, 1, 1) - MAT4(m, 0, 1)*MAT4(m, 1, 2)) + MAT4(m, 3, 1)*(MAT4(m, 0, 0)*MAT4(m, 1, 2) - MAT4(m, 0, 2)*MAT4(m, 1, 0)) + MAT4(m, 3, 2)*(MAT4(m, 0, 1)*MAT4(m, 1, 0) - MAT4(m, 0, 0)*MAT4(m, 1, 1)));
	MAT4(&ret, 3, 3) = r*(MAT4(m, 0, 0)*(MAT4(m, 1, 1)*MAT4(m, 2, 2) - MAT4(m, 1, 2)*MAT4(m, 2, 1)) + MAT4(m, 0, 1)*(MAT4(m, 1, 2)*MAT4(m, 2, 0) - MAT4(m, 1, 0)*MAT4(m, 2, 2)) + MAT4(m, 0, 2)*(MAT4(m, 1, 0)*MAT4(m, 2, 1) - MAT4(m, 1, 1)*MAT4(m, 2, 0)));

	mat4_copy(dst, &ret);
}


void mat4_transpose(matrix4* dst, const matrix4* m)
{
	matrix4 result;
    int row;
    int col;
    for (row = 0; row < 4; row++)
        for (col = 0; col < 4; col++)
            MAT4(&result, row, col) = MAT4(m, col, row);
	mat4_copy(dst, &result);
}

Real mat4_determinant(const matrix4* m)
{
    return (MAT4(m, 0, 0)*MAT4(m, 1, 1) - MAT4(m, 0, 1)*MAT4(m, 1, 0))
           *(MAT4(m, 2, 2)*MAT4(m, 3, 3) - MAT4(m, 2, 3)*MAT4(m, 3, 2))
           -(MAT4(m, 0, 0)*MAT4(m, 1, 2) - MAT4(m, 0, 2)*MAT4(m, 1, 0))
           *(MAT4(m, 2, 1)*MAT4(m, 3, 3) - MAT4(m, 2, 3)*MAT4(m, 3, 1))
           +(MAT4(m, 0, 0)*MAT4(m, 1, 3) - MAT4(m, 0, 3)*MAT4(m, 1, 0))
           *(MAT4(m, 2, 1)*MAT4(m, 3, 2) - MAT4(m, 2, 2)*MAT4(m, 3, 1))
           +(MAT4(m, 0, 1)*MAT4(m, 1, 2) - MAT4(m, 0, 2)*MAT4(m, 1, 1))
           *(MAT4(m, 2, 0)*MAT4(m, 3, 3) - MAT4(m, 2, 3)*MAT4(m, 3, 0))
           -(MAT4(m, 0, 1)*MAT4(m, 1, 3) - MAT4(m, 0, 3)*MAT4(m, 1, 1))
           *(MAT4(m, 2, 0)*MAT4(m, 3, 2) - MAT4(m, 2, 2)*MAT4(m, 3, 0))
           +(MAT4(m, 0, 2)*MAT4(m, 1, 3) - MAT4(m, 0, 3)*MAT4(m, 1, 2))
           *(MAT4(m, 2, 0)*MAT4(m, 3, 1) - MAT4(m, 2, 1)*MAT4(m, 3, 0));
}


void mat4_dump(const matrix4* m)
{
    printf(" [ %f %f %f %f ]\n", m->m[0], m->m[4], m->m[8], m->m[12]);
    printf(" [ %f %f %f %f ]\n", m->m[1], m->m[5], m->m[9], m->m[13]);
    printf(" [ %f %f %f %f ]\n", m->m[2], m->m[6], m->m[10], m->m[14]);
    printf(" [ %f %f %f %f ]\n", m->m[3], m->m[7], m->m[11], m->m[15]);
}


Real distsq_tri_point(const vector3* v0,
					  const vector3* v1,
					  const vector3* v2,
					  const vector3* p)
{
	/* refer to http://www.magic-software.com/Distance.html */
	vector3 e0;
	vector3 e1;
	vector3 temp;
	Real a;
	Real b;
	Real c;
	Real d;
	Real e;
	Real f;
	Real det;
	Real inv_det;
	Real s;
	Real t;
	Real numer;
	Real denom;
	Real tmp0;
	Real tmp1;

	vec3_sub(&e0, v1, v0);
	vec3_sub(&e1, v2, v0);

	a = vec3_dot(&e0, &e0);
	b = vec3_dot(&e0, &e1);
	c = vec3_dot(&e1, &e1);
	vec3_sub(&temp, v0, p);
	d = vec3_dot(&e0, &temp);
	e = vec3_dot(&e1, &temp);
	f = vec3_dot(&temp, &temp);


	det = a*c - b*b;
	s = b*e - c*d;
	t = b*d - a*e;

	if ((s + t) <= det)
	{
		if (s < 0)
		{
			if (t < 0)
			{
				/* region 4 */
				if (d < 0.0f)
				{
					t = 0;
					s = ((-d >= a) ? 1 : -d/a);
				}
				else
				{
					s = 0;
					t = ((e >= 0) ? 0 : ((-e >= c) ? 1 : -e/c));
				}

			}
			else
			{
				/* region 3 */
				s = 0;
				t = (e >= 0 ? 0 : (-e >= c ? 1 : -e/c));
			}
		}
		else if (t < 0)
		{
			/* region 5 */
			s = (d >= 0 ? 0 : (-d >= a ? 1 : -d/a));
			t = 0;
		}
		else
		{
			/* region 0 */
			inv_det = 1/det;
			s *= inv_det;
			t *= inv_det;
		}
	}
	else
	{
		if (s < 0)
		{
			/* region 2 */
			tmp0 = b + d;
			tmp1 = c + e;
			if (tmp1 > tmp0)
			{
				numer = tmp1 - tmp0;
				denom = a - 2*b + c;
				s = (numer >= denom ? 1 : numer/denom);
				t = 1 - s;
			}
			else
			{
				s = 0;
				t = (tmp1 <= 0 ? 1 : (e >= 0 ? 0 : -e/c));
			}
		}
		else if (t < 0)
		{
			/* region 6 */
			tmp0 = b + e;
			tmp1 = a + d;
			if (tmp1 > tmp0)
			{
				numer = tmp1 - tmp0;
				denom = a - 2*b + c;
				t = (numer >= denom ? 1 : numer/denom);
				s = 1 - t;
			}
			else
			{
				t = 0;
				s = (tmp1 <= 0 ? 1 : (d >= 0 ? 0 : -d/a));
			}
		}
		else
		{
			/* region 1 */
			numer = (c + e - b - d);
			if (numer <= 0)
			{
				s = 0;
			}
			else
			{
				denom = a - 2*b + c;
				s = (numer >= denom ? 1 : numer/denom);
			}
			t = 1 - s;
		}
	}


	vec3_copy(&temp, v0);
	vec3_scaleadd(&temp, &temp, s, &e0);
	vec3_scaleadd(&temp, &temp, t, &e1);

	return vec3_distsq(&temp, p);
}


Real dist_tri_point(const vector3* v0,
					const vector3* v1,
					const vector3* v2,
					const vector3* p)
{
	return glg_sqrt(distsq_tri_point(v0, v1, v2, p));
}

Real dist_tri_point2(const vector3* v0,
					 const vector3* v1,
					 const vector3* v2,
					 const vector3* p)
{
	
	/*
	vector3 e0;
	vector3 e1;
	vector3 tri_n;
	vector3 p_tri;
	vector3 org_p;


	vec3_sub(&e0, v1, v0);
	vec3_sub(&e1, v2, v0);
	vec3_cross(&tri_n, &e0, &e1);
	vec3_normalize(&tri_n);
	vec3_sub(&org_p, p, v0);
	vec3_set(&p_tri, vec3_dot(&e0, &org_p), vec3_dot(&e1, &org_p), vec3_dot(&tri_n, &org_p));

	if ((p_tri.x > 0.0) && (p_tri.y > 0.0) && ((p_tri.x + p_tri.y) < (vec3_lensq(&e0) + vec3_lensq(&e1))))
//	if ((p_tri.x > 0.0) && (p_tri.y > 0.0) && ((p_tri.x + p_tri.y) < 1.0))
	{
		return p_tri.z;
	}
	else return p_tri.z + p_tri.x*p_tri.x + p_tri.y*p_tri.y;//length(p_tri);
*/

	/**** original ****/
	
	vector3 e0;
	vector3 e1;
	vector3 tri_n;
	vector3 p_tri;
	matrix4 m;
	matrix4 m_tri;


	vec3_sub(&e0, v1, v0);
	vec3_sub(&e1, v2, v0);

	tri_normal(&tri_n, v0, v1, v2);

	mat4_set_identity(&m);
	MAT4(&m, 0, 0) = e0.x;
	MAT4(&m, 1, 0) = e0.y;
	MAT4(&m, 2, 0) = e0.z;

	MAT4(&m, 0, 1) = e1.x;
	MAT4(&m, 1, 1) = e1.y;
	MAT4(&m, 2, 1) = e1.z;

	MAT4(&m, 0, 2) = tri_n.x;
	MAT4(&m, 1, 2) = tri_n.y;
	MAT4(&m, 2, 2) = tri_n.z;

	MAT4(&m, 0, 3) = v0->x;
	MAT4(&m, 1, 3) = v0->y;
	MAT4(&m, 2, 3) = v0->z;

	mat4_invert(&m_tri, &m);

	mat4_mulvec3(&p_tri, &m_tri, p);

	//return p_tri.z;

//	if ((0.0f < p_tri.x) && (p_tri.x < 1.0f) && (0.0f < p_tri.y) && (p_tri.y < 1.0f))
	if ((0.0f <= p_tri.x) && (0.0f <= p_tri.y) && ((p_tri.x + p_tri.y) <= 1.0f))
		return p_tri.z;
	
	return p_tri.z + p_tri.x*p_tri.x + p_tri.y*p_tri.y;
	
}

void tri_normal(vector3* n, 
				const vector3* v0,
				const vector3* v1,
				const vector3* v2)
{
	vector3 e0;
	vector3 e1;

	vec3_sub(&e0, v2, v0);
	vec3_sub(&e1, v1, v0);

	vec3_cross(n, &e0, &e1);
	vec3_normalize(n, n);
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?