www.pudn.com > Ì廿֯Âë.rar > vecmath.cpp, change:2001-11-25,size:6113b


/* ========================================================= 
 *   File ........... vecmath.cpp 
 *   Purpose ........ vector mathematics 
 * ========================================================= */ 
 
#include <stdlib.h> 
#include <math.h> 
#include "vecmath.h" 
 
matrix44 IDENTITY_MATRIX = {0x8421, 0x8421, {{1.0f,0.0f,0.0f,0.0f},{0.0f,1.0f,0.0f,0.0f},{0.0f,0.0f,1.0f,0.0f},{0.0f,0.0f,0.0f,1.0f}}}; 
 
/* ========== vector functions */ 
 
coord3 * 
vec_set(coord3 *v, float x, float y, float z) 
{ 
	v->x = x; 
	v->y = y; 
	v->z = z; 
	return v; 
} 
 
coord3 * 
vec_normalize(coord3 *w, coord3 *v) 
{ 
	float l = (float)sqrt((v->x * v->x) + (v->y * v->y) + (v->z * v->z)); 
	if (l == 0) return w; 
	w->x = v->x / l; 
	w->y = v->y / l; 
	w->z = v->z / l; 
	return w; 
} 
 
coord3 * 
vec_crossproduct(coord3 *n,coord3 *v1, coord3 *v2) 
{ 
	n->x = (v1->y * v2->z) - (v1->z * v2->y); 
	n->y = (v1->z * v2->x) - (v1->x * v2->z); 
	n->z = (v1->x * v2->y) - (v1->y * v2->x); 
	return n; 
} 
 
coord3 *  
vec_add(coord3 *v,coord3 *v1, coord3 *v2) 
{ 
	v->x = v1->x + v2->x; 
	v->y = v1->y + v2->y; 
	v->z = v1->z + v2->z; 
	return v; 
} 
 
coord3 * 
vec_subtract(coord3 *v,coord3 *v1, coord3 *v2) 
{ 
	v->x = v1->x - v2->x; 
	v->y = v1->y - v2->y; 
	v->z = v1->z - v2->z; 
	return v; 
} 
 
coord3 * 
vec_scale(coord3 *w, coord3 *v, float s) 
{ 
	w->x = v->x * s; 
	w->y = v->y * s; 
	w->z = v->z * s; 
	return w; 
} 
 
coord3 * 
vec_rotate(coord3 *w, coord3 *v, coord3 *r, float angle) 
{ 
   float si = (float)sin(angle/2); 
   float s = (float)cos(angle/2); 
	float a = r->x * si; 
	float b = r->y * si; 
	float c = r->z * si; 
	w->x = v->x*(1-2*(b*b+c*c)) + v->y*(  2*(a*b-s*c)) + v->z*(  2*(a*c+s*b)); 
	w->y = v->x*(  2*(a*b+s*c)) + v->y*(1-2*(a*a+c*c)) + v->z*(  2*(b*c-s*a)); 
	w->z = v->x*(  2*(a*c-s*b)) + v->y*(  2*(b*c+s*a)) + v->z*(1-2*(a*a+b*b)); 
	return w; 
} 
 
coord3 * 
vec_normal(coord3 *n, coord3 *p0, coord3 *p1, coord3 *p2) 
{ 
	coord3 v1, v2; 
	vec_subtract(&v1, p1, p0); 
	vec_subtract(&v2, p2, p0); 
	vec_crossproduct(n, &v1, &v2); 
	vec_normalize(n, n); 
	return n; 
} 
 
float vec_length(coord3 *v) 
{ 
	return (float)sqrt((v->x * v->x) + (v->y * v->y) + (v->z * v->z)); 
} 
 
float vec_angle(coord3 *v1, coord3 *v2) 
{ 
	return (float)((v1->x * v2->x) + (v1->y * v2->y) + (v1->z * v2->z)); 
} 
 
/* ========== vector/matrix functions */ 
 
coord3 * 
vec_matrixmul(coord3 *w, matrix44 *m, coord3 *v) 
{ 
	matrix_a *ma = &(m->matrix); 
	 
	float vx = v->x; 
	float vy = v->y; 
	float vz = v->z; 
 
	float hi = ((*ma)[0][3]*vx + (*ma)[1][3]*vy + (*ma)[2][3]*vz + (*ma)[3][3]); 
 
	if (hi == 1.0f) 
	{ 
		w->x = ((*ma)[0][0]*vx + (*ma)[1][0]*vy + (*ma)[2][0]*vz + (*ma)[3][0]); 
		w->y = ((*ma)[0][1]*vx + (*ma)[1][1]*vy + (*ma)[2][1]*vz + (*ma)[3][1]); 
		w->z = ((*ma)[0][2]*vx + (*ma)[1][2]*vy + (*ma)[2][2]*vz + (*ma)[3][2]); 
	} 
	else 
	{ 
		float h = 1.0f / hi; 
		w->x = ((*ma)[0][0]*vx + (*ma)[1][0]*vy + (*ma)[2][0]*vz + (*ma)[3][0]) * h; 
		w->y = ((*ma)[0][1]*vx + (*ma)[1][1]*vy + (*ma)[2][1]*vz + (*ma)[3][1]) * h; 
		w->z = ((*ma)[0][2]*vx + (*ma)[1][2]*vy + (*ma)[2][2]*vz + (*ma)[3][2]) * h; 
	} 
 
	return w; 
} 
 
/* ========== matrix functions */ 
 
void matrix_identity(matrix44 *m) 
{ 
	*m = IDENTITY_MATRIX; 
} 
 
void matrix_translate(matrix44 *m, float x, float y, float z) 
{ 
	*m = IDENTITY_MATRIX; 
	m->maskh = 0x842f; 
	m->maskv = 0x9531; 
	matrix_a *ma = &(m->matrix); 
	(*ma)[3][0] = x; 
	(*ma)[3][1] = y; 
	(*ma)[3][2] = z; 
} 
 
void matrix_scale(matrix44 *m, float x, float y, float z) 
{ 
	*m = IDENTITY_MATRIX; 
	matrix_a *ma = &(m->matrix); 
	(*ma)[0][0] = x; 
	(*ma)[1][1] = y; 
	(*ma)[2][2] = z; 
} 
 
void matrix_rotate(matrix44 *m, float x, float y, float z, float angle) 
{ 
	*m = IDENTITY_MATRIX; 
   float si = (float)sin(angle/2)/(float)sqrt(x*x + y*y + z*z); 
   float s = (float)cos(angle/2); 
	float a = x * si; 
	float b = y * si; 
	float c = z * si; 
	m->maskh = 0xeee1; 
	m->maskv = 0xeee1; 
	matrix_a *ma = &(m->matrix); 
	(*ma)[0][0] = (1-2*(b*b+c*c)); 
	(*ma)[1][0] = (  2*(a*b-s*c)); 
	(*ma)[2][0] = (  2*(a*c+s*b)); 
	(*ma)[0][1] = (  2*(a*b+s*c)); 
	(*ma)[1][1] = (1-2*(a*a+c*c)); 
	(*ma)[2][1] = (  2*(b*c-s*a)); 
	(*ma)[0][2] = (  2*(a*c-s*b)); 
	(*ma)[1][2] = (  2*(b*c+s*a)); 
	(*ma)[2][2] = (1-2*(a*a+b*b)); 
 
/*	(*ma)[0][0] = (1-2*(b*b+c*c)); 
	(*ma)[0][1] = (  2*(a*b-s*c)); 
	(*ma)[0][2] = (  2*(a*c+s*b)); 
	(*ma)[1][0] = (  2*(a*b+s*c)); 
	(*ma)[1][1] = (1-2*(a*a+c*c)); 
	(*ma)[1][2] = (  2*(b*c-s*a)); 
	(*ma)[2][0] = (  2*(a*c-s*b)); 
	(*ma)[2][1] = (  2*(b*c+s*a)); 
	(*ma)[2][2] = (1-2*(a*a+b*b)); */ 
} 
 
void matrix_matrixmul(matrix44 *m, matrix44 *m1, matrix44 *m2) 
{ 
	matrix_a *ma = &(m->matrix); 
	matrix_a *m1a = &(m1->matrix); 
	matrix_a *m2a = &(m2->matrix); 
 
	float sum; 
 
	unsigned short mask1 = m1->maskv; 
	unsigned short mask2 = m2->maskh; 
 
	unsigned short mk1; 
	unsigned short mk2; 
	unsigned short bv, bh; 
 
	register unsigned short mkh = 0; 
	register unsigned short mkv = 0; 
	register unsigned short mk; 
 
	mk2 = mask2; 
	bh = 0x8000; 
	for (int i=0; i<4; i++) 
	{ 
		bv = 0x8000 >> i; 
		mk1 = mask1; 
		for (int j=0; j<4; j++) 
		{ 
			sum = 0.0f; 
			mk = mk1 & mk2 & 0xf000; 
			if (mk) 
			{ 
				if (mk & 0x8000) sum += (*m1a)[0][j] * (*m2a)[i][0]; 
				if (mk & 0x4000) sum += (*m1a)[1][j] * (*m2a)[i][1]; 
				if (mk & 0x2000) sum += (*m1a)[2][j] * (*m2a)[i][2]; 
				if (mk & 0x1000) sum += (*m1a)[3][j] * (*m2a)[i][3]; 
				if (sum != 0.0)  
				{ 
					mkh |= bh; 
					mkv |= bv; 
				} 
			} 
			(*ma)[i][j] = sum; 
			mk1 <= 4;  
			bh >>= 1; 
			bv >>= 4; 
		} 
		mk2 <= 4; 
	} 
	m->maskh = mkh; 
	m->maskv = mkv; 
} 
 
void matrix_matrixmul_top(matrix44 *m, matrix44 *n) 
{ 
	matrix44 mm; 
	matrix_matrixmul(&mm, m, n); 
	*m = mm; 
} 
 
void matrix_matrixmul_bottom(matrix44 *m, matrix44 *n) 
{ 
	matrix44 mm; 
	matrix_matrixmul(&mm, n, m); 
	*m = mm; 
} 
 
void matrix_clean(matrix44 *m, matrix44 *n) 
{ 
	coord3 v0 = {0.0f, 0.0f, 0.0f}; 
	coord3 w; 
	matrix44 t; 
	vec_matrixmul(&w, n, &v0); 
	matrix_translate(&t, -w.x, -w.y, -w.z); 
	matrix_matrixmul(m, &t, n); 
}