示例#1
0
文件: ray.c 项目: kaspermeerts/cg
/* This is basically Cramer's rule, but with vector calculus. */
static bool ray_triangle_intersect(Ray ray, Vec3 u, Vec3 v, Vec3 w,
		struct TriangleHit *tri_hit)
{
	Vec3 edge1, edge2, tvec, pvec, qvec;
	float det;
	float aa, bb, cc;

	edge1 = vec3_sub(v, u);
	edge2 = vec3_sub(w, u);

	pvec = vec3_cross(ray.direction, edge2);
	det = vec3_dot(edge1, pvec);

	tvec = vec3_sub(ray.origin, u);
	bb = vec3_dot(tvec, pvec) / det;
	if (bb < 0.0 || bb > 1.0)
		return false;

	qvec = vec3_cross(tvec, edge1);
	cc = vec3_dot(ray.direction, qvec) / det;
	if (cc < 0.0 || cc + bb > 1.0)
		return false;

	aa = 1.0 - bb - cc;

	tri_hit->a = aa;
	tri_hit->b = bb;
	tri_hit->c = cc;
	tri_hit->t = vec3_dot(edge2, qvec) / det;

	return true;
}
示例#2
0
/* calculate sphere that goes through 4 points */
struct sphere* sphere_circum(struct sphere* rs, const struct vec4f* v0,
                             const struct vec4f* v1, const struct vec4f* v2, const struct vec4f* v3)
{
    struct vec4f a;
    vec3_sub(&a, v1, v0);
    struct vec4f b;
    vec3_sub(&b, v2, v0);
    struct vec4f c;
    vec3_sub(&c, v3, v0);
    struct vec4f o;
    struct vec4f tmp;

    struct mat3f m;
    mat3_setf(&m,
              a.x, a.y, a.z,
              b.x, b.y, b.z,
              c.x, c.y, c.z,
              0.0f, 0.0f, 0.0f);

    float denom = 2.0f * mat3_det(&m);
    vec3_muls(&o, vec3_cross(&tmp, &a, &b), vec3_dot(&c, &c));
    vec3_add(&o, &o, vec3_muls(&tmp, vec3_cross(&tmp, &c, &a), vec3_dot(&b, &b)));
    vec3_add(&o, &o, vec3_muls(&tmp, vec3_cross(&tmp, &b, &c), vec3_dot(&a, &a)));
    vec3_muls(&o, &o, 1.0f/denom);

    return sphere_setf(rs, v0->x + o.x, v0->y + o.y, v0->z + o.z, vec3_len(&o) + EPSILON);
}
示例#3
0
文件: tools.c 项目: Indy9000/goxel
static box_t get_box(const vec3_t *p0, const vec3_t *p1, const vec3_t *n,
                     float r, const plane_t *plane)
{
    mat4_t rot;
    box_t box;
    if (p1 == NULL) {
        box = bbox_from_extents(*p0, r, r, r);
        box = box_swap_axis(box, 2, 0, 1);
        return box;
    }
    if (r == 0) {
        box = bbox_grow(bbox_from_points(*p0, *p1), 0.5, 0.5, 0.5);
        // Apply the plane rotation.
        rot = plane->mat;
        rot.vecs[3] = vec4(0, 0, 0, 1);
        mat4_imul(&box.mat, rot);
        return box;
    }

    // Create a box for a line:
    int i;
    const vec3_t AXES[] = {vec3(1, 0, 0), vec3(0, 1, 0), vec3(0, 0, 1)};

    box.mat = mat4_identity;
    box.p = vec3_mix(*p0, *p1, 0.5);
    box.d = vec3_sub(*p1, box.p);
    for (i = 0; i < 3; i++) {
        box.w = vec3_cross(box.d, AXES[i]);
        if (vec3_norm2(box.w) > 0) break;
    }
    if (i == 3) return box;
    box.w = vec3_mul(vec3_normalized(box.w), r);
    box.h = vec3_mul(vec3_normalized(vec3_cross(box.d, box.w)), r);
    return box;
}
示例#4
0
文件: ray.c 项目: kaspermeerts/cg
/* Various intersection routines. The sphere and cylinder routines are the most
 * mature. */
