Example #1
0
X42_EXPORT bool X42_CALL x42_ApplyBoneOffsets( x42animLerp_t *lerp, const x42data_t *x42,
	const x42boneOffset_t *offsets, uint numOffsets, x42opts_t *opts )
{
	uint i, j;

	REF_PARAM( opts );

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

	for( i = 0; i < numOffsets; i++ )
	{
		for( j = 0; j < x42->header.numBones; j++ )
		{
			if( x42name_eq2( x42, x42->bones[j].name, offsets[i].boneName ) )
				break;
		}

		if( j == x42->header.numBones )
			continue;

		vec3_add( lerp->p[j], lerp->p[j], offsets[i].pos_offset );
		vec3_add( lerp->s[j], lerp->s[j], offsets[i].scale_offset );

		quat_mul( lerp->r[j], offsets[i].rot_offset, lerp->r[j] );
	}

	return true;
}
Example #2
0
void object3d_render(screen_buffer *screen, object3d *obj) {
	vec3 a, b, c;
	int i;
	for (i = 0; i < obj->vertex_cnt; i+=3) {
		a = obj->vertices[i][0];
		b = obj->vertices[i+1][0];
		c = obj->vertices[i+2][0];
		
		vec3_rotate(&a, &obj->rotation);
		vec3_mul(&a, &obj->scale);
		vec3_add(&a, &obj->position);

		vec3_rotate(&b, &obj->rotation);
		vec3_mul(&b, &obj->scale);
		vec3_add(&b, &obj->position);
		
		vec3_rotate(&c, &obj->rotation);
		vec3_mul(&c, &obj->scale);
		vec3_add(&c, &obj->position);

		rasterize_vertex(screen, &a, &b, &c);
		//line(screen, a.x, a.y, b.x, b.y, '+');
		//line(screen, b.x, b.y, c.x, c.y, '+');
		//line(screen, c.x, c.y, a.x, a.y, '+');
	}
}
Example #3
0
void collision_response_slide(void* x, vec3* position, vec3* velocity, collision (*colfunc)(void* x, vec3* pos, vec3* vel) ) {
  
  collision col = colfunc(x, position, velocity);
  
  int count = 0;
  while (col.collided) {
    
    //renderer_add(x, render_object_line(*position, vec3_add(*position, col.norm), vec3_red(), count+1));
    
    if (count++ == 100) {
      *velocity = vec3_zero();
      break;
    }
    
    vec3 fwrd = vec3_mul(*velocity, col.time);
    
    float len = max(vec3_length(fwrd) - 0.001, 0.0) / vec3_length(fwrd);
    vec3 move = vec3_add(*position, vec3_mul(fwrd, len));
    vec3 proj = vec3_project(vec3_mul(*velocity, (1.0-col.time)), col.norm);
    
    //renderer_add(x, render_object_line(*position, vec3_add(*position, vec3_normalize(proj)), vec3_green(), count+1));
    
    *position = move;
    *velocity = proj;
    
    col = colfunc(x, position, velocity);
  
  }
  
  *position = vec3_add(*position, *velocity);
  

}
void BillboardSprite::draw(Vec3 v)
{
    v = quadrant_translate_position(current_camera_position, v);
    if (!point_fulstrum_test(v.x, v.y, v.z))
        return;

    Vec3 up = vec3_init(model_view_matrix[0]*this->scale,
                        model_view_matrix[4]*this->scale,
                        model_view_matrix[8]*this->scale);
    Vec3 right = vec3_init(model_view_matrix[1]*this->scale,
                           model_view_matrix[5]*this->scale,
                           model_view_matrix[9]*this->scale);

    float tx_min, tx_max, ty_min, ty_max;
    tx_min = (float)(this->texture_index%16)* (1.0f/16.0f);
    tx_max = tx_min + (1.0f/16.0f);
    ty_min = (float)(this->texture_index/16)* (1.0f/16.0f);
    ty_max = ty_min + (1.0f/16.0f);

    Vec3 p = vec3_sub(v, vec3_add(right, up));
    glTexCoord2f(tx_min,ty_max);
    glVertex3f(p.x, p.y, p.z);

    p = vec3_add(v, vec3_sub(up, right));
    glTexCoord2f(tx_max,ty_max);
    glVertex3f(p.x, p.y, p.z);

    p = vec3_add(v, vec3_add(up, right));
    glTexCoord2f(tx_max,ty_min);
    glVertex3f(p.x, p.y, p.z);

    p = vec3_add(v, vec3_sub(right, up));
    glTexCoord2f(tx_min,ty_min);
    glVertex3f(p.x, p.y, p.z);
}
Example #5
0
collision sphere_collide_face(sphere s, vec3 v, ctri ct) {
  
  //if (unlikely(sphere_intersects_face(s, ct.a, ct.b, ct.c, ct.norm))) { error("Collision Sphere Inside Mesh Face!"); }
  
  float angle = vec3_dot(ct.norm, v);
  float dist  = vec3_dot(ct.norm, vec3_sub(s.center, ct.a)); 
  
  float t0 = ( s.radius - dist) / angle;
  float t1 = (-s.radius - dist) / angle;
  float t = FLT_MAX;
  
  if (between_or(t0, 0, 1)
  &&  between_or(t1, 0, 1)) { t = min(t0, t1); }
  else if (between_or(t0, 0, 1)) { t = t0; }
  else if (between_or(t1, 0, 1)) { t = t1; } 
  else { return collision_none(); }
  
  vec3 cpoint = vec3_add(s.center, vec3_mul(v, t));
  vec3 spoint = vec3_add(cpoint, vec3_mul(ct.norm, -s.radius));
  
  if (!point_inside_triangle(spoint, ct.a, ct.b, ct.c)) {
    return collision_none();
  } else {
    return collision_new(t, spoint, ct.norm);
  }
  
}
Example #6
0
 void _set_collision_point()
 {
     if (this->type == HITSCAN_TARGET_NONE)
     {
         const Vec3 away = vec3_scalar_mult(this->direction, this->range);
         this->collision_point = vec3_add(this->start_position, away);
     }
     else if (this->type == HITSCAN_TARGET_BLOCK)
     {
         const Vec3 away = vec3_scalar_mult(this->direction, this->block_distance);
         this->collision_point = vec3_add(this->start_position, away);
     }
     else if (this->type == HITSCAN_TARGET_MECH)
     {
         const Vec3 away = vec3_scalar_mult(this->direction, this->mech_distance);
         this->collision_point = vec3_add(this->start_position, away);
     }
     else if (this->type == HITSCAN_TARGET_SPRITE_MOB)
     {
         this->collision_point = this->sprite_mob_collision_point;
     }
     else if (this->type == HITSCAN_TARGET_VOXEL)
     {
         this->collision_point = this->voxel_collision_point;
     }
     else
     {
         GS_ASSERT(false);
     }
 }
