Exemplo n.º 1
0
static void camOrbit(int dx, int dy)
{
	const double radius = 200;
	double dist;
	Vec3 v = cam_position;
	Quaternion o = cam_orientation;
	Quaternion q, q2;

	/* We invert the transformation because we are transforming the camera
	 * and not the scene. */
	q = quat_conjugate(quat_trackball(dx, dy, radius));

	/* The quaternion q gives us an intrinsic transformation, close to unity.
	 * To make it extrinsic, we compute q2 = o * q * ~o */
	q2 = quat_multiply(o, quat_multiply(q, quat_conjugate(o)));
	q2 = quat_normalize(q2);

	/* As round-off errors accumulate, the distance between the camera and the
	 * target would normally fluctuate. We take steps to prevent that here. */
	dist = vec3_length(v);
	v = quat_transform(q2, v);
	v = vec3_normalize(v);
	v = vec3_scale(v, dist);

	cam_position = v;
	cam_orientation = quat_multiply(q2, cam_orientation);
}
Exemplo n.º 2
0
static void camDolly(int dz)
{
	Vec3 v = cam_position;

	v = vec3_scale(v, exp(-0.1*dz));
	cam_position = v;
}
Exemplo n.º 3
0
int						collision_test_sphere(t_ray_result *r,
											  t_sphere *sphere)
{
	t_real				a;
	t_real				b;
	t_real				c;
	t_real				det;

	a = collision_test_sphere_a(&r->ray.direction);
	b = collision_test_sphere_b(&r->ray, &sphere->position);
	c = collision_test_sphere_c(&r->ray, sphere);

	det = ft_pow(b, 2) - (4 * a * c);
	if (!det)
		r->distance = -(b / 2 * a);
	else if (det > 0)
		r->distance = FT_MIN((-b - sqrt(det)) / (2 * a),
							 (-b + sqrt(det)) / (2 * a));
	else
		return (0);
	r->hit = OT_SPHERE;
	r->contact.point = vec3_add(r->ray.origin,
								vec3_scale(r->ray.direction, r->distance));
	return (1);
}
Exemplo n.º 4
0
void generate_debug_geometry(vector_buffer *vertices, vector_buffer *normals, geometry* out)
{
    float temp[3];

    vector_buffer debug;
    vector_init(&debug);

    for(int i = 0; i < out->vertex_count; ++i)
    {
        vec3_scale(vector_get(normals, i), 0.05f, temp);
        vec3_add(vector_get(vertices, i), temp, temp);

        vector_append(&debug, vector_get(vertices, i));
        vector_append(&debug, temp);
    }

    out->debug_geometry.attributes.position = 3;
    make_buffer(out->debug_geometry.attributes.position, &out->debug_geometry.vertex_buffer, debug.data , (GLsizei) (out->vertex_count * 3 * 2 * sizeof(float)));

    out->debug_geometry.vertex_shader = make_shader(GL_VERTEX_SHADER, "shaders/debug_shader.v.glsl");
    out->debug_geometry.fragment_shader = make_shader(GL_FRAGMENT_SHADER, "shaders/debug_shader.f.glsl");

    out->debug_geometry.program = make_program(out->debug_geometry.vertex_shader, out->debug_geometry.fragment_shader);

    glBindAttribLocation(out->debug_geometry.program, out->debug_geometry.attributes.position, "position");

    glLinkProgram(out->debug_geometry.program);

    out->debug_geometry.uniform.mvp_matrix = glGetUniformLocation(out->program, "mvp_matrix");
}
Exemplo n.º 5
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));
}
Exemplo n.º 6
0
CollisionResult collision_ray_scene_invert(const Ray* ray, const Scene* scene) {
	CollisionResult r = collision_ray_scene(ray, (const Scene*)scene->data);
	if (r.type == None) {
		return r;
	} else if (r.type == Enter) {
		r.type = Exit;
		r.normal = vec3_scale(&r.normal, (FPType)-1);
		return r;
	} else if (r.type == Exit) {
		r.type = Enter;
		r.normal = vec3_scale(&r.normal, (FPType)-1);
		return r;
	} else {
		assert(!"unexpected line reached");
		return r;
	}
}
Exemplo n.º 7
0
Arquivo: geom.c Projeto: jsgf/terrain
void quat_mult(quat_t *r, const quat_t *a, const quat_t *b)
{
	quat_t ret;
	vec3_t t;

	ret.w = a->w * b->w - vec3_dot(&a->v, &b->v);
	vec3_cross(&ret.v, &a->v, &b->v);

	t = a->v;
	vec3_scale(&t, b->w);
	vec3_add(&ret.v, &ret.v, &t);

	t = b->v;
	vec3_scale(&t, a->w);
	vec3_add(&ret.v, &ret.v, &t);

	*r = ret;
}
Exemplo n.º 8
0
static int ray_mesh_intersect(Ray ray, const Mesh *mesh, float *t, Vec3 *normal)
{
	struct TriangleHit tri_hit;

	if (ray_kd_tree_intersect(ray, mesh->vertex, mesh->kd_tree, &tri_hit))
	{
		Triangle tri = tri_hit.triangle;
		*t = tri_hit.t;
		*normal = vec3_add(vec3_add(
				vec3_scale(tri_hit.a, mesh->normal[tri.normal_index[0]]),
				vec3_scale(tri_hit.b, mesh->normal[tri.normal_index[1]])),
				vec3_scale(tri_hit.c, mesh->normal[tri.normal_index[2]]));
		return 1;
	}

	return 0;

}
Exemplo n.º 9
0
Arquivo: geom.c Projeto: jsgf/terrain
void quat_normalize(quat_t *q)
{
	float m = q->w * q->w + vec3_dot(&q->v, &q->v);

	m = 1.f / m;

	q->w *= m;
	vec3_scale(&q->v, m);
}
Exemplo n.º 10
0
Arquivo: geom.c Projeto: jsgf/terrain
void quat_axis_angle(quat_t *q, const vec3_t *v, float angle)
{
	float s, c;
	sincosf(angle/2, &s, &c);

	q->w = c;
	q->v = *v;
	vec3_normalize(&q->v);
	vec3_scale(&q->v, s);
}
Exemplo n.º 11
0
void marching_cubes(float threshold, scan_data *data, int debug, geometry* out) {

    float temp[3];

    vector_buffer vertices;
    vector_buffer normals;

    vector_init(&vertices);
    vector_init(&normals);

    for (size_t x = 0; x < data->length; x++)
        for (size_t y = 0; y < data->width; y++)
            for (size_t z = 0; z < data->height; z++) {
                march_cube(x, y, z, step_size, threshold, data, &vertices, &normals);
            }

    out->vertex_count = (GLuint) vertices.size;
    out->attributes.position = 0;
    out->attributes.normal = 1;

    make_buffer(out->attributes.position, &out->vertex_buffer, vertices.data , (GLsizei) (out->vertex_count * 3 * sizeof(float)));
    make_buffer(out->attributes.normal, &out->vertex_buffer, normals.data , (GLsizei) (out->vertex_count * 3 * sizeof(float)));

    out->vertex_shader = make_shader(GL_VERTEX_SHADER, "shaders/diffuse_shader.v.glsl");
    out->fragment_shader = make_shader(GL_FRAGMENT_SHADER, "shaders/diffuse_shader.f.glsl");

    out->program = make_program(out->vertex_shader, out->fragment_shader);

    glBindAttribLocation(out->program, out->attributes.position, "position");
    glBindAttribLocation(out->program, out->attributes.normal, "normal");

    glLinkProgram(out->program);

    out->uniform.mvp_matrix = glGetUniformLocation(out->program, "mvp_matrix");
    out->uniform.normal_matrix = glGetUniformLocation(out->program, "normal_matrix");

    out->center[0] = 0.0f;
    out->center[1] = 0.0f;
    out->center[2] = 0.0f;

    for(size_t i = 0; i < out->vertex_count; ++i)
    {
        vec3_scale(vertices.data[i], -1.0f / out->vertex_count, temp);
        vec3_add(out->center, temp, out->center);
    }

    if(debug)
    {
        generate_debug_geometry(&vertices, &normals, out);
    }

    vector_free(&vertices);
    vector_free(&normals);
}
Exemplo n.º 12
0
static inline void _move_camera(game *g, direction d) {
    vec3 temp;
    switch (d) {
        case (UP):
            vec3_scale(temp, g->d.view_u, g->d.trans);
            break;
        case(DOWN):
            vec3_scale(temp, g->d.view_u, -g->d.trans);
            break;
        case(LEFT):
            vec3_scale(temp, g->d.view_r, -g->d.trans);
            break;
        case(RIGHT):
            vec3_scale(temp, g->d.view_r, g->d.trans);
            break;
    }
    vec3_add(g->d.eye, g->d.eye, temp);
    vec3_add(g->d.eye_zoom, g->d.eye_zoom, temp);
    vec3_add(g->d.center, g->d.center, temp);
}
Exemplo n.º 13
0
/**
 * GJK collision support function.
 **/
