Example #1
0
void update_object_orientation(void)
{
	static int mx = 0, my = 0, last_mouse_x = 0, last_mouse_y = 0;
	static int arcball = 0;
	
	IF_FAILED(init);
	
	if(!disable_mouse) {
		
		if(!arcball && input_get_mousebtn_state(MOUSE_LEFTBTN)) {
			arcball = 1;
			
			input_get_mouse_position(&mx, &my);
			
			last_mouse_x = mx;
			last_mouse_y = my;
		} else if(arcball && !input_get_mousebtn_state(MOUSE_LEFTBTN)) {
			arcball = 0;
			return;
		}
		
		if(arcball) {
			input_get_mouse_position(&mx, &my);
			
			if(mx < 0)
				mx = 0;
			else if(mx > window_width)
				mx = window_width;
			if(my < 0)
				my = 0;
			else if(my > window_height)
				my = window_height;
			
			if(last_mouse_x != mx || last_mouse_y != my) {
				// получаем вектора вращения виртуальной сферы
				vector3f v1 = compute_sphere_vector(last_mouse_x, last_mouse_y);
				vector3f v2 = compute_sphere_vector(mx, my);
				
				// угол вращения
				rot_angle = RAD_TO_DEG(math_acosf(math_min(1.0f, vec3f_dot(v1, v2))));
				
				matrix3f rotmat3, model3, rotmodel3;
				mat4_submat(rotmat3, 3, 3, rotmat);
				mat4_submat(model3, 3, 3, modelmat);
				
				mat3_mult2(rotmodel3, rotmat3, model3);
				
				// получаем ось вращения (переводим её в систему координат объекта)
				rot_axis = mat3_mult_vec3(rotmodel3, vec3f_norm(vec3f_cross(v1, v2)));
				
				// домножаем матрицу вращения
				mat4_rotate_axis_mult(rotmat, rot_angle, rot_axis);
				
				last_mouse_x = mx;
				last_mouse_y = my;
			}
		}
	}
}
Example #2
0
float perlin_noise_3d(vector3f pos)
{
	int x = math_fast_floorf(pos.x);
	int y = math_fast_floorf(pos.y);
	int z = math_fast_floorf(pos.z);
	
	pos.x -= x;
	pos.y -= y;
	pos.z -= z;
	
	x &= 255;
	y &= 255;
	z &= 255;
	
	float u = fade(pos.x), v = fade(pos.y), w = fade(pos.z);
	
	int gi000 = perm[ x +	  perm[ y +		perm[z] ] ]		% 12;
	int gi001 = perm[ x +	  perm[ y +		perm[z + 1] ] ] % 12;
	int gi010 = perm[ x +	  perm[ y + 1 + perm[z] ] ]		% 12;
	int gi011 = perm[ x +	  perm[ y + 1 + perm[z + 1] ] ] % 12;
	int gi100 = perm[ x + 1 + perm[ y +		perm[z] ] ]		% 12;
	int gi101 = perm[ x + 1 + perm[ y +		perm[z + 1] ] ] % 12;
	int gi110 = perm[ x + 1 + perm[ y + 1 + perm[z] ] ]		% 12;
	int gi111 = perm[ x + 1 + perm[ y + 1 + perm[z + 1] ] ] % 12;
	
	float n000 = vec3f_dot(grad3[gi000], vec3f(pos.x,		 pos.y,		   pos.z));
	float n100 = vec3f_dot(grad3[gi100], vec3f(pos.x - 1.0f, pos.y,		   pos.z));
	float n010 = vec3f_dot(grad3[gi010], vec3f(pos.x,		 pos.y - 1.0f, pos.z));
	float n110 = vec3f_dot(grad3[gi110], vec3f(pos.x - 1.0f, pos.y - 1.0f, pos.z));
	float n001 = vec3f_dot(grad3[gi001], vec3f(pos.x,		 pos.y,		   pos.z - 1.0f));
	float n101 = vec3f_dot(grad3[gi101], vec3f(pos.x - 1.0f, pos.y,		   pos.z - 1.0f));
	float n011 = vec3f_dot(grad3[gi011], vec3f(pos.x,		 pos.y - 1.0f, pos.z - 1.0f));
	float n111 = vec3f_dot(grad3[gi111], vec3f(pos.x - 1.0f, pos.y - 1.0f, pos.z - 1.0f));
	
	float nx00 = math_mix(n000, n100, u);
	float nx01 = math_mix(n001, n101, u);
	float nx10 = math_mix(n010, n110, u);
	float nx11 = math_mix(n011, n111, u);
	
	float nxy0 = math_mix(nx00, nx10, v);
	float nxy1 = math_mix(nx01, nx11, v);
	
	float nxyz = math_mix(nxy0, nxy1, w);
			
	return nxyz;
}
Example #3
0
/**
 * Apply an infinitesimal rotation w*dt to a direction cosine matrix A.
 * An orthonormalization step is added to prevent rounding errors.
 *
 * Without the normalization, this would be a simple matrix multiplication:
 *
 * return mat3_matmul( A, (mat3f) {
 *        1,   -w.z,  w.y,
 *      w.z,    1, -w.x,
 *     -w.y,  w.x,    1
 * };
 */