static int ray_plane_intersect(Ray ray, Plane plane, float t[1], Vec3 normal[1])
{
	float test_t, alpha, beta, det;
	Vec3 a = plane.edge1, b = plane.edge2, d = ray.direction, o = ray.origin;
	Vec3 n, axn, bxn, pos;

	/* This is basically Cramer's rule with vector calculus */
	n = vec3_cross(a, b);
	test_t = -vec3_dot(o, n)/vec3_dot(d, n);
	pos = vec3_add(o, vec3_scale(test_t, d));

	axn = vec3_cross(a, n);
	bxn = vec3_cross(b, n);
	det = vec3_dot(a, bxn);

	alpha =  vec3_dot(pos, bxn)/det;
	beta  = -vec3_dot(pos, axn)/det;

	if (alpha < 0 || alpha > 1 || beta < 0 || beta > 1)
		return 0;

	t[0] = test_t;
	if (vec3_dot(d, n) < 0)
		normal[0] = n;
	else
		normal[0] = vec3_scale(-1, n);

	return 1;
}
t_mat4			mat4_view_lookat(t_vec3 eye, t_vec3 targ, t_vec3 up)
{
	t_mat4		out;
	t_vec3		zaxis;
	t_vec3		xaxis;
	t_vec3		yaxis;

	zaxis = vec3_normal(vec3_sub(eye, targ));
	xaxis = vec3_normal(vec3_cross(up, zaxis));
	yaxis = vec3_cross(zaxis, xaxis);
	out = mat4_ident();
	out.m[0] = xaxis.x;
	out.m[1] = yaxis.x;
	out.m[2] = zaxis.x;
	out.m[4] = xaxis.y;
	out.m[5] = yaxis.y;
	out.m[6] = zaxis.y;
	out.m[8] = xaxis.z;
	out.m[9] = yaxis.z;
	out.m[10] = zaxis.z;
	out.m[12] = -vec3_dot(xaxis, eye);
	out.m[13] = -vec3_dot(yaxis, eye);
	out.m[14] = -vec3_dot(zaxis, eye);
	return (out);
}
static void spherical_lerp(float *v1, float *v2, float d, float *vout)
{
	float v1xv2[3];
	float v3[3];

	float v1_norm = vec3_norm(v1);
	float v2_norm = vec3_norm(v2);
	vec3_normalize(v1);
	vec3_normalize(v2);

	vec3_cross(v1, v2, v1xv2);

	double theta;

	float dot = vec3_dot(v1, v2);
	if (dot > 1) dot = 1;
	theta = acosf(dot);

	if (theta < 0.05) {
		lerp(v1, v2, d, vout);
		return;
	}

	double phi = d * theta;

	vec3_normalize(v1xv2);
	vec3_cross(v1xv2, v1, v3);

	int i = 0;
	float cos_phi = cos(phi);
	float sin_phi = sin(phi);
	for (i = 0; i < 3; i++) {
		vout[i] = (cos_phi * v1[i] + sin_phi * v3[i]) * (v1_norm * (1-d) + v2_norm * d);
	}
}
示例#7
0
/**
 * Component of the support function for a cylinder collider.
 **/