static void
object_support(object_t *a, object_t *b, float direction[3], float out[3])
{
	float pa[3];
	float pb[3];

	object_support_component(a, direction, pa);
	vec3_scale(direction, direction, -1);
	object_support_component(b, direction, pb);
	vec3_subtract(pa, pb, out);
}
Exemplo n.º 14
0
Arquivo: geom.c Projeto: jsgf/terrain
void vec3_normalize(vec3_t *v)
{
	float len = vec3_magnitude(v);

	if (len < 1.e-5)
		return;

	len = 1.f / len;

	vec3_scale(v, len);
}
Exemplo n.º 15
0
Arquivo: bullet.c Projeto: lcthums/C3D
int bullet_updatePosition(bullet* B, unsigned int frameTime) {
	B->distanceTraveled += frameTime * B->frameDistance;
	vec3 velocity;
	vec3_scale(velocity, B->direction, frameTime * B->specs->speed);
	B->position[0] += velocity[0];
	B->position[1] += velocity[1];
	B->position[2] += velocity[2];
	mesh_translate_from_origin(B->model, B->position[0], B->position[1], B->position[2]);
	
	if (B->distanceTraveled < B->specs->maximumTravelDistance)
		return 1;
	else
		return 0;
}
Exemplo n.º 16
0
bool sphere::intersect(const ray& ray, const range& r, surface_hit* hit)
{
    float t = sphere_intersect(center, radius, ray, r);

    if(t == NO_t)
        return false;

    if(t > hit->t)
        return false;

    if(keep_stats) sphere_shadings++;

    vec3 point = vec3_add(ray.o, vec3_scale(ray.d, t));
    // snap to sphere surface
    vec3 to_surface = vec3_subtract(point, center);
    float distance = sqrtf(vec3_dot(to_surface, to_surface));
    hit->point = vec3_add(center, vec3_scale(to_surface, radius / distance));
    hit->normal = vec3_divide(to_surface, radius);
    hit->color = color;
    hit->t = t;

    return true;
}
Exemplo n.º 17
0
Arquivo: geom.c Projeto: jsgf/terrain
void matrix_project(const matrix_t *m, const vec3_t *in, vec3_t *out)
{
	vec3_t t;
	float w;

	t.x = m->m[0] * in->x + m->m[4] * in->y + m->m[ 8] * in->z + m->m[12];
	t.y = m->m[1] * in->x + m->m[5] * in->y + m->m[ 9] * in->z + m->m[13];
	t.z = m->m[2] * in->x + m->m[6] * in->y + m->m[10] * in->z + m->m[14];
	w   = m->m[3] * in->x + m->m[7] * in->y + m->m[11] * in->z + m->m[15];

	if (w != 0.f)
		vec3_scale(&t, 1.f/w);

	*out = t;
}
Exemplo n.º 18
0
static inline void _calc_zoom(game *g, int dir) {
    g->d.zoom_level += dir;
    g->d.zoom = pow(g->d.zoom_amount, g->d.zoom_level - (g->d.ortho ? 0 : 6));
    _update_translations(g);

    float zoom = 1 / g->d.zoom;
    if (g->d.ortho) {
        mat4x4_ortho(g->d.proj, -g->aspect * zoom, g->aspect * zoom, -1 * zoom, 1 * zoom, 1, 1000);
    } else {
        vec3 temp;
        memcpy(&g->d.eye_zoom, &g->d.eye, sizeof(g->d.eye_zoom));
        vec3_scale(temp, g->d.view_f, zoom);
        vec3_sub(g->d.eye_zoom, g->d.center, temp);
    }
}
Exemplo n.º 19
0
float fBm(const vec3 p)
{
    float amplitude = 1.0f;
    float frequency = 1.0f;
    float fBm = 0.0f;

    vec3 p_freq;    
    for(int i = 0; i < lattice_noise.num_octaves; i++)
    {
        vec3_scale(p_freq, p, frequency);                    
        fBm += amplitude * noiseFunc(p_freq);
        amplitude *= lattice_noise.gain;
        frequency *= lattice_noise.lacunarity;        
    }
    return (fBm - lattice_noise.fs_min) / (lattice_noise.fs_max - lattice_noise.fs_min);        
}
Exemplo n.º 20
0
float turbulenceNoise(const vec3 p)
{
    float amplitude = 1.0f;
    float frequency = 1.0f;
    float turbulence = 0.0f;

    vec3 p_freq;
    for(int i = 0; i < lattice_noise.num_octaves; i++)
    {
        vec3_scale(p_freq, p, frequency);            
        turbulence += amplitude * fabs(noiseFunc(p_freq));
        amplitude *= 0.5f;
        frequency *= 2.0f;
    }
    return turbulence /= lattice_noise.fs_max;    
}
Exemplo n.º 21
0
/**
 * Component of the support function for a sphere collider.
 **/