Example #7
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);

}
Example #8
0
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);

}
Example #9
0
static Ray cam_ray_internal(Camera *cam, int i, int j, float offx, float offy,
		double near)
{
	Ray r;
	float d, u, v;
	double bottom, left, width, height;
	const int nx = config->width, ny = config->height;

	width = 2*near*tan(cam->fov*M_TWO_PI/360./2.);
	left = -width/2;
	height = width * ny/(double) nx;
	bottom = -height/2;

	d = near;
	u = left +   width *(i + offx)/nx;
	v = bottom + height*(j + offy)/ny;
	r.origin = cam->position;
	r.direction = vec3_normalize(vec3_add(
			vec3_scale(-d, cam->w), vec3_add(
			vec3_scale( u, cam->u),
			vec3_scale( v, cam->v))));
	r.near = 0;
	r.far = HUGE_VAL;

	return r;
}
Example #10
0
static int ray_sphere_intersect(Ray r, Sphere sph, float t[2], Vec3 normal[2])
{
	Vec3 v;
	float dd, vd, vv, discriminant;
	float radius = sph.radius;

	v = r.origin;
	vv = vec3_dot(v, v);
	vd = vec3_dot(v, r.direction);
	dd = vec3_dot(r.direction, r.direction);

	discriminant = vd*vd - dd*(vv - radius*radius);
	if (discriminant < 0)
		return 0;
	else if (discriminant == 0)
	{
		t[0] = -vd/dd;
		normal[0] = vec3_normalize(vec3_add(r.origin,
				vec3_scale(t[0], r.direction)));
		return 1;
	} else
	{
		t[0] = (-vd - sqrtf(discriminant))/dd;
		t[1] = (-vd + sqrtf(discriminant))/dd;

		normal[0] = vec3_add(r.origin, vec3_scale(t[0], r.direction));
		normal[1] = vec3_add(r.origin, vec3_scale(t[1], r.direction));
		return 2;
	}
}
static void _control_camera(Game* G, float delta_time)
{
    if(G->num_points == 1) {
        Vec2 curr = G->points[0].pos;
        Vec2 delta = vec2_sub(curr, G->prev_single);

        /* L-R rotation */
        Quaternion q = quat_from_axis_anglef(0, 1, 0, delta_time*delta.x*0.2f);
        G->camera.orientation = quat_multiply(G->camera.orientation, q);

        /* U-D rotation */
        q = quat_from_axis_anglef(1, 0, 0, delta_time*delta.y*0.2f);
        G->camera.orientation = quat_multiply(q, G->camera.orientation);

        G->prev_single = curr;
    } else if(G->num_points == 2) {
        float camera_speed = 0.1f;
        Vec3 look = quat_get_z_axis(G->camera.orientation);
        Vec3 right = quat_get_x_axis(G->camera.orientation);
        Vec2 avg = vec2_add(G->points[0].pos, G->points[1].pos);
        Vec2 delta;

        avg = vec2_mul_scalar(avg, 0.5f);
        delta = vec2_sub(avg, G->prev_double);

        look = vec3_mul_scalar(look, -delta.y*camera_speed);
        right = vec3_mul_scalar(right, delta.x*camera_speed);


        G->camera.position = vec3_add(G->camera.position, look);
        G->camera.position = vec3_add(G->camera.position, right);

        G->prev_double = avg;
    }
}
Example #12
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);
}
Example #13
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));
}
Example #14
0
static int on_move(gesture3d_t *gest, void *user)
{
    float face_plane[4][4];
    cursor_t *curs = gest->cursor;
    tool_move_t *tool = user;
    float n[3], pos[3], d[3], ofs[3], v[3];
    layer_t *layer = goxel->image->active_layer;
    float mat[4][4];

    if (box_is_null(tool->box)) return GESTURE_FAILED;

    if (gest->type == GESTURE_HOVER) {
        goxel_set_help_text(goxel, "Drag to move face");
        if (curs->snaped != SNAP_LAYER_OUT) return GESTURE_FAILED;
        tool->snap_face = get_face(curs->normal);
        curs->snap_offset = 0;
        curs->snap_mask &= ~SNAP_ROUNDED;
        mat4_mul(tool->box, FACES_MATS[tool->snap_face], face_plane);
        render_img(&goxel->rend, NULL, face_plane, EFFECT_NO_SHADING);
        if (curs->flags & CURSOR_PRESSED) {
            gest->type = GESTURE_DRAG;
            vec3_normalize(face_plane[0], v);
            plane_from_vectors(goxel->tool_plane, curs->pos, curs->normal, v);
            image_history_push(goxel->image);
        }
        return 0;
    }
    if (gest->type == GESTURE_DRAG) {
        goxel_set_help_text(goxel, "Drag to move face");
        curs->snap_offset = 0;
        curs->snap_mask &= ~SNAP_ROUNDED;
        mat4_mul(tool->box, FACES_MATS[tool->snap_face], face_plane);

        vec3_normalize(face_plane[2], n);
        vec3_sub(curs->pos, goxel->tool_plane[3], v);
        vec3_project(v, n, v);
        vec3_add(goxel->tool_plane[3], v, pos);
        pos[0] = round(pos[0]);
        pos[1] = round(pos[1]);
        pos[2] = round(pos[2]);
        vec3_add(tool->box[3], face_plane[2], d);
        vec3_sub(pos, d, ofs);
        vec3_project(ofs, n, ofs);

        mat4_set_identity(mat);
        mat4_itranslate(mat, ofs[0], ofs[1], ofs[2]);
        do_move(layer, mat);

        if (gest->state == GESTURE_END) {
            gest->type = GESTURE_HOVER;
            mat4_copy(plane_null, goxel->tool_plane);
        }
        return 0;
    }
    return 0;
}
Example #15
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());
}
Example #16
0
t_bool           lambertian(t_material *material, const t_ray *r, const t_hit_record *h, t_vec3 *attenuation, t_ray *scattered)
{
    (void)r;
    t_vec3      target;
    t_vec3      random;

    random = random_in_unit_sphere(1.0f);
    vec3_add(&target, vec3_add(&target, &h->normal, &h->pos), &random);
    ray_assign(scattered, &h->pos, vec3_sub(&target, &target, &h->pos));
    material->texture.value(&material->texture, h, attenuation);
    return (TRUE);
}
Example #17
0
void RailTrailEffect::draw_quad(const Vec3& p, float r, float theta, float phi) // quadratic radius
{   // with no rotation modifications, it faces upwards
    static const float tx_min = 0.0f;
    static const float tx_max = 1.0f;
    static const float ty_min = 0.0f;
    static const float ty_max = 1.0f;

    Vec3 bl, tl, tr, br;
    bl = tl = tr = br = vec3_init(0.0f);

    // FIXME: MOVE SHIT LIKE THIS TO BE CALC'ED ONLY ONCE then applied to all the interpolated points
    // rotate the y & z (pitch) .... prob need to reverse/mirror the y
    float radian = phi*PI;

    // first setup up-facing quad with correct PITCH
    // bottom edge
    bl.y = br.y = -r*sinf(radian);
    bl.z = br.z = r*cosf(radian);
    //printf("bl.y: %8.2f  bl.z: %8.2f \n", bl.y, bl.z);

    // top edge
    tl.y = tr.y = r*sinf(radian);
    tl.z = tr.z = -r*cosf(radian);
    //printf("tl.y: %8.2f  tl.z: %8.2f \n", tl.y, tl.z);

    // sides
    bl.x = tl.x = -r;
    br.x = tr.x = r;

    // do YAW
    bl = vec3_euler_rotation(bl, theta-0.5f, 0, 0);
    tl = vec3_euler_rotation(tl, theta-0.5f, 0, 0);
    tr = vec3_euler_rotation(tr, theta-0.5f, 0, 0);
    br = vec3_euler_rotation(br, theta-0.5f, 0, 0);

    // translate to world space
    bl = vec3_add(p, bl);
    tl = vec3_add(p, tl);
    tr = vec3_add(p, tr);
    br = vec3_add(p, br);

    // draw
    glTexCoord2f(tx_max, ty_max);
    glVertex3f(bl.x, bl.y, bl.z);  // Bottom left
    glTexCoord2f(tx_min, ty_max);
    glVertex3f(tl.x, tl.y, tl.z);  // Top left
    glTexCoord2f(tx_min, ty_min);
    glVertex3f(tr.x, tr.y, tr.z);  // Top right
    glTexCoord2f(tx_max, ty_min);
    glVertex3f(br.x, br.y, br.z);  // Bottom right
}
void OBSBasicPreview::SnapStretchingToScreen(vec3 &tl, vec3 &br)
{
	uint32_t stretchFlags = (uint32_t)stretchHandle;
	vec3     newTL        = GetTransformedPos(tl.x, tl.y, itemToScreen);
	vec3     newTR        = GetTransformedPos(br.x, tl.y, itemToScreen);
	vec3     newBL        = GetTransformedPos(tl.x, br.y, itemToScreen);
	vec3     newBR        = GetTransformedPos(br.x, br.y, itemToScreen);
	vec3     boundingTL;
	vec3     boundingBR;

	vec3_copy(&boundingTL, &newTL);
	vec3_min(&boundingTL, &boundingTL, &newTR);
	vec3_min(&boundingTL, &boundingTL, &newBL);
	vec3_min(&boundingTL, &boundingTL, &newBR);

	vec3_copy(&boundingBR, &newTL);
	vec3_max(&boundingBR, &boundingBR, &newTR);
	vec3_max(&boundingBR, &boundingBR, &newBL);
	vec3_max(&boundingBR, &boundingBR, &newBR);

	vec3 offset = GetScreenSnapOffset(boundingTL, boundingBR);
	vec3_add(&offset, &offset, &newTL);
	vec3_transform(&offset, &offset, &screenToItem);
	vec3_sub(&offset, &offset, &tl);

	if (stretchFlags & ITEM_LEFT)
		tl.x += offset.x;
	else if (stretchFlags & ITEM_RIGHT)
		br.x += offset.x;

	if (stretchFlags & ITEM_TOP)
		tl.y += offset.y;
	else if (stretchFlags & ITEM_BOTTOM)
		br.y += offset.y;
}
Example #19
0
// NB. Proportional x and y
Ray Camera::getRay(float x, float y){
  vec3 xdir;
  vec3 ydir;
  vec3 dest;

  xdir = vec3_scale(camx, (x-0.5) * tax);
  ydir = vec3_scale(camy, (y-0.5) * tay);

  dest = vec3_add(camz, vec3_add(xdir, ydir));

  Ray r;
  r.ro = location;
  r.rd = dest;

  return r;
}
Example #20
0
/* 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;
}
Example #21
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");
}
Example #22
0
static vec4_t fragment_shader(const vs_to_fs_t *in)
{
	vec3_t result = { 0, 0, 0 };
	//eye position
	const vec3_t E = { 0, 0, 1 };

	const float ambient = 0.05f;
	float diffuse, specular;

	vec3_t N = vec3_normalize(in->normal);

	int i;
	for(i=0; i<sizeof(lights)/sizeof(light_t); i++){
		vec3_t H = vec3_normalize(vec3_add(E, lights[i].position));

		diffuse = vec3_dot(N, lights[i].position);
		specular = vec3_dot(N, H);
		specular *= specular;
		specular *= specular;
		specular *= specular;
		specular *= specular;
		specular *= specular;
		specular *= specular * 0.6f;

		vec3_t c = r3d_texture_nearest(textures[mesh], in->uv); // read texel
		result.r += diffuse * c.r * lights[i].color.r + specular;
		result.g += diffuse * c.g * lights[i].color.g + specular;
		result.b += diffuse * c.b * lights[i].color.b + specular;
	}
	return vec4(ambient + result.r,	ambient + result.g, ambient + result.b, 1.0f);
}
Example #23
0
static void toggle_freecam(ui_button* b, SDL_Event event) {
  
  if (event.type == SDL_MOUSEBUTTONDOWN) {
    
    if (ui_button_contains_position(b, vec2_new(event.motion.x, event.motion.y))) {
      b->pressed = true;
    }
  
  } else if (event.type == SDL_MOUSEBUTTONUP) {
    
    if (b->pressed) {
      b->pressed = false;
      
      freecam = !freecam;
      
      camera* cam = entity_get("camera");
      landscape* world = entity_get("world");
      
      vec3 cam_dir = vec3_normalize(vec3_sub(cam->target, cam->position));
      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);
    }
  }
}
Example #24
0
collision sphere_collide_edge(sphere s, vec3 v, vec3 e0, vec3 e1) {
  
  //Wif (unlikely(!line_outside_sphere(s, e0, e1))) { error("Collision Sphere Inside Mesh Edge!"); }
  
  vec3 x0 = vec3_sub(e0, s.center);
  vec3 x1 = vec3_sub(e1, s.center);
  
  vec3 d = vec3_sub(x1, x0);  
  float dlen = vec3_length_sqrd(d);
  float vlen = vec3_length_sqrd(v);
  float xlen = vec3_length_sqrd(x0);
  
  float A = dlen * -vlen + vec3_dot(d, v) * vec3_dot(d, v);
  float B = dlen * 2 * vec3_dot(v, x0) - 2 * vec3_dot(d, v) * vec3_dot(d, x0);
  float C = dlen * (s.radius * s.radius - xlen) + vec3_dot(d, x0) * vec3_dot(d, x0);
  
  float t0, t1, t;
  if (!quadratic(A, B, C, &t0, &t1)) { return collision_none(); }
  
  if (between_or(t0, 0, 1) && between_or(t1, 0, 1)) { t = min(t0, t1); }
  else if (between_or(t0, 0, 1)) { t = t0; }
  else if (between_or(t1, 0, 1)) { t = t1; } 
  else { return collision_none(); }
  
  float range = (vec3_dot(d, v) * t - vec3_dot(d, x0)) / dlen;
  
  if (!between_or(range, 0, 1)) {
    return collision_none();
  } else {
    vec3 spoint = vec3_add(e0, vec3_mul(d, range));
    return collision_new(t, spoint, vec3_normalize(vec3_sub(s.center, spoint)));
  }
  
}
Example #25
0
collision point_collide_edge(vec3 p, vec3 v, vec3 e0, vec3 e1) {

  vec3 x0 = vec3_sub(e0, p);
  vec3 x1 = vec3_sub(e1, p);
  
  vec3 d = vec3_sub(x1, x0);  
  float dlen = vec3_length_sqrd(d);
  float vlen = vec3_length_sqrd(v);
  float xlen = vec3_length_sqrd(x0);
  
  float A = dlen * -vlen + vec3_dot(d, v) * vec3_dot(d, v);
  float B = dlen * 2 * vec3_dot(v, x0) - 2 * vec3_dot(d, v) * vec3_dot(d, x0);
  float C = dlen * - xlen + vec3_dot(d, x0) * vec3_dot(d, x0);
  
  float t0, t1, t;
  if (!quadratic(A, B, C, &t0, &t1)) { return collision_none(); }
  
  if (between_or(t0, 0, 1) && between_or(t1, 0, 1)) { t = min(t0, t1); }
  else if (between_or(t0, 0, 1)) { t = t0; }
  else if (between_or(t1, 0, 1)) { t = t1; } 
  else { return collision_none(); }
  
  float range = (vec3_dot(d, v) * t - vec3_dot(d, x0)) / dlen;
  
  if (!between_or(range, 0, 1)) {
    return collision_none();
  } else {
    vec3 spoint = vec3_add(e0, vec3_mul(d, range));
    return collision_new(t, spoint, vec3_normalize(vec3_sub(p, spoint)));
  }

}
Example #26
0
static int _llfunc_vec3_add(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_add(a, b, r);
	return 1;
}
Example #27
0
void trace_image(int width, int height, float aspect, unsigned char *image, const world* world, const vec3& light_dir)
{
#pragma omp parallel for schedule(dynamic)
    for(int yloop = 0; yloop < height; yloop++) {
        unsigned char *row = image + (height - yloop - 1) * (((width * 3) + 3) & ~3);
        for(int xloop = 0; xloop < width; xloop++) {
            // printf("%d, %d\n", xloop, yloop);
            int cols = 0;
            vec3 color(0, 0, 0);
            for(int qky = 0; qky < world->ysub; qky++) {
                for(int qkx = 0; qkx < world->xsub; qkx++) {
                    float u = ((xloop + qkx / (float)world->xsub) + .5) / width;
                    float v = ((yloop + qky / (float)world->ysub) + .5) / height;
                    ray eye_ray;
                    eye_ray.d = make_eye_ray(u, v, aspect, world->cam.fov);
                    eye_ray.o = vec3(0, 0, 0);
                    ray world_ray = transform_ray(eye_ray, world->camera_matrix, world->camera_normal_matrix);
                    vec3 sample = trace(world_ray, world, light_dir);
                    color = vec3_add(color, sample);
                    ++cols;
                }
            }
            vec3 final_color = vec3_divide(color, cols);
            unsigned char *pixel = row + xloop * 3;
            pixel[0] = final_color.x * 255;
            pixel[1] = final_color.y * 255;
            pixel[2] = final_color.z * 255;
        }
    }
}
Example #28
0
void calc_torque(struct vec3 *dst, const struct vec3 *v1,
                 const struct vec3 *v2, float torque, float min_adjust,
                 float t)
{
    struct vec3 line, dir;
    float orig_dist, torque_dist, adjust_dist;

    if (vec3_close(v1, v2, EPSILON)) {
        vec3_copy(dst, v1);
        return;
    }

    vec3_sub(&line, v2, v1);
    orig_dist = vec3_len(&line);
    vec3_mulf(&dir, &line, 1.0f/orig_dist);

    torque_dist = orig_dist*torque; /* use distance to determine speed */
    if (torque_dist < min_adjust)   /* prevent from going too slow */
        torque_dist = min_adjust;

    adjust_dist = torque_dist*t;

    if (adjust_dist <= (orig_dist-LARGE_EPSILON)) {
        vec3_mulf(dst, &dir, adjust_dist);
        vec3_add(dst, dst, v1); /* add torque */
    } else {
        vec3_copy(dst, v2);     /* clamp if overshoot */
    }
}
Example #29
0
void foreach_block_in_hiearchy(
    struct group *group,
    struct vec3 const *parentpos,
    void (*proc)(struct blockref*, struct vec3 const *pos, void*),
    void *data)
{
    vec3 pos;
    vec3_add(&pos, parentpos, &group->position);

    struct groupdata *groupdata  = group->data;
    struct ptrarray  *blocks     = groupdata->blocks;
    size_t            blockcount = ptrarray_count(blocks);
    struct blockref   ref        = {NULL, group};

    for (size_t i = 0; i < blockcount; ++i)
    {
        ref.block = get_ptrarray(blocks, i);
        proc(&ref, &pos, data);
    }

    struct ptrarray *groups = groupdata->groups;
    size_t groupcount = ptrarray_count(groups);

    for (size_t i = 0; i < groupcount; ++i)
    {
        struct group *child = get_ptrarray(groups, i);
        foreach_block_in_hiearchy(child, &pos, proc, data);
    }
}
Example #30
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);
}