static void
object_support_component_cylinder(object_t *object,
				  float direction[3], float out[3])
{
	float top[3] = { 0, object->h / 2, 0 };
	float bottom[3] = { 0, -object->h / 2, 0 };
	float axis[3];
	float dir_perp[3];
	float trans[16];
	float dot_top;

	object_get_transform_mat(object, trans);

	/* Top and bottom are set to points in the middle of the top and the
	 * bottom faces of the cylinder respectively. We transform them to
	 * their worldspace positions.
	 */
	matrix_vec3_mul(trans, top, 1.0, top);
	matrix_vec3_mul(trans, bottom, 1.0, bottom);

	/* We get an axis vector that runs down the middle of the cylinder. */
	vec3_subtract(top, bottom, axis);

	/* Part of another process, but useful now for a reason... */
	vec3_cross(axis, direction, dir_perp);

	/* If the cross product is zero, our direction is aligned with the
	 * cylinder and top and bottom are our two final candidates.
	 */
	if (vec3_magnitude(dir_perp) > 0) {
		/* This completes what we started with the last cross product.
		 * dir_perp is now a vector perpendicular to the cylinder's
		 * axis, but as close to our selected direction as possible.
		 */
		vec3_cross(dir_perp, axis, dir_perp);

		/* Scale dir_perp to be the radius of our cylinder.
		 */
		vec3_normalize(dir_perp, dir_perp);
		vec3_scale(dir_perp, dir_perp, object->r);

		/* Finally, move top and bottom to the edges of our cylinder in
		 * the appropriate direction. We now have our two final
		 * candidates.
		 */
		vec3_add(dir_perp, top, top);
		vec3_add(dir_perp, bottom, bottom);
	}

	/* We now have two candidates, top and bottom. We can just use largest
	 * dot product to determine which is furthest.
	 */
	dot_top = vec3_dot(top, direction);

	if (dot_top > vec3_dot(bottom, direction))
		memcpy(out, top, 3 * sizeof(float));
	else
		memcpy(out, bottom, 3 * sizeof(float));
}
示例#8
0
文件: camera.c 项目: Drooids/Corange
void camera_control_freecam(camera* c, float timestep) {

  const Uint8* kbstate = SDL_GetKeyboardState(NULL);
  
  if (kbstate[SDL_SCANCODE_W] 
  ||  kbstate[SDL_SCANCODE_S] 
  ||  kbstate[SDL_SCANCODE_A] 
  ||  kbstate[SDL_SCANCODE_D]) {
    
    vec3 cam_dir = vec3_normalize(vec3_sub(c->target, c->position));
    vec3 side_dir = vec3_normalize(vec3_cross(cam_dir, vec3_new(0,1,0)));

    const float speed = 100 * timestep;
    
    if (kbstate[SDL_SCANCODE_W]) {
      c->position = vec3_add(c->position, vec3_mul(cam_dir, speed));
      c->target = vec3_add(c->target, vec3_mul(cam_dir, speed));
    }
    if (kbstate[SDL_SCANCODE_S]) {
      c->position = vec3_sub(c->position, vec3_mul(cam_dir, speed));
      c->target = vec3_sub(c->target, vec3_mul(cam_dir, speed));
    }
    if (kbstate[SDL_SCANCODE_D]) {
      c->position = vec3_add(c->position, vec3_mul(side_dir, speed));
      c->target = vec3_add(c->target, vec3_mul(side_dir, speed));
    }
    if (kbstate[SDL_SCANCODE_A]) {
      c->position = vec3_sub(c->position, vec3_mul(side_dir, speed));
      c->target = vec3_sub(c->target, vec3_mul(side_dir, speed));
    }
    
  }
  
  int mouse_x, mouse_y;
  Uint8 mstate = SDL_GetRelativeMouseState(&mouse_x, &mouse_y);
  if (mstate & SDL_BUTTON(1)) {
  
    float a1 = -(float)mouse_x * 0.005;
    float a2 = (float)mouse_y * 0.005;
    
    vec3 cam_dir = vec3_normalize(vec3_sub(c->target, c->position));
    
    cam_dir.y += -a2;
    vec3 side_dir = vec3_normalize(vec3_cross(cam_dir, vec3_new(0,1,0)));
    cam_dir = vec3_add(cam_dir, vec3_mul(side_dir, -a1));
    cam_dir = vec3_normalize(cam_dir);
    
    c->target = vec3_add(c->position, cam_dir);
  }
}
示例#9
0
/* Manually apply a look-at matrix. Will reset MODELVIEW automatically. */
void cm_apply_look_at(VEC3 target, VEC3 position)
{
  VEC3 forward = vec3_normalize(vec3_subtract(target, position));
  VEC3 right = vec3_cross(forward, (VEC3){ 0, 1, 0 });
  VEC3 up = vec3_normalize(vec3_cross(forward, right));
  double ang = atan(NOT_DUMB_ABS(forward.y) / sqrt(forward.x * forward.x + forward.z * forward.z));
  if (ang >= PI_O4)
  {
    up = vec3_negate(up);
  }

  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
  gluLookAt(position.x, position.y, position.z, target.x, target.y, target.z, up.x, up.y, up.z);
}
示例#10
0
/* Calculate the quaternion to rotate from vector u to vector v */
void quat_from_u2v(union quat *q, const union vec3 *u, const union vec3 *v, const union vec3 *up)
{
	union vec3 un, vn, axis, axisn;
	float dot;
	float angle;

	vec3_normalize(&un, u);
	vec3_normalize(&vn, v);
	dot = vec3_dot(&un, &vn);
	if (fabs(dot - -1.0f) < ZERO_TOLERANCE) {
		/* vector a and b point exactly in the opposite direction
		 * so it is a 180 degrees turn around the up-axis
		 */
		union vec3 default_up = { { 0, 1, 0} };
		if (!up)
			up = &default_up;
		quat_init_axis(q, up->v.x, up->v.y, up->v.z, M_PI);
		return;
	}
	if (fabs(dot - 1.0f) < ZERO_TOLERANCE) {
		/* vector a and b point exactly in the same direction
		 * so we return the identity quaternion
		 */
		*q = identity_quat;
		return;
	}
	angle = acos(dot);
	vec3_cross(&axis, &un, &vn);
	vec3_normalize(&axisn, &axis);
	quat_init_axis(q, axisn.v.x, axisn.v.y, axisn.v.z, angle);
}
示例#11
0
static int _llfunc_vec3_cross(lua_State *L) {
	vec3 *a = (vec3*)userdata_get_or_die(L, 1);
	vec3 *b = (vec3*)userdata_get_or_die(L, 2);
	vec3 *r = (vec3*)userdata_get_or_new(L, 3, sizeof(vec3));
	vec3_cross(a, b, r);
	return 1;
}
示例#12
0
void camera_control_joyorbit(camera* c, float timestep) {
  
  if (joystick_count() == 0) return;
  
  SDL_Joystick* mainstick = joystick_get(0);
  int x_move = SDL_JoystickGetAxis(mainstick, 0);
  int y_move = SDL_JoystickGetAxis(mainstick, 1);
  
  /* Dead Zone */
  if (abs(x_move) < 10000) { x_move = 0; };
  if (abs(y_move) < 10000) { y_move = 0; };
  
  float a1 = (x_move / 32768.0) * -0.05;
  float a2 = (y_move / 32768.0) * 0.05;
  
  vec3 translation = c->target;
  c->position = vec3_sub(c->position, translation);
  c->target = vec3_sub(c->target, translation);
  
  c->position = mat3_mul_vec3(mat3_rotation_y( a1 ), c->position );
  vec3 axis = vec3_normalize(vec3_cross( vec3_sub(c->position, c->target) , vec3_new(0,1,0) ));
  c->position = mat3_mul_vec3(mat3_rotation_axis_angle(axis, a2 ), c->position );
  
  c->position = vec3_add(c->position, translation);
  c->target = vec3_add(c->target, translation);

}
示例#13
0
文件: geom.c 项目: jsgf/terrain
void quat_vector_vector(quat_t *q, const vec3_t *a, const vec3_t *b)
{
	float cost = vec3_dot(a, b);

	if (cost > 0.99999f) {
		/* parallel */
		*q = QUAT_IDENT;
	} else if (cost < -0.99999f) {
		/* opposite */
		vec3_t t = VEC3(0, a->x, -a->y); /* cross with (1,0,0) */
		if (vec3_magnitude(&t) < EPSILON)
			t = VEC3(-a->z, 0, a->x); /* nope, use (0,1,0) */

		vec3_normalize(&t);

		q->v = t;
		q->w = 0.f;
	} else {
		vec3_t t;

		vec3_cross(&t, a, b);
		vec3_normalize(&t);

		/* sin^2 t = (1 - cos(2t)) / 2 */
		float ss = sqrt(.5f * (1.f - cost));
		vec3_scale(&t, ss);
		q->v = t;

		/* cos^2 t = (1 + cos(2t) / 2 */
		q->w = sqrt(.5f * (1.f + cost));
	}
}
示例#14
0
文件: face3.cpp 项目: Calinou/godot
bool Face3::intersects_aabb(const AABB &p_aabb) const {

	/** TEST PLANE **/
	if (!p_aabb.intersects_plane(get_plane()))
		return false;

#define TEST_AXIS(m_ax)                                            \
	/** TEST FACE AXIS */                                          \
	{                                                              \
		real_t aabb_min = p_aabb.position.m_ax;                    \
		real_t aabb_max = p_aabb.position.m_ax + p_aabb.size.m_ax; \
		real_t tri_min = vertex[0].m_ax;                           \
		real_t tri_max = vertex[0].m_ax;                           \
		for (int i = 1; i < 3; i++) {                              \
			if (vertex[i].m_ax > tri_max)                          \
				tri_max = vertex[i].m_ax;                          \
			if (vertex[i].m_ax < tri_min)                          \
				tri_min = vertex[i].m_ax;                          \
		}                                                          \
                                                                   \
		if (tri_max < aabb_min || aabb_max < tri_min)              \
			return false;                                          \
	}

	TEST_AXIS(x);
	TEST_AXIS(y);
	TEST_AXIS(z);

	/** TEST ALL EDGES **/

	Vector3 edge_norms[3] = {
		vertex[0] - vertex[1],
		vertex[1] - vertex[2],
		vertex[2] - vertex[0],
	};

	for (int i = 0; i < 12; i++) {

		Vector3 from, to;
		p_aabb.get_edge(i, from, to);
		Vector3 e1 = from - to;
		for (int j = 0; j < 3; j++) {
			Vector3 e2 = edge_norms[j];

			Vector3 axis = vec3_cross(e1, e2);

			if (axis.length_squared() < 0.0001)
				continue; // coplanar
			axis.normalize();

			real_t minA, maxA, minB, maxB;
			p_aabb.project_range_in_plane(Plane(axis, 0), minA, maxA);
			project_range(axis, Transform(), minB, maxB);

			if (maxA < minB || maxB < minA)
				return false;
		}
	}
	return true;
}
示例#15
0
文件: camera.c 项目: Drooids/Corange
void camera_control_orbit(camera* c, SDL_Event e) {
  
  float a1 = 0;
  float a2 = 0;
  vec3 axis;
  
  vec3 translation = c->target;
  c->position = vec3_sub(c->position, translation);
  c->target = vec3_sub(c->target, translation);
  
  switch(e.type) {
    
    case SDL_MOUSEMOTION:
      if (e.motion.state & SDL_BUTTON(1)) {
        a1 = e.motion.xrel * -0.005;
        a2 = e.motion.yrel * 0.005;
        c->position = mat3_mul_vec3(mat3_rotation_y( a1 ), c->position );
        axis = vec3_normalize(vec3_cross( vec3_sub(c->position, c->target) , vec3_new(0,1,0) ));
        c->position = mat3_mul_vec3(mat3_rotation_angle_axis(a2, axis), c->position );
      }
    break;
    
    case SDL_MOUSEWHEEL:
      c->position = vec3_add(c->position, vec3_mul(vec3_normalize(c->position), -e.wheel.y));
    break;

  }
  
  c->position = vec3_add(c->position, translation);
  c->target = vec3_add(c->target, translation);

}
示例#16
0
void scotland_update() {
  
  camera* cam = entity_get("camera");
  light* sun = entity_get("sun");
  static_object* skydome = entity_get("skydome");
  landscape* world = entity_get("world");
  
  sun_orbit += frame_time() * 0.01;
  
  sun->position.x = 512 + sin(sun_orbit) * 512;
  sun->position.y = cos(sun_orbit) * 512;
  sun->position.z = 512;
  sun->target = vec3_new(512, 0, 512);
  
  if (w_held || s_held) {
    
    vec3 cam_dir = vec3_normalize(vec3_sub(cam->target, cam->position));
    float speed = 0.5;
    if (!freecam) speed = 0.05;
    if (w_held) {
      cam->position = vec3_add(cam->position, vec3_mul(cam_dir, speed));
    }
    if (s_held) {
      cam->position = vec3_sub(cam->position, vec3_mul(cam_dir, speed));
    }
    
    if (!freecam) {
      float height = terrain_height(asset_hndl_ptr(world->terrain), vec2_new(cam->position.x, cam->position.z));
      cam->position.y = height + 1;
    }
    
    cam->target = vec3_add(cam->position, cam_dir);
  }
  
  Uint8 keystate = SDL_GetMouseState(NULL, NULL);
  if(keystate & SDL_BUTTON(1)){
  
    float a1 = -(float)mouse_x * 0.005;
    float a2 = (float)mouse_y * 0.005;
    
    vec3 cam_dir = vec3_normalize(vec3_sub(cam->target, cam->position));
    
    cam_dir.y += -a2;
    vec3 side_dir = vec3_normalize(vec3_cross(cam_dir, vec3_new(0,1,0)));
    cam_dir = vec3_add(cam_dir, vec3_mul(side_dir, -a1));
    cam_dir = vec3_normalize(cam_dir);
    
    cam->target = vec3_add(cam->position, cam_dir);
  }
  
  mouse_x = 0;
  mouse_y = 0;
  
  ui_button* framerate = ui_elem_get("framerate");
  ui_button_set_label(framerate, frame_rate_string());
}
示例#17
0
/*
=======================================================================================================================================
BaseWindingForPlane
=======================================================================================================================================
*/
winding_t *BaseWindingForPlane(vec3_t normal, vec_t dist) {
	int i, x = -1;
	vec_t max = -MAX_MAP_BOUNDS, v;
	vec3_t org, vright, vup;
	winding_t *w;

	// find the major axis
	for (i = 0; i < 3; i++) {
		v = Q_fabs(normal[i]);

		if (v > max) {
			x = i;
			max = v;
		}
	}

	if (x == -1) {
		Com_Error(ERR_DROP, "BaseWindingForPlane: no axis found");
	}

	VectorCopy(vec3_origin, vup);

	switch (x) {
		case 0:
		case 1:
			vup[2] = 1;
			break;
		case 2:
			vup[0] = 1;
			break;
	}

	v = DotProduct(vup, normal);

	VectorMA(vup, -v, normal, vup);
	vec3_norm2(vup, vup);
	VectorScale(normal, dist, org);
	vec3_cross(vup, normal, vright);
	VectorScale(vup, MAX_MAP_BOUNDS, vup);
	VectorScale(vright, MAX_MAP_BOUNDS, vright);
	// project a really big axis aligned box onto the plane
	w = AllocWinding(4);

	VectorSubtract(org, vright, w->p[0]);
	VectorAdd(w->p[0], vup, w->p[0]);
	VectorAdd(org, vright, w->p[1]);
	VectorAdd(w->p[1], vup, w->p[1]);
	VectorAdd(org, vright, w->p[2]);
	VectorSubtract(w->p[2], vup, w->p[2]);
	VectorSubtract(org, vright, w->p[3]);
	VectorSubtract(w->p[3], vup, w->p[3]);

	w->numpoints = 4;

	return w;
}
示例#18
0
/*
=======================================================================================================================================
WindingPlane
=======================================================================================================================================
*/
void WindingPlane(winding_t *w, vec3_t normal, vec_t *dist) {
	vec3_t v1, v2;

	VectorSubtract(w->p[1], w->p[0], v1);
	VectorSubtract(w->p[2], w->p[0], v2);
	vec3_cross(v2, v1, normal);
	vec3_norm2(normal, normal);

	*dist = DotProduct(w->p[0], normal);
}
示例#19
0
文件: polygon.c 项目: vvs-/OpenTomb
void Polygon_FindNormale(polygon_p p)
{
    float v1[3], v2[3];

    vec3_sub(v1, p->vertices[1].position, p->vertices[0].position);
    vec3_sub(v2, p->vertices[2].position, p->vertices[1].position);
    vec3_cross(p->plane, v1, v2);
    p->plane[3] = -vec3_abs(p->plane);
    vec3_norm_plane(p->plane, p->vertices[0].position, p->plane[3]);
}
示例#20
0
/* for a plane defined by n=normal, return a u and v vector that is on that plane and perpendictular */
void plane_vector_u_and_v_from_normal(union vec3 *u, union vec3 *v, const union vec3 *n)
{
	union vec3 basis = { { 1, 0, 0 } };

	/* find a vector we can use for our basis to define v */
	float dot = vec3_dot(n, &basis);
	if (fabs(dot) >= 1.0 - ZERO_TOLERANCE) {
		/* if forward is parallel, we can use up */
		vec3_init(&basis, 0, 1, 0);
	}

	/* find the right vector from our basis and the normal */
	vec3_cross(v, &basis, n);
	vec3_normalize_self(v);

	/* now the final forward vector is perpendicular n and v */
	vec3_cross(u, n, v);
	vec3_normalize_self(u);
}
示例#21
0
文件: plane.cpp 项目: Paulloz/godot
bool Plane::intersect_3(const Plane &p_plane1, const Plane &p_plane2, Vector3 *r_result) const {

	const Plane &p_plane0 = *this;
	Vector3 normal0 = p_plane0.normal;
	Vector3 normal1 = p_plane1.normal;
	Vector3 normal2 = p_plane2.normal;

	real_t denom = vec3_cross(normal0, normal1).dot(normal2);

	if (ABS(denom) <= CMP_EPSILON)
		return false;

	if (r_result) {
		*r_result = ((vec3_cross(normal1, normal2) * p_plane0.d) +
							(vec3_cross(normal2, normal0) * p_plane1.d) +
							(vec3_cross(normal0, normal1) * p_plane2.d)) /
					denom;
	}

	return true;
}
示例#22
0
/*
Create a new buffer object from an array of vec3s for pts, and vec3s for texture coordinates.
Faces is an array of 3 shorts for each face.
*/
BUFFER_T *buffer_new(float pts[][3], float tex[][3], short faces[][3], int numpts, int numfaces)
{
    int i;
    float normals[numpts][3];
    BUFFER_T *buf;
    NEW(buf);

    for(i=0; i<numpts; i++)
    {
        normals[i][0]=0;
        normals[i][1]=0;
        normals[i][2]=1;
    }
    for(i=0; i<numfaces; i++)
    {
        int a = faces[i][0];
        int b = faces[i][1];
        int c = faces[i][2];
        float tmp[3];
        float tmp2[3];
        float n[3];
        vec3_sub(tmp,pts[b],pts[a]);
        vec3_sub(tmp2,pts[c],pts[a]);
        vec3_cross(n,tmp,tmp2);
        vec3_normal(n,n);
        vec3_copy(normals[a],n);
        vec3_copy(normals[b],n);
        vec3_copy(normals[c],n);
    }
    float B[3*3*numpts];
    for(i=0; i<numpts; i++)
    {
        for(int j=0; j<3; j++)
        {
            B[i*3*3+j]=pts[i][j];
            B[i*3*3+3+j]=tex[i][j];
            B[i*3*3+6+j]=normals[i][j];
        }
    }

    buf->ntris=numfaces;
    glGenBuffers(1,&buf->vbuf);
    glBindBuffer(GL_ARRAY_BUFFER, buf->vbuf);
    glBufferData(GL_ARRAY_BUFFER, 36*numpts, B, GL_STATIC_DRAW);
    buf->vbuf_num = numpts;

    glGenBuffers(1,&buf->ebuf);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buf->ebuf);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, 6*numfaces, faces, GL_STATIC_DRAW);
    buf->ebuf_num = numfaces*3;

    return buf;
}
示例#23
0
bool hitscan_sprite_mobs(const Vec3& position, const Vec3& direction, float range,
                         SpriteMobID& id, float& distance, Vec3& collision_point)
{
    SpriteMobID nearest_mob = NULL_SPRITE_MOB;
    float nearest_distance = 100000.0f;
    Vec3 nearest_collision_point = vec3_init(0);
    const float range_sq = range * range;
    const Vec3 up = vec3_init(0, 0, 1);
    for (size_t i=0, j=0; i<sprite_mob_list->max && j<sprite_mob_list->count; i++)
    {   // TODO
        // do a line-plane intersection test against the mob, if its in frustum
        SpriteMob* m = sprite_mob_list->objects[i];
        if (m == NULL) continue;
        j++;

        Vec3 p = m->get_center();
        p = quadrant_translate_position(position, p);

        if (vec3_distance_squared(position, p) > range_sq)
            continue;

        float rad_sq = 10000.0f;
        Vec3 line_point = vec3_init(0);
        if (!sphere_line_distance(position, direction, p, line_point, rad_sq))
            continue;

        Vec3 forward = vec3_sub(position, p);
        forward.z = 0.0f;
        if (unlikely(vec3_length_squared(forward) == 0))
            continue;
        forward = vec3_normalize(forward);
        const Vec3 right = vec3_normalize(vec3_cross(forward, up));

        float d = 1000000.0f;
        float width = get_mob_width(m->type) * 0.5f;
        float height = get_mob_height(m->type) * 0.5f;
        if (!line_plane_intersection(position, direction, p, width, height,
                                     forward, right, up, d))
            continue;

        if (d >= nearest_distance)
            continue;

        nearest_distance = d;
        nearest_mob = m->id;
        nearest_collision_point = line_point;
    }

    id = nearest_mob;
    distance = nearest_distance;
    collision_point = translate_position(nearest_collision_point);
    return (nearest_mob != NULL_SPRITE_MOB);
}
示例#24
0
文件: hw4.c 项目: SeMo810/CSCI-4229
static void draw_gui()
{
  glColor3d(1, 1, 1);
  VEC3 cfwd = cm_get_fps_camera_forward(fcamera);
  VEC3 cright = cm_get_fps_camera_right(fcamera);
  VEC3 cup = vec3_cross(cright, cfwd);
  rh_draw_window_text((VEC2){ 3, 3 }, "Camera Type: %s", camera_type == 1 ? "Perspective Target" : (camera_type == 2 ? "Orthographic Target" : "Perspective FPS"));
  rh_draw_window_text((VEC2){ 3, 25}, "Camera Position: (%f,%f,%f)", fcamera.position.x, fcamera.position.y, fcamera.position.z);
  rh_draw_window_text((VEC2){ 3, 50}, "Camera Forward: (%f,%f,%f)", cfwd.x, cfwd.y, cfwd.z);
  rh_draw_window_text((VEC2){ 3, 75}, "Camera Right: (%f,%f,%f)", cright.x, cright.y, cright.z);
  rh_draw_window_text((VEC2){ 3, 100}, "Camera Up: (%f,%f,%f)", cup.x, cup.y, cup.z);
}
示例#25
0
/* Calculate the quaternion to rotate from vector u to vector v */
void quat_from_u2v(union quat *q, const union vec3 *u, const union vec3 *v, const union vec3 *up)
{
	/* See: http://lolengine.net/blog/2013/09/18/beautiful-maths-quaternion-from-vectors */
	union vec3 w;

	vec3_cross(&w, u, v);
	q->v.w = vec3_dot(u, v);
	q->v.x = w.v.x;
	q->v.y = w.v.y;
	q->v.z = w.v.z;
	q->v.w += quat_len(q);
	quat_normalize_self(q);
}
示例#26
0
void plane_from_tri(struct plane *dst,
                    const struct vec3 *v1,
                    const struct vec3 *v2,
                    const struct vec3 *v3)
{
	struct vec3 temp;

	vec3_sub(&temp, v2, v1);
	vec3_sub(&dst->dir, v3, v1);
	vec3_cross(&dst->dir, &temp, &dst->dir);
	vec3_norm(&dst->dir, &dst->dir);
	dst->dist = vec3_dot(v1, &dst->dir);
}
示例#27
0
文件: polygon.c 项目: vvs-/OpenTomb
int Polygon_RayIntersect(polygon_p p, float dir[3], float dot[3], float *t)
{
    float tt, u, v, E1[3], E2[3], P[3], Q[3], T[3];
    vertex_p vp;

    u = vec3_dot(p->plane, dir);
    if(fabs(u) < 0.001 /*|| vec3_plane_dist(p->plane, dot) < -0.001*/)          // FIXME: magick
    {
        return 0;                                                               // plane is parallel to the ray - no intersection
    }
    *t = - vec3_plane_dist(p->plane, dot);
    *t /= u;

    vp = p->vertices;                                                           // current polygon pointer
    vec3_sub(T, dot, vp[0].position);

    vec3_sub(E2, vp[1].position, vp[0].position)
    for(uint16_t i = 0; i < p->vertex_count - 2; i++, vp++)
    {
        vec3_copy(E1, E2)                                                       // PREV
        vec3_sub(E2, vp[2].position, p->vertices[0].position)                   // NEXT

        vec3_cross(P, dir, E2)
        vec3_cross(Q, T, E1)

        tt = vec3_dot(P, E1);
        u = vec3_dot(P, T);
        u /= tt;
        v = vec3_dot(Q, dir);
        v /= tt;
        tt = 1.0 - u - v;
        if((u <= 1.0) && (u >= 0.0) && (v <= 1.0) && (v >= 0.0) && (tt <= 1.0) && (tt >= 0.0))
        {
            return 1;
        }
    }
    return 0;
}
示例#28
0
t_vec3			bump_normal(t_obj *obj, t_ray *ray)
{
	t_vec3		normal;
	t_vec3		tangent;
	t_vec3		binormal;
	t_vec3		bump;
	t_vec3		c[2];

	normal = obj->normal;
	bump = texture_mapping(obj, obj->mat.texture.bump, ray->hit);
	bump = vec3_sub(vec3_fmul(bump, 2), vec3(1, 1, 1));
	c[0] = vec3_cross(normal, vec3(0, 0, 1));
	c[1] = vec3_cross(normal, vec3(0, 1, 0));
	tangent = (vec3_magnitude(c[0]) > vec3_magnitude(c[1]) ? c[0] : c[1]);
	tangent = vec3_sub(tangent, vec3_fmul(normal, vec3_dot(tangent, normal)));
	vec3_normalize(&tangent);
	binormal = vec3_norm(vec3_cross(normal, tangent));
	normal.x = vec3_dot(bump, vec3(tangent.x, binormal.x, normal.x));
	normal.y = vec3_dot(bump, vec3(tangent.y, binormal.y, normal.y));
	normal.z = vec3_dot(bump, vec3(tangent.z, binormal.z, normal.z));
	vec3_normalize(&normal);
	return (normal);
}
示例#29
0
/*
=======================================================================================================================================
WindingArea
=======================================================================================================================================
*/
vec_t WindingArea(winding_t *w) {
	int i;
	vec3_t d1, d2, cross;
	vec_t total = 0;

	for (i = 2; i < w->numpoints; i++) {
		VectorSubtract(w->p[i - 1], w->p[0], d1);
		VectorSubtract(w->p[i], w->p[0], d2);
		vec3_cross(d1, d2, cross);
		total += 0.5f * vec3_length(cross);
	}

	return total;
}
示例#30
0
void matrix_4x4_lookat(math_matrix_4x4 *out,
      vec3_t eye,
      vec3_t center,
      vec3_t up)
{
   vec3_t zaxis;   /* the "forward" vector */
   vec3_t xaxis;   /* the "right"   vector */
   vec3_t yaxis;   /* the "up"      vector */

   vec3_copy(&zaxis[0], center);
   vec3_subtract(&zaxis[0], eye);
   vec3_normalize(&zaxis[0]);

   vec3_cross(&xaxis[0], &zaxis[0], up);
   vec3_normalize(&xaxis[0]);
   vec3_cross(&yaxis[0], &xaxis[0], zaxis);

   MAT_ELEM_4X4(*out, 0, 0) = xaxis[0];
   MAT_ELEM_4X4(*out, 0, 1) = yaxis[0];
   MAT_ELEM_4X4(*out, 0, 2) = -zaxis[0];
   MAT_ELEM_4X4(*out, 0, 3) = 0.0;

   MAT_ELEM_4X4(*out, 1, 0) = xaxis[1];
   MAT_ELEM_4X4(*out, 1, 1) = yaxis[1];
   MAT_ELEM_4X4(*out, 1, 2) = -zaxis[1];
   MAT_ELEM_4X4(*out, 1, 3) = 0.0f;

   MAT_ELEM_4X4(*out, 2, 0) = xaxis[2];
   MAT_ELEM_4X4(*out, 2, 1) = yaxis[2];
   MAT_ELEM_4X4(*out, 2, 2) = -zaxis[2];
   MAT_ELEM_4X4(*out, 2, 3) = 0.0f;

   MAT_ELEM_4X4(*out, 3, 0) = -(xaxis[0] * eye[0] + xaxis[1] * eye[1] + xaxis[2] * eye[2]);
   MAT_ELEM_4X4(*out, 3, 1) = -(yaxis[0] * eye[0] + yaxis[1] * eye[1] + yaxis[2] * eye[2]);
   MAT_ELEM_4X4(*out, 3, 2) = -(zaxis[0] * eye[0] + zaxis[1] * eye[1] + zaxis[2] * eye[2]);
   MAT_ELEM_4X4(*out, 3, 3) = 1.f;
}