static void
object_support_component_sphere(object_t *object,
				float direction[3], float out[3])
{
	float trans[16];

	vec3_normalize(direction, direction);
	vec3_scale(direction, direction, object->r);

	object_get_transform_mat(object, trans);

	out[0] = trans[3];
	out[1] = trans[7];
	out[2] = trans[11];

	vec3_add(direction, out, out);
}
Exemplo n.º 22
0
int						collision_test_plane(t_ray_result *result,
											 t_plane *plane)
{
	t_vec3				opp;
	t_real				dv;

	opp = vec3_sub(result->ray.origin, plane->point);
	dv = vec3_dot(plane->normal, result->ray.direction);
	if (!dv)
		return (0);
	result->distance = -vec3_dot(plane->normal, opp) / dv;
	if (result->distance < 0)
		return (0);
	result->hit = OT_PLANE;
	result->contact.point = vec3_add(result->ray.origin,
									 vec3_scale(result->ray.direction,
												result->distance));
	return (1);
}
Exemplo n.º 23
0
void Camera_update(Camera* const camera, Input* const input) {

    Camera_offset_orientation(
        camera,
        toRadians((-input->mouse_dx * input->mouse_sensitivity)),
        toRadians((-input->mouse_dy * input->mouse_sensitivity))
    );

    // TODO: Delta time
    vec3 dir = {0.0f, 0.0f, 0.0f};
    float vel = 0.2f;
    vec3 forward, backward, left, right;
    Camera_relative_directions(camera, forward, backward, left, right);

    if (input->forward_key) {
        vec3 f = {forward[0], 0.0f, forward[2]};
        vec3_norm(f, f);
        vec3_add(dir, dir, f);
    }
    if (input->back_key) {
        vec3 b = {backward[0], 0.0f, backward[2]};
        vec3_norm(b, b);
        vec3_add(dir, dir, b);
    }
    if (input->left_key) {
        vec3_add(dir, dir, left);
    }
    if (input->right_key) {
        vec3_add(dir, dir, right);
    }

    if (vec3_len(dir) > 0.0f) {
        vec3_norm(dir, dir);
    }

    vec3 movement;
    vec3_scale(movement, dir, vel);
    vec3_add(camera->transform.position, camera->transform.position, movement);
}
Exemplo n.º 24
0
void test_vec3() {
    // Vec4
/*
    struct vec4 v1 = { 1, 2, 3, 4 };
    struct vec4 v2 = { 2, 2, 2, 2 };
    assert(vec4_dot(&v1, &v2) == 2);
    
    struct vec4 v3 = vec4_sub(&v1, &v2);
    assert(v3.x == -1);
    assert(v3.y == 0);
    assert(v3.z == 1);
    assert(v3.w == 2);
    
    struct vec4 v3 = v1 + v2;
    assert(v3.x == 3);
    assert(v3.y == 4);
    assert(v3.z == 5);
    assert(v3.w == 6);
    
    struct vec4 v3 = 2 * v1;
    assert(v3.x == 2);
    assert(v3.y == 4);
    assert(v3.z == 6);
    assert(v3.w == 8);
*/
    
    // Vec3
    struct vec3 v1 = {1, 2, 3};
    struct vec3 v2 = {2, 2, 2};
    assert(vec3_dot(&v1, &v2) == 12);
    
    struct vec3 v3 = vec3_sub(&v1, &v2);
    assert(v3.x == -1);
    assert(v3.y == 0);
    assert(v3.z == 1);
    
    struct vec3 v4 = vec3_add(&v1, &v2);
    assert(v4.x == 3);
    assert(v4.y == 4);
    assert(v4.z == 5);
    
    struct vec3 v5 = vec3_scale(&v1, 2);
    assert(v5.x == 2);
    assert(v5.y == 4);
    assert(v5.z == 6);

    struct vec3 vx = {1, 0, 0};
    struct vec3 vy = {0, 1, 0};
    struct vec3 vz = {0, 0, 1};
    
    struct vec3 v6;
    v6 = vec3_cross(&vx, &vy);
    assert(v6.x == 0 && v6.y == 0 && v6.z == 1);
    v6 = vec3_cross(&vz, &vx);
    assert(v6.x == 0 && v6.y == 1 && v6.z == 0);
    v6 = vec3_cross(&vy, &vz);
    assert(v6.x == 1 && v6.y == 0 && v6.z == 0);
    
    
    
/*
    // Vec2
    local v1 = vec.Vec2(1, 2)
    local v2 = vec.Vec2(2, 2)
    assert(v1:dot(v2) == 6)
    
    local v3 = v1 - v2
    assert(v3.x == -1)
    assert(v3.y == 0)
    
    local v3 = v1 + v2
    assert(v3.x == 3)
    assert(v3.y == 4)
    
    local v3 = 2 * v1
    assert(v3.x == 2)
    assert(v3.y == 4)
    
    assert(v3:data()[0] == 2)
    assert(v3:data()[1] == 4)
    assert(ffi.sizeof(v3) == ffi.sizeof('vec_Scalar')*2)
    
    assert(v3 == vec.Vec2(2, 4))
*/
}
Exemplo n.º 25
0
void render(msg_block_t *msg, rt_context_t *rtx, uint32_t *frame_buffer)
{
  uint32_t *pixel;
  float sy = rtx->sheight * 0.5f - rtx->ayc;
  unsigned int y;
  for (y = 0; y < rtx->height; y++)
  {
    uint32_t *src = frame_buffer + (y * SCALE + rtx->yoff) * msg->fbinfo.line_length / sizeof(uint32_t) + rtx->xoff;
    pixel = src;
    float sx = rtx->swidth * -0.5f;
    unsigned int x;
    for (x = 0; x < rtx->width; x++)
    {
      rtx->ray.pos = rtx->eye;
      rtx->ray.dir = normalize(vec3_sub(vec3_set(sx, sy, 0.0f), rtx->eye));
      vec3_t col = vec3_set(0.0f, 0.0f, 0.0f);
      unsigned int j;
      for (j = 0; j < MAXREF; j++)
      {
        trace_ray(rtx);
        if (rtx->hit != NOHIT)
        {
          vec3_t p, n;
          ray_t next;
          p = vec3_add(rtx->ray.pos, vec3_scale(rtx->ray.dir, rtx->dist));
          switch (rtx->obj[rtx->hit].type)
          {
            case SPHERE:
              n = normalize(vec3_sub(p, rtx->obj[rtx->hit].pos));
              break;
            case PLANE:
              n = rtx->obj[rtx->hit].norm;
              break;
            default:
              break;
          }
          next.pos = vec3_add(p, vec3_scale(n, EPSILON));
          vec3_t lv = vec3_sub(rtx->light.pos, p);
          vec3_t l = normalize(lv);
          next.dir = rtx->ray.dir;
          int prev_hit_index = rtx->hit;
          vec3_t hit_obj_col = rtx->obj[rtx->hit].col;
          float diffuse = dot(n, l);
          float specular = dot(rtx->ray.dir, vec3_sub(l, vec3_scale(n, 2.0f * diffuse)));
          diffuse = max(diffuse, 0.0f);
          specular = max(specular, 0.0f);
          specular = power_spec(specular);
          float s1 = 1.0f;
          float s2 = 1.0f;
          if (rtx->obj[rtx->hit].flag_shadow)
          {
            rtx->ray.dir = l;
            rtx->ray.pos = next.pos;
            trace_ray(rtx);
            int shadow = (rtx->dist < norm(lv));
            s1 = shadow ? 0.5f : s1;
            s2 = shadow ? 0.0f : s2;
          }
          col = vec3_add(col, vec3_add(vec3_scale(rtx->light.col, specular * s2), vec3_scale(hit_obj_col, diffuse * s1)));
          if (!rtx->obj[prev_hit_index].flag_refrect)
          {
            break;
          }
          rtx->ray.dir = vec3_sub(next.dir, vec3_scale(n, dot(next.dir, n) * 2.0f));
          rtx->ray.pos = next.pos;
        }
        else
        {
          break;
        }
      }
      col = vec3_min(vec3_max(col, 0.0f), 1.0f);
      uint32_t col2 = 0xff000000 + ((unsigned int)(col.x * 255.0f) << 16) + ((unsigned int)(col.y * 255.0f) << 8) + (unsigned int)(col.z * 255.0f);
      *pixel = col2;
#if SCALE > 1
      *(pixel + 1) = col2;
#endif
#if SCALE > 3
      *(pixel + 2) = col2;
      *(pixel + 3) = col2;
#endif
      pixel += SCALE;
      sx += rtx->ax;
    }
    uint32_t size = rtx->width * SCALE;
    unsigned int i;
    for (i = 1; i < SCALE; i++)
    {
      uint32_t *dst = src + i * msg->fbinfo.line_length / sizeof(uint32_t);
      unsigned int j;
      for (j = 0; j < size; j++)
      {
        dst[j] = src[j];
      }
    }
    sy -= rtx->ay;
  }
}
Exemplo n.º 26
0
static bool ray_surface_intersect(Ray ray, const Surface *surf, Hit *hit)
{
	float ts[2] = {-HUGE_VAL, -HUGE_VAL}, t;
	Vec3 tnormals[2] = {{0,0,0},{0,0,0}}, tnormal;
	Ray tray;
	Mat4 normal_matrix;
	Shape *shape = surf->shape;
	int hits;

	mat4_copy(normal_matrix, surf->world_to_model);
	mat4_transpose(normal_matrix);

	tray.origin = mat4_transform3_homo(surf->world_to_model, ray.origin);
	tray.direction = mat4_transform3_hetero(surf->world_to_model, ray.direction);
	tray.near = ray.near;
	tray.far = ray.far;

	switch(shape->type)
	{
	case SHAPE_PLANE:
		hits = ray_plane_intersect(tray, shape->u.plane, ts, tnormals);
		break;
	case SHAPE_DISK:
		hits = ray_disk_intersect(tray, shape->u.disk, ts, tnormals);
		break;
	case SHAPE_SPHERE:
		hits = ray_sphere_intersect(tray, shape->u.sphere, ts, tnormals);
		break;
	case SHAPE_CYLINDER:
		hits = ray_cylinder_intersect(tray, shape->u.cylinder, ts, tnormals);
		break;
	case SHAPE_CONE:
		hits = ray_cone_intersect(tray, shape->u.cone, ts, tnormals);
		break;
	case SHAPE_MESH:
		hits = ray_mesh_intersect(tray, shape->u.mesh, ts, tnormals);
		break;
	default:
		printf("Unknown shape\n");
		return false;
		break;
	}

	/* We're looking for the smallest hit that is between the near and far
	 * planes of the ray. */
	if (hits == 0)
		return false;
	if (hits == 1)
	{
		if (ts[0] < ray.near || ts[0] > ray.far)
			return false;

		t = ts[0];
		tnormal = tnormals[0];
	} else if (hits == 2)
	{
		bool t0_ok = ts[0] >= ray.near && ts[0] <= ray.far;
		bool t1_ok = ts[1] >= ray.near && ts[1] <= ray.far;

		     if (!t0_ok && !t1_ok)
		{
			return false;
		}
		else if (t0_ok && !t1_ok)
		{
			t = ts[0];
			tnormal = tnormals[0];
		}
		else if (!t0_ok && t1_ok)
		{
			t = ts[1];
			tnormal = tnormals[1];
		}
		else
		{
			if (ts[0] < ts[1])
			{
				t = ts[0];
				tnormal = tnormals[0];
			} else
			{
				t = ts[1];
				tnormal = tnormals[1];
			}
		}
	} else
	{
		printf("General t finding code unimplemented\n");
		return false;
	}

	hit->t = t;
	hit->position = vec3_add(ray.origin, vec3_scale(t, ray.direction));
	hit->normal = vec3_normalize(mat4_transform3_hetero(normal_matrix, tnormal));
	return true;
}
Exemplo n.º 27
0
X42_EXPORT affine_t* X42_CALL x42_GetAnimBoneMatrices( void *out_buffer, const x42data_t *x42,
	const x42animLerp_t *lerp, x42opts_t *opts )
{
	uint i;

	affine_t * RESTRICT ret;

	const vec3_t * RESTRICT pv;
	const vec3_t * RESTRICT sv;
	const quat_t * RESTRICT rv;

	REF_PARAM( opts );

#ifndef LIBX42_NO_PARAM_VALIDATION
	demand_rn( out_buffer != NULL, X42_ERR_BADPTR, "out_buffer is NULL" );
	demand_rn( lerp != NULL, X42_ERR_BADPTR, "lerp is NULL" );
	demand_rn( x42 != NULL, X42_ERR_BADPTR, "x42 is NULL" );
	demand_rn( x42_ValidateHeader( &x42->header ), X42_ERR_BADDATA, "invalid x42 header data" );
#endif

	pv = lerp->p;
	sv = lerp->s;
	rv = lerp->r;

	ret = (affine_t*)out_buffer;

	for( i = 0; i < x42->header.numBones; i++ )
	{
		affine_t * RESTRICT o = ret + i;

		const x42bone_t * RESTRICT b = x42->bones + i;

		if( b->parentIdx != X42_MODEL_BONE && (b->flags & X42_BF_USE_INV_PARENT_SCALE) )
		{
			vec3_t ips;
			affine_t rs;

			quat_to_affine( &rs, rv[i] );

			vec3_scale( rs.c[0], rs.c[0], sv[i][0] );
			vec3_scale( rs.c[1], rs.c[1], sv[i][1] );
			vec3_scale( rs.c[2], rs.c[2], sv[i][2] );

			ips[0] = 1.0F / sv[b->parentIdx][0];
			ips[1] = 1.0F / sv[b->parentIdx][1];
			ips[2] = 1.0F / sv[b->parentIdx][2];

			vec3_mul( o->c[0], rs.c[0], ips );
			vec3_mul( o->c[1], rs.c[1], ips );
			vec3_mul( o->c[2], rs.c[2], ips );
		}
		else
		{
			quat_to_affine( o, rv[i] );

			vec3_scale( o->c[0], o->c[0], sv[i][0] );
			vec3_scale( o->c[1], o->c[1], sv[i][1] );
			vec3_scale( o->c[2], o->c[2], sv[i][2] );
		}

		vec3_cpy( o->c[3], pv[i] );
	}

	for( i = 0; i < x42->header.numBones; i++ )
	{
		const x42bone_t * RESTRICT b = x42->bones + i;

		if( b->parentIdx != X42_MODEL_BONE )
			affine_mul( ret + i, ret + b->parentIdx, ret + i );
		else if( x42->header.runFlags & X42_RF_ROOT_MATRIX )
			affine_mul( ret + i, &x42->rootMatrix, ret + i );		
	}

	return ret;
}
Exemplo n.º 28
0
group* make_tree(sphere* spheres, int start, unsigned int count, int level = 0)
{
    if(level == 0) {
        previous = time(NULL);
        if(getenv("DEBUG_BVH") != NULL) {
            bvh_spheres_debug_output = fopen("bvh.r9", "w");
        }
    }
    if(time(NULL) > previous) {
        fprintf(stderr, "total treed = %d\n", total_treed);
        previous = time(NULL);
    }

    if((level >= bvh_max_depth) || count <= bvh_leaf_max) {
        total_treed += count;
        group* g = new group(spheres, start, count);
        if(bvh_spheres_debug_output != NULL) {
            // fprintf(bvh_spheres_debug_output, "sphere 7 %f %f %f %f 1 1 1 # %d\n", g->radius, g->center.x, g->center.y, g->center.z, level );
            if(level == 0) {
                fclose(bvh_spheres_debug_output);
                bvh_spheres_debug_output = NULL;
            }
        }
        bvh_leaf_size_counts[std::min(63U, count)]++;
        bvh_leaf_count++;
        bvh_level_counts[level]++;
        bvh_node_count++;
        return g;
    }

    vec3 split_pivot;
    vec3 split_plane_normal;

    // find bounding box
    vec3 boxmin, boxmax;
    box_init(boxmin, boxmax);
    for(unsigned int i = 0; i < count; i++) {
        sphere &s = spheres[start + i];
        vec3 spheremin = vec3_subtract(s.center, vec3(s.radius));
        vec3 spheremax = vec3_add(s.center, vec3(s.radius));
        box_extend(boxmin, boxmax, spheremin, spheremax);
    }

    split_pivot = vec3_scale(vec3_add(boxmin, boxmax), .5);

    vec3 boxdim = vec3_subtract(boxmax, boxmin);
    if(boxdim.x > boxdim.y && boxdim.x > boxdim.z) {
        split_plane_normal = vec3(1, 0, 0);
    } else if(boxdim.y > boxdim.z) {
        split_plane_normal = vec3(0, 1, 0);
    } else {
        split_plane_normal = vec3(0, 0, 1);
    }

    // XXX output split plane to BVH debug file

    int startA;
    int countA;
    int startB;
    int countB;

    if(!bvh_split_median) {

        int s1 = start - 1;
        int s2 = start + count;

        do {
            // from start to s1, not including s1, is negative
            // from s2 to start + count - 1 is positive
            do {
                s1 += 1;
            } while((s1 < s2) && vec3_dot(vec3_subtract(spheres[s1].center, split_pivot), split_plane_normal) < 0);

            // If there wasn't a positive sphere before s2, done.
            if(s1 >= s2)
                break;

            // s1 is now location of lowest positive sphere 

            do {
                s2 -= 1;
            } while((s1 < s2) && vec3_dot(vec3_subtract(spheres[s2].center, split_pivot), split_plane_normal) >= 0);


            // If there wasn't a negative sphere between s1 and s2, done
            if(s1 >= s2)
                break;

            // s2 is now location of highest negative sphere 
            std::swap(spheres[s1], spheres[s2]);
        } while(true);

        // s1 is the first of the positive spheres
        startA = start;
        countA = s1 - startA;
        startB = s1;
        countB = start + count - s1;

    } else {

        sphere_sorter sorter(split_plane_normal);
        std::sort(spheres + start, spheres + start + count - 1, sorter);

        startA = start;
        countA = count / 2;
        startB = startA + countA;
        countB = count - countA;

    }

    group *g;

    if(countA > 0 && countB > 0) {

        // get a tighter bound around children than hierarchical bounds
        vec3 boxmin, boxmax;
        box_init(boxmin, boxmax);
        for(unsigned int i = 0; i < count; i++) {
            add_sphere(&boxmin, &boxmax, spheres[start + i].center, spheres[start + i].radius);
        }

        // construct children
        group *g1 = make_tree(spheres, startA, countA, level + 1);
        g = new group(spheres, g1, NULL, split_plane_normal, boxmin, boxmax);
        group *g2 = make_tree(spheres, startB, countB, level + 1);
        g->positive = g2;
        bvh_level_counts[level]++;
        bvh_node_count++;

    } else {

        total_treed += count;
        fprintf(stderr, "Leaf node at %d, %u spheres, total %d\n", level, count, total_treed);
        g = new group(spheres, start, count);
        bvh_leaf_size_counts[std::min(63U, count)]++;
        bvh_leaf_count++;
        bvh_level_counts[level]++;
        bvh_node_count++;
    }

    if(bvh_spheres_debug_output != NULL) {
        // fprintf(bvh_spheres_debug_output, "sphere 7 %f %f %f %f 1 1 1 # %d\n", g->radius, g->center.x, g->center.y, g->center.z, level );
        if(level == 0) {
            fclose(bvh_spheres_debug_output);
            bvh_spheres_debug_output = NULL;
        }
    }

    return g;
}
Exemplo n.º 29
0
Arquivo: main.c Projeto: larso0/PTGame
int main(int argc, char** argv)
{
    Settings settings;
    ConstructSettings(&settings);
    LoadSettingsFile(&settings, "settings.ini");
    if(Init(&settings) < 0) return -1;

    GLuint program;
    if(SetupProgram(&program) < 0) return -2;

    GLuint grid_vbuf = CreateGridVertexBuffer(settings.graphics.viewdistance);
    int grid_icount;
    GLuint grid_ibuf = CreateGridIndexBuffer(&grid_icount,
                                             settings.graphics.viewdistance);

    glUseProgram(program);
    GLint grid_pos_loc = glGetAttribLocation(program, "grid_pos");
    GLint grid_world_mat_loc = glGetUniformLocation(program, "world_mat");
    GLint grid_view_mat_loc = glGetUniformLocation(program, "view_mat");
    GLint grid_proj_mat_loc = glGetUniformLocation(program, "proj_mat");
    GLint grid_color_loc = glGetUniformLocation(program, "color");
    GLint grid_viewdistance_loc = glGetUniformLocation(program, "viewdistance");

    glUniform3f(grid_color_loc, 0.f, 0.6f, 0.f);
    glUniform1f(grid_viewdistance_loc, settings.graphics.viewdistance);

    GLuint grid_vao;
    glGenVertexArrays(1, &grid_vao);
    glBindVertexArray(grid_vao);
    glBindBuffer(GL_ARRAY_BUFFER, grid_vbuf);
    glEnableVertexAttribArray(grid_pos_loc);
    glVertexAttribPointer(grid_pos_loc, 2, GL_FLOAT, GL_FALSE, 0, 0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, grid_ibuf);

    glEnable(GL_DEPTH_TEST);
    glEnable(GL_CULL_FACE);
    glClearColor(0.5f, 0.5f, 0.5f, 1.f);
    glViewport(0, 0, settings.video.width, settings.video.height);

    Node grid_node;
    ConstructNode(&grid_node);
    Camera camera;
    ConstructCamera(&camera);
    mat4x4 projection_matrix;
    mat4x4_perspective(projection_matrix,
                       settings.video.pfov,
                       settings.video.width/(float)settings.video.height,
                       settings.video.pnear,
                       settings.video.pfar);
    glUniformMatrix4fv(grid_proj_mat_loc, 1, GL_FALSE,
                       (const float*)projection_matrix);

    float speed = 10.f;
    Uint32 ticks = SDL_GetTicks();
    State state = STATE_RUNNING | (settings.video.fullscreen ? STATE_FULLSCREEN : 0);
    while(state & STATE_RUNNING)
    {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glUseProgram(program);
        glUniformMatrix4fv(grid_world_mat_loc, 1, GL_FALSE,
                           (const float*)grid_node.world_matrix);
        glUniformMatrix4fv(grid_view_mat_loc, 1, GL_FALSE,
                           (const float*)camera.view_matrix);
        glBindVertexArray(grid_vao);
        glDrawElements(GL_TRIANGLE_STRIP, grid_icount, GL_UNSIGNED_INT, NULL);
        SDL_GL_SwapWindow(window);

        SDL_Event event;
        while(SDL_PollEvent(&event))
        {
            switch(event.type)
            {
            case SDL_QUIT:
                state &= ~STATE_RUNNING;
                break;
            case SDL_KEYUP:
                switch(event.key.keysym.scancode)
                {
                case SDL_SCANCODE_F11:
                    state ^= STATE_FULLSCREEN;
                    SDL_SetWindowFullscreen
                    (
                        window,
                        state & STATE_FULLSCREEN ?
                        SDL_WINDOW_FULLSCREEN_DESKTOP : 0
                    );
                    break;
                case SDL_SCANCODE_ESCAPE:
                    state ^= STATE_MOUSE_GRABBED;
                    SDL_SetRelativeMouseMode(state & STATE_MOUSE_GRABBED);
                    break;
                case SDL_SCANCODE_LSHIFT:
                    speed = settings.controls.speed1;
                    break;
                default:
                    break;
                }
                break;
            case SDL_KEYDOWN:
                switch(event.key.keysym.scancode)
                {
                case SDL_SCANCODE_LSHIFT:
                    speed = settings.controls.speed2;
                    break;
                default:
                    break;
                }
                break;
            case SDL_WINDOWEVENT:
                if(event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED)
                {
                    int w = event.window.data1;
                    int h = event.window.data2;
                    glViewport(0, 0, w, h);
                    mat4x4_perspective(projection_matrix,
                                       settings.video.pfov,
                                       w/(float)h,
                                       settings.video.pnear,
                                       settings.video.pfar);
                    glUniformMatrix4fv(grid_proj_mat_loc, 1, GL_FALSE,
                                       (const float*)projection_matrix);
                }
                break;
            case SDL_MOUSEMOTION:
                if(state & STATE_MOUSE_GRABBED)
                {
                    camera.yaw -= settings.controls.xsensitivity *
                                  event.motion.xrel;
                    camera.pitch -= settings.controls.xsensitivity *
                                    event.motion.yrel;
                }
                break;
            default:
                break;
            }
        }
        Uint32 nticks = SDL_GetTicks();
        float delta = (nticks - ticks)/1000.f;
        ticks = nticks;

        const Uint8* keys = SDL_GetKeyboardState(NULL);
        vec3 movement;
        int i;
        for(i = 0; i < 3; i++) movement[i] = 0.f;
        SDL_bool moved = SDL_FALSE;
        if(keys[SDL_SCANCODE_W] && !keys[SDL_SCANCODE_S])
        {
            vec3_add(movement, movement, camera.direction);
            moved = SDL_TRUE;
        }
        else if(keys[SDL_SCANCODE_S] && !keys[SDL_SCANCODE_W])
        {
            vec3_sub(movement, movement, camera.direction);
            moved = SDL_TRUE;
        }
        if(keys[SDL_SCANCODE_A] && !keys[SDL_SCANCODE_D])
        {
            vec3_sub(movement, movement, camera.right);
            moved = SDL_TRUE;
        }
        else if(keys[SDL_SCANCODE_D] && !keys[SDL_SCANCODE_A])
        {
            vec3_add(movement, movement, camera.right);
            moved = SDL_TRUE;
        }
        if(keys[SDL_SCANCODE_Q] && !keys[SDL_SCANCODE_E])
        {
            vec3_sub(movement, movement, camera.up);
            moved = SDL_TRUE;
        }
        else if(keys[SDL_SCANCODE_E] && !keys[SDL_SCANCODE_Q])
        {
            vec3_add(movement, movement, camera.up);
            moved = SDL_TRUE;
        }

        if(moved)
        {
            vec3_norm(movement, movement);
            vec3_scale(movement, movement, delta * speed);
            vec3_add(camera.node.translation, camera.node.translation,
                     movement);
        }

        UpdateCamera(&camera);

        if(moved)
        {
            vec2 tmp1;
            tmp1[0] = camera.node.position[0];
            tmp1[1] = camera.node.position[2];
            vec2 tmp2;
            tmp2[0] = grid_node.position[0];
            tmp2[1] = grid_node.position[2];
            vec2_sub(tmp1, tmp1, tmp2);
            tmp1[0] = floor(tmp1[0]);
            tmp1[1] = floor(tmp1[1]);
            grid_node.translation[0] += tmp1[0];
            grid_node.translation[2] += tmp1[1];
            UpdateNode(&grid_node);
        }
    }

    glDeleteVertexArrays(1, &grid_vao);
    glDeleteBuffers(1, &grid_vbuf);
    glDeleteBuffers(1, &grid_ibuf);
    glDeleteProgram(program);

    return 0;
}
Exemplo n.º 30
0
/**
 * Check for collision between objects.
 **/