static mat3f dcm_integrate(mat3f A, vec3f w, float dt)
{
    w = vec3f_scale(w, dt);

    // Calculate the new x and y axes. z is calculated later.
    //
    vec3f x = vec3f_matmul(A, (vec3f){    1, w.z, -w.y } );
    vec3f y = vec3f_matmul(A, (vec3f){ -w.z,   1,  w.x } );

    // Orthonormalization
    //
    // First we compute the dot product of the x and y rows of the matrix, which
    // is supposed to be zero, so the result is a measure of how much the X and Y
    // rows are rotating toward each other
    //
    float error = vec3f_dot(x, y);

    // We apportion half of the error each to the x and y rows, and approximately
    // rotate the X and Y rows in the opposite direction by cross coupling:
    //
    vec3f xo, yo, zo;
    xo = vec3f_sub(x, vec3f_scale(y, 0.5 * error));
    yo = vec3f_sub(y, vec3f_scale(x, 0.5 * error));

    // Scale them to unit length and take a cross product for the Z axis
    //
    xo = vec3f_norm(xo);
    yo = vec3f_norm(yo);
    zo = vec3f_cross(xo, yo);

    return (mat3f) {
        xo.x, yo.x, zo.x,
        xo.y, yo.y, zo.y,
        xo.z, yo.z, zo.z
    };
}
Example #4
0
float simplex_noise_3d(vector3f pos)
{
	const float F3 = 1.0f / 3.0f;
	const float G3 = 1.0f / 6.0f;
	
	float s = (pos.x + pos.y + pos.z) * F3;
	
	int i = math_fast_floorf(pos.x + s);
	int j = math_fast_floorf(pos.y + s);
	int k = math_fast_floorf(pos.z + s);
	
	
	float t = (i + j + k) * G3;
	float X0 = i - t;
	float Y0 = j - t;
	float Z0 = k - t;
	
	float x0 = pos.x - X0;
	float y0 = pos.y - Y0;
	float z0 = pos.z - Z0;
	
	int i1, i2,  j1, j2,  k1, k2;
	
	if(x0 >= y0) {
		if(y0 >= z0) {
			i1 = 1; j1 = 0; k1 = 0;
			i2 = 1; j2 = 1; k2 = 0;
		} else if(x0 >= z0) {
			i1 = 1; j1 = 0; k1 = 0;
			i2 = 1; j2 = 0; k2 = 1;
		} else {
			i1 = 0; j1 = 0; k1 = 1;
			i2 = 1; j2 = 0; k2 = 1;
		}
	} else {
		if(y0 < z0) {
			i1 = 0; j1 = 0; k1 = 1;
			i2 = 0; j2 = 1; k2 = 1;
		} else if(x0 < z0) {
			i1 = 0; j1 = 1; k1 = 0;
			i2 = 0; j2 = 1; k2 = 1;
		} else {
			i1 = 0; j1 = 1; k1 = 0;
			i2 = 1; j2 = 1; k2 = 0;
		}
	}
	
	float x1 = x0 - i1 + G3;
	float y1 = y0 - j1 + G3;
	float z1 = z0 - k1 + G3;
	float x2 = x0 - i2 + 2.0f * G3;
	float y2 = y0 - j2 + 2.0f * G3;
	float z2 = z0 - k2 + 2.0f * G3;
	float x3 = x0 - 1.0f + 3.0f * G3;
	float y3 = y0 - 1.0f + 3.0f * G3;
	float z3 = z0 - 1.0f + 3.0f * G3;
	
	int ii = i & 255;
	int jj = j & 255;
	int kk = k & 255;
	
	int gi0 = perm[ii +		 perm[jj +		perm[kk		]]] % 12;
	int gi1 = perm[ii + i1 + perm[jj + j1 + perm[kk + k1]]] % 12;
	int gi2 = perm[ii + i2 + perm[jj + j2 + perm[kk + k2]]] % 12;
	int gi3 = perm[ii + 1 +  perm[jj + 1 +  perm[kk + 1 ]]] % 12;
	
	float n0 = 0.0f, n1 = 0.0f, n2 = 0.0f, n3 = 0.0f;
	
	float t0 = 0.6f - x0*x0 - y0*y0 - z0*z0;
	if(t0 < 0.0f) { 
		n0 = 0.0f;
	} else {
		t0 *= t0;
		n0 = t0 * t0 * vec3f_dot(grad3[gi0], vec3f(x0, y0, z0));
	}
	
	float t1 = 0.6f - x1*x1 - y1*y1 - z1*z1;
	if(t1 < 0.0f) { 
		n1 = 0.0f;
	} else {
		t1 *= t1;
		n1 = t1 * t1 * vec3f_dot(grad3[gi1], vec3f(x1, y1, z1));
	}
	
	float t2 = 0.6f - x2*x2 - y2*y2 - z2*z2;
	if(t2 < 0.0f) { 
		n2 = 0.0f;
	} else {
		t2 *= t2;
		n2 = t2 * t2 * vec3f_dot(grad3[gi2], vec3f(x2, y2, z2));
	}
	
	float t3 = 0.6f - x3*x3 - y3*y3 - z3*z3;
	if(t3 < 0.0f) { 
		n3 = 0.0f;
	} else {
		t3 *= t3;
		n3 = t3 * t3 * vec3f_dot(grad3[gi3], vec3f(x3, y3, z3));
	}
	
	return 32.0f * (n0 + n1 + n2 + n3);
	//return 16.0f * (n0 + n1 + n2 + n3) + 1.0f;
}