int
object_check_collision(object_t *a, object_t *b)
{
	float direction[3] = { 0, 1, 0 };
	float simplex[4][3];
	size_t simplex_pos = 5;
	size_t last;
	float middle[3];
	float to_last[3];

	if (! (object_is_collider(a) &&
	       object_is_collider(b)))
		return 0;

	object_support(a, b, direction, simplex[0]);

	direction[2] = -1;
	object_support(a, b, direction, simplex[1]);

	if (vec3_dot(simplex[1], direction) <= 0)
		return 0;

	vec3_subtract(simplex[1], simplex[0], to_last);
	vec3_cross(simplex[1], to_last, direction);
	vec3_cross(direction, to_last, direction);
	object_support(a, b, direction, simplex[2]);

	if (vec3_dot(simplex[2], direction) <= 0)
		return 0;

	while (vec3_dot(simplex[simplex_pos], direction)) {
		if (simplex_pos == 5) {
			simplex_pos = 3;
			last = 2;
		} else {
			last = simplex_pos;
			simplex_pos =
				object_simplex_detect_region(simplex,
							     simplex_pos);
		}

		if (simplex_pos == 4)
			return 1;

		middle[0] = middle[1] = middle[2] = 0;

		if (simplex_pos != 3)
			vec3_add(simplex[3], middle, middle);

		if (simplex_pos != 2)
			vec3_add(simplex[2], middle, middle);

		if (simplex_pos != 1)
			vec3_add(simplex[1], middle, middle);

		if (simplex_pos != 0)
			vec3_add(simplex[0], middle, middle);

		vec3_scale(middle, middle, 1.0/3.0);
		vec3_subtract(middle, simplex[last], to_last);
		vec3_cross(middle, to_last, direction);
		vec3_cross(direction, to_last, direction);
		object_support(a, b, direction, simplex[simplex_pos]);
	}

	return 0;
}