Esempio n. 1
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);
  

}
Esempio n. 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, '+');
	}
}
Esempio n. 3
0
/* FIXME: Broken, entities "disappears" */
vec3
vec3_slerp(const vec3 *v, const vec3 *u, float t)
{
	const double DOT_THRESHOLD = 0.9995;
	
	float dot;
	float theta;
	vec3	v0,
			u0,
			w;
	
	v0 = *v;
	u0 = *u;
	dot = vec3_dot(&v0, &u0);
	
    if (dot > DOT_THRESHOLD) {
		vec3_lerp(&v0, &u0, t);
    }
	
	theta = t * acosf(dot);
	
	w = vec3_mul(v, dot);
	w = vec3_sub(u, &w);
	//w = vector_normalize(&w);
	
	v0 = vec3_mul(&v0, cosf(theta));
	u0 = vec3_mul(&u0, sinf(theta));
	w = vec3_add(&v0, &u0);
	
	return w;
}
Esempio n. 4
0
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;
}
Esempio n. 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);
  }
  
}
Esempio n. 6
0
void matrix3_scale(struct matrix3 *dst, const struct matrix3 *m,
		const struct vec3 *v)
{
	vec3_mul(&dst->x, &m->x, v);
	vec3_mul(&dst->y, &m->y, v);
	vec3_mul(&dst->z, &m->z, v);
	vec3_mul(&dst->t, &m->t, v);
}
Esempio n. 7
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());
}
Esempio n. 8
0
static void vertex_shader(const vertex_t *in, vs_to_fs_t *out)
{
	// decode vertex
	const vec3_t pc = { 0.5f, 0.5f, 0.5f }, nc = { 1.0f, 1.0f, 1.0f };
	const float pi = 1.0f / 65535.0f, ni = 2.0f / 255.0f, uvi = 1.0f / 255.0f;
	vec3_t position = vec3_sub(vec3_mul(vec3(in->x, in->y, in->z), pi), pc);
	vec3_t normal = vec3_sub(vec3_mul(vec3(in->nx, in->ny, in->nz), ni), nc);
	vec2_t uv = vec2_mul(vec2(in->u, in->v), uvi);
	// transform vertex
	out->position = mat4_transform_position(mvp, position);
	out->normal = mat4_transform_vector(mv, normal);
	out->uv = uv;
}
Esempio n. 9
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)));
  }
  
}
Esempio n. 10
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);

}
Esempio n. 11
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)));
  }

}
Esempio n. 12
0
//-----------------------------------------------------------------------------------------------------------------------------------------
// calcul la position dans le monde des coordonnées de l'objet
void ObjBones::Transform(ObjetU3D* obj) {
    CoordU3D*           ctmp = obj->Ctab;
    OneObjBones*        tmpB;
    BonesCoordListe*    cbtmp;
    Mat3x4              mat = obj->GetObjToWorld();

    /*  for( U32 a=0; a<obj->nbcoords; a++,ctmp++ )
            vec3_set( ctmp->trans, 0.0f, 0.0f, 0.0f );
        for( U32 a=0; a<obj->nbcoords; a++,ctmp++ )
            vec3_set( ctmp->origine, 0.0f, 0.0f, 0.0f );*/

    //------------- ini toutes les coords touchées par au moins 1 bone
    cbtmp = ListeCoord;
    while (cbtmp) {
        vec3_mul(cbtmp->coord->origine, cbtmp->origine, cbtmp->Influence);
        cbtmp = cbtmp->suiv;
    }

    tmpB = AllBones;
    while (tmpB) {
        tmpB->Transform();
        tmpB = tmpB->suiv;
    }

    //------------- Transform ensuite toute les coordonnées ki on été modifiées
    cbtmp = ListeCoord;
    while (cbtmp) {
        cbtmp->coord->trans[0] = mat.GetXTransfo(cbtmp->coord->origine);
        cbtmp->coord->trans[1] = mat.GetYTransfo(cbtmp->coord->origine);
        cbtmp->coord->trans[2] = mat.GetZTransfo(cbtmp->coord->origine);

        cbtmp = cbtmp->suiv;
    }
}
Esempio n. 13
0
float vec3_dot (const vec3 v1, const vec3 v2) {
  vec3 mul_result = vec3_mul(v1, v2);

  float result = mul_result.x + mul_result.y + mul_result.z;

  return result;
}
Esempio n. 14
0
//----------------------------------------------------------------------------------------------------------------------------------------
void OneNebuRayon::GetVal(Ufloat debut[3], Ufloat fin[3], Ufloat& intensity) {
    Ufloat pos = timeToGo / totalTime;

    vec3_mul(debut, vec, dist*pos);
    debut[0] += BIGPART_X;
    debut[1] += BIGPART_Y;
    debut[2] += BIGPART_Z;


    vec3_mul(fin, vec, (dist+taille)*pos);
    fin[0] += BIGPART_X;
    fin[1] += BIGPART_Y;
    fin[2] += BIGPART_Z;

    intensity = .7f - pos*pos*.7f;
}
Esempio n. 15
0
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);
  }
}
Esempio n. 16
0
t_real			collision_test_sphere_b(t_ray *ray, t_vec3 *sphere_pos)
{
	t_vec3				osp;
	t_vec3				dosp;

	osp = vec3_sub(ray->origin, *sphere_pos);
	dosp = vec3_mul(ray->direction, osp);
	return (2.0 * (dosp.x + dosp.y + dosp.z));
}
Esempio n. 17
0
//----------------------------------------------------------------------------------------------------------
// calcul new position des coord du bone
void OneObjBones::Transform() {
    BonesCoord* tmp = AllCoords;
    Ufloat      vtmp[3];

    for (U32 a=0; a<nbcoord; a++,tmp++) {
        WorldMatrix.GetTransfo(vtmp, tmp->origine);
        vec3_mul(vtmp, vtmp, tmp->Influence);
//      vec3_add( tmp->coord->trans, vtmp, tmp->coord->trans );
        vec3_add(tmp->coord->origine, vtmp, tmp->coord->origine);
    }
}
Esempio n. 18
0
vec3
vec3_lerp(const vec3 *v, const vec3 *u, float t)
{
	vec3 w;
	
	memset(&w, 0, sizeof(w));
	w = vec3_sub(u, v);
	w = vec3_mul(&w, t);
	w = vec3_add(v, &w);
	
	return w;
}
Esempio n. 19
0
static int _llfunc_vec3_mul(lua_State *L) {
	vec3 *v = (vec3*)userdata_get_or_die(L, 1);
	if (lua_isuserdata(L, 2)) {
		mat4 *m = (mat4*)lua_touserdata(L, 2);
		vec3 *r = (vec3*)userdata_get_or_new(L, 3, sizeof(vec3));
		vec3_mul_mat4(v, m, r);
	}
	else {
		float k = (float)luaL_checknumber(L, 2);
		vec3 *r = (vec3*)userdata_get_or_new(L, 3, sizeof(vec3));
		vec3_mul(v, k, r);
	}
	return 1;
}
Esempio n. 20
0
collision sphere_collide_sphere(sphere s, vec3 v, sphere s0) {

  //if (unlikely(!sphere_outside_sphere(s, s0))) { error("Collision Sphere Inside Sphere!"); }

  vec3  o = vec3_sub(s.center, s0.center);
  float A = vec3_dot(v, v);
  float B = 2 * vec3_dot(v, o);
  float C = vec3_dot(o, o) - ((s.radius + s0.radius) * (s.radius + s0.radius));
  
  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(); }
  
  vec3 proj = vec3_add(s.center, vec3_mul(v, t));
  vec3 twrd = vec3_normalize(vec3_sub(s0.center, proj));
  vec3 p = vec3_add(proj, vec3_mul(twrd, s.radius));
  
  return collision_new(t, p, vec3_normalize(vec3_sub(s.center, p)));

}
//----------------------------------------------------------------------------------------------------------------------------------------
void CoupleShadowP3D::IncAnim(Ufloat laptime) {
    Mat3x4  mat;
    Ufloat  tmp[3]= {0.0f,1.0f,0.0f};
    Ufloat  alpha = petal->GetAlpha();

    vec4_set(p1->RVBA, 1.0f, 1.0f, 1.0f, alpha);

    petal->GetQuat().matrix(mat);
    vec3_mul(tmp, petal->GetPos(), FACT_SCENE_CM);
    mat.SetPos(tmp[0], tmp[1], tmp[2]);
    mat *= petal->GetMass() + tmp[1]*.001f;


    for (U32 a=0; a<4; a++) {
        mat.GetTransfo(p1->Vtab[a]->c->trans, p1->Vtab[a]->c->origine);
        p1->Vtab[a]->c->trans[1] = 0.0f;
    }
}
Esempio n. 22
0
/*
 * Create the vertex array with vertexes in mip level order.
 */
static void lsc_setupPatchVtxArr(lsc l, int m,
								 int x0, int x1, int y0, int y1,
								 float *vtxArr)
{
	int i, j, k;
	vec3 v;
	unsigned char *hm = l->hm;
	int hmSize = l->hmSize;
	int patchSize = l->patchSize;
	float texScale = (float)l->texTile / (float)l->hmSize;
	float baseTexScale = (float)l->baseTexTile / (float)l->hmSize;
	int S = x0 % (l->hmSize / l->texTile);
	int T = y0 % (l->hmSize / l->texTile);
	unsigned short *patchIdx = l->patchIdx;

	if (hm)
		hm = &hm[x0 + y0*(hmSize+1)];

	for (j = 0; j <= patchSize; j++) {
		for (i = 0; i <= patchSize; i++) {

			k = patchIdx[j*(patchSize + 1) + i];

			v[0] = i + x0;
			v[1] = j + y0;

			/* Texture 0 */
			vtxArr[8*k + 4] = (S + i) * texScale;
			vtxArr[8*k + 5] = (T + j) * texScale;

			/* Texture 1 */
			vtxArr[8*k + 6] = v[0] * baseTexScale;
			vtxArr[8*k + 7] = v[1] * baseTexScale;

			/* Vertex */
			if (hm)
				v[2] = hm[j*(hmSize + 1) + i];
			else
				v[2] = 0.0f;
			vec3_mul(v, l->scale, v);
			vec3_cpy(v, (&vtxArr[8*k]));
		}
	}
}
//----------------------------------------------------------------------------------------------------------------------------------------
void CoupleOnePetals3D::IncAnim(Ufloat laptime) {
    Mat3x4  mat;
    Ufloat  tmp[3];

    CalcPos(laptime);

    Ufloat alpha = GetAlpha();

    vec4_set(p1->RVBA, 1.0f, 1.0f, 1.0f, alpha);
    vec4_set(p2->RVBA, 1.0f, 1.0f, 1.0f, alpha);

    rot *= incrot * laptime;
    rot.matrix(mat);
    vec3_mul(tmp, GetPos(), FACT_SCENE_CM);
    mat.SetPos(tmp[0], tmp[1], tmp[2]);

    for (U32 a=0; a<6; a++)
        mat.GetTransfo(coord[a]->trans, coord[a]->origine);
}
Esempio n. 24
0
pixel_data_t world_render(world_t *world, camera_t *camera) {
    pixel_t **pixels = calloc(camera->h, sizeof(pixel_t *));
    for (uint32_t i = 0; i < camera->h; i++) {
        pixels[i] = malloc(sizeof(pixel_t) * camera->w);
    }
    
    pixel_data_t pixel_data = { camera->w, camera->h, pixels };
    
    for (uint32_t x = 0; x < camera->w; x++) {
        for (uint32_t y = 0; y < camera->h; y++) {
            ray_t *ray = ray_new(camera->pos, dir_for_pixel(camera, x, y));
            sphere_t *sphere = ptr_array_index(world->spheres, 0);
            vec3_t normal;
            double distance;
            if (!object_get_collision(OBJECT(sphere), ray, &distance, &normal))
                continue;
            
            vec3_t p = vec3_add(ray->pos, vec3_mul(ray->dir, distance));
            
            pixel_t pixel = { 1, 0, 0, 0 };
            for (uint32_t i = 0; i < world->lights->len; i++) {
                light_t *light = ptr_array_index(world->lights, i);
                
                vec3_t l = vec3_normalize(vec3_sub(p, light->pos));
                
                double lambert = MAX(0, vec3_dot(l, normal) * LAMBERT_COEF);
                
                pixel.a = 1;
                pixel.r += 1 * lambert;
                pixel.g += 1 * lambert;
                pixel.b += 1 * lambert;
            }
            
            pixels[x][y] = pixel;
        }
    }
    
    return pixel_data;
}
Esempio n. 25
0
t_vec3		raytracing_color(t_env *e, t_ray *ray, t_cam *cam, t_obj *obj)
{
	t_lgt	*light;
	t_vec3	color;
	t_vec3	diffuse;
	t_vec3	specular;

	color = (t_vec3) {0, 0, 0};
	light = e->lgt;
	while (light != NULL)
	{
		set_light(ray->hit, obj, light);
		set_color(obj, ray);
		color = vec3_add(color, vec3_fmul(light->color, obj->mat.ambient));
		diffuse = set_diffuse(obj, light);
		specular = set_specular(obj, cam, light);
		color = vec3_add(color, vec3_add(diffuse, specular));
		color = vec3_mul(color, obj->mat.color);
		obj->mat.receive_shadow ? set_shadow(e, &color, *light, obj) : 0;
		light = light->next;
	}
	return (color);
}
Esempio n. 26
0
collision point_collide_face(vec3 p, vec3 v, ctri ct) {
  
  float angle = vec3_dot(ct.norm, v);
  float dist  = vec3_dot(ct.norm, vec3_sub(p, ct.a)); 
  
  float t0 = -dist / angle;
  float t1 = -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(p, vec3_mul(v, t));
  
  if (!point_inside_triangle(cpoint, ct.a, ct.b, ct.c)) {
    return collision_none();
  } else {
    return collision_new(t, cpoint, ct.norm);
  }

}
Esempio n. 27
0
void bounds_scale(struct bounds *dst, const struct bounds *b,
		const struct vec3 *v)
{
	vec3_mul(&dst->min, &b->min, v);
	vec3_mul(&dst->max, &b->max, v);
}
Esempio n. 28
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;
}
/*
 * This function is called (see bottom of this file for more details)
 * whenever the OBS filter interface changes. So when the user is messing
 * with a slider this function is called to update the internal settings
 * in OBS, and hence the settings being passed to the CPU/GPU.
 */
static void color_correction_filter_update(void *data, obs_data_t *settings)
{
	struct color_correction_filter_data *filter = data;

	/* Build our Gamma numbers. */
	double gamma = obs_data_get_double(settings, SETTING_GAMMA);
	gamma = (gamma < 0.0) ? (-gamma + 1.0) : (1.0 / (gamma + 1.0));
	vec3_set(&filter->gamma, (float)gamma, (float)gamma, (float)gamma);

	/* Build our contrast number. */
	filter->contrast = (float)obs_data_get_double(settings,
			SETTING_CONTRAST) + 1.0f;
	float one_minus_con = (1.0f - filter->contrast) / 2.0f;

	/* Now let's build our Contrast matrix. */
	filter->con_matrix = (struct matrix4)
	{
		filter->contrast, 0.0f, 0.0f, 0.0f,
		0.0f, filter->contrast, 0.0f, 0.0f,
		0.0f, 0.0f, filter->contrast, 0.0f,
		one_minus_con, one_minus_con, one_minus_con, 1.0f
	};

	/* Build our brightness number. */
	filter->brightness = (float)obs_data_get_double(settings,
			SETTING_BRIGHTNESS);

	/*
	 * Now let's build our Brightness matrix.
	 * Earlier (in the function color_correction_filter_create) we set
	 * this matrix to the identity matrix, so now we only need
	 * to set the 3 variables that have changed.
	 */
	filter->bright_matrix.t.x = filter->brightness;
	filter->bright_matrix.t.y = filter->brightness;
	filter->bright_matrix.t.z = filter->brightness;

	/* Build our Saturation number. */
	filter->saturation = (float)obs_data_get_double(settings,
			SETTING_SATURATION) + 1.0f;

	/* Factor in the selected color weights. */
	float one_minus_sat = (1.0f - filter->saturation) / 3.0f;
	float sat_val = one_minus_sat + filter->saturation;

	/* Now we build our Saturation matrix. */
	filter->sat_matrix = (struct matrix4)
	{
		sat_val, one_minus_sat, one_minus_sat, 0.0f,
		one_minus_sat, sat_val, one_minus_sat, 0.0f,
		one_minus_sat, one_minus_sat, sat_val, 0.0f,
		0.0f, 0.0f, 0.0f, 1.0f
	};

	/* Build our Hue number. */
	filter->hue_shift = (float)obs_data_get_double(settings,
			SETTING_HUESHIFT);

	/* Build our Transparency number. */
	filter->opacity = (float)obs_data_get_int(settings,
			SETTING_OPACITY) * 0.01f;

	/* Hue is the radian of 0 to 360 degrees. */
	float half_angle = 0.5f * (float)(filter->hue_shift / (180.0f / M_PI));

	/* Pseudo-Quaternion To Matrix. */
	float rot_quad1 = root3 * (float)sin(half_angle);
	vec3_set(&filter->rot_quaternion, rot_quad1, rot_quad1,
			rot_quad1);
	filter->rot_quaternion_w = (float)cos(half_angle);

	vec3_mul(&filter->cross, &filter->rot_quaternion,
			&filter->rot_quaternion);
	vec3_mul(&filter->square, &filter->rot_quaternion,
			&filter->rot_quaternion);
	vec3_mulf(&filter->wimag, &filter->rot_quaternion,
			filter->rot_quaternion_w);

	vec3_mulf(&filter->square, &filter->square, 2.0f);
	vec3_sub(&filter->diag, &filter->half_unit, &filter->square);
	vec3_add(&filter->a_line, &filter->cross, &filter->wimag);
	vec3_sub(&filter->b_line, &filter->cross, &filter->wimag);

	/* Now we build our Hue and Opacity matrix. */
	filter->hue_op_matrix = (struct matrix4)
	{
		filter->diag.x * 2.0f,
		filter->b_line.z * 2.0f,
		filter->a_line.y * 2.0f,
		0.0f,

		filter->a_line.z * 2.0f,
		filter->diag.y * 2.0f,
		filter->b_line.x * 2.0f,
		0.0f,

		filter->b_line.y * 2.0f,
		filter->a_line.x * 2.0f,
		filter->diag.z * 2.0f,
		0.0f,

		0.0f, 0.0f, 0.0f, filter->opacity
	};

	/* Now get the overlay color data. */
	uint32_t color = (uint32_t)obs_data_get_int(settings,
			SETTING_COLOR);
	vec4_from_rgba(&filter->color, color);

	/*
	* Now let's build our Color 'overlay' matrix.
	* Earlier (in the function color_correction_filter_create) we set
	* this matrix to the identity matrix, so now we only need
	* to set the 6 variables that have changed.
	*/
	filter->color_matrix.x.x = filter->color.x;
	filter->color_matrix.y.y = filter->color.y;
	filter->color_matrix.z.z = filter->color.z;

	filter->color_matrix.t.x = filter->color.w *
			filter->color.x;
	filter->color_matrix.t.y = filter->color.w *
			filter->color.y;
	filter->color_matrix.t.z = filter->color.w *
			filter->color.z;


	/* First we apply the Contrast & Brightness matrix. */
	matrix4_mul(&filter->final_matrix, &filter->bright_matrix,
			&filter->con_matrix);
	/* Now we apply the Saturation matrix. */
	matrix4_mul(&filter->final_matrix, &filter->final_matrix,
			&filter->sat_matrix);
	/* Next we apply the Hue+Opacity matrix. */
	matrix4_mul(&filter->final_matrix, &filter->final_matrix,
			&filter->hue_op_matrix);
	/* Lastly we apply the Color Wash matrix. */
	matrix4_mul(&filter->final_matrix, &filter->final_matrix,
			&filter->color_matrix);
}

/*
 * Since this is C we have to be careful when destroying/removing items from
 * OBS. Jim has added several useful functions to help keep memory leaks to
 * a minimum, and handle the destruction and construction of these filters.
 */
static void color_correction_filter_destroy(void *data)
{
	struct color_correction_filter_data *filter = data;

	if (filter->effect) {
		obs_enter_graphics();
		gs_effect_destroy(filter->effect);
		obs_leave_graphics();
	}

	bfree(data);
}

/*
 * When you apply a filter OBS creates it, and adds it to the source. OBS also
 * starts rendering it immediately. This function doesn't just 'create' the
 * filter, it also calls the render function (farther below) that contains the
 * actual rendering code.
 */
static void *color_correction_filter_create(obs_data_t *settings,
	obs_source_t *context)
{
	/*
	* Because of limitations of pre-c99 compilers, you can't create an
	* array that doesn't have a known size at compile time. The below
	* function calculates the size needed and allocates memory to
	* handle the source.
	*/
	struct color_correction_filter_data *filter =
		bzalloc(sizeof(struct color_correction_filter_data));

	/*
	 * By default the effect file is stored in the ./data directory that
	 * your filter resides in.
	 */
	char *effect_path = obs_module_file("color_correction_filter.effect");

	filter->context = context;

	/* Set/clear/assign for all necessary vectors. */
	vec3_set(&filter->half_unit, 0.5f, 0.5f, 0.5f);
	matrix4_identity(&filter->bright_matrix);
	matrix4_identity(&filter->color_matrix);

	/* Here we enter the GPU drawing/shader portion of our code. */
	obs_enter_graphics();

	/* Load the shader on the GPU. */
	filter->effect = gs_effect_create_from_file(effect_path, NULL);

	/* If the filter is active pass the parameters to the filter. */
	if (filter->effect) {
		filter->gamma_param = gs_effect_get_param_by_name(
				filter->effect, SETTING_GAMMA);
		filter->final_matrix_param = gs_effect_get_param_by_name(
				filter->effect, "color_matrix");
	}

	obs_leave_graphics();

	bfree(effect_path);

	/*
	 * If the filter has been removed/deactivated, destroy the filter
	 * and exit out so we don't crash OBS by telling it to update
	 * values that don't exist anymore.
	 */
	if (!filter->effect) {
		color_correction_filter_destroy(filter);
		return NULL;
	}

	/*
	 * It's important to call the update function here. If we don't
	 * we could end up with the user controlled sliders and values
	 * updating, but the visuals not updating to match.
	 */
	color_correction_filter_update(filter, settings);
	return filter;
}

/* This is where the actual rendering of the filter takes place. */
static void color_correction_filter_render(void *data, gs_effect_t *effect)
{
	struct color_correction_filter_data *filter = data;

	if (!obs_source_process_filter_begin(filter->context, GS_RGBA,
			OBS_ALLOW_DIRECT_RENDERING))
		return;

	/* Now pass the interface variables to the .effect file. */
	gs_effect_set_vec3(filter->gamma_param, &filter->gamma);
	gs_effect_set_matrix4(filter->final_matrix_param, &filter->final_matrix);

	obs_source_process_filter_end(filter->context, filter->effect, 0, 0);

	UNUSED_PARAMETER(effect);
}

/*
 * This function sets the interface. the types (add_*_Slider), the type of
 * data collected (int), the internal name, user-facing name, minimum,
 * maximum and step values. While a custom interface can be built, for a
 * simple filter like this it's better to use the supplied functions.
 */
static obs_properties_t *color_correction_filter_properties(void *data)
{
	obs_properties_t *props = obs_properties_create();

	obs_properties_add_float_slider(props, SETTING_GAMMA,
			TEXT_GAMMA, -3.0f, 3.0f, 0.01f);

	obs_properties_add_float_slider(props, SETTING_CONTRAST,
			TEXT_CONTRAST, -2.0f, 2.0f, 0.01f);
	obs_properties_add_float_slider(props, SETTING_BRIGHTNESS,
			TEXT_BRIGHTNESS, -1.0f, 1.0f, 0.01f);
	obs_properties_add_float_slider(props, SETTING_SATURATION,
			TEXT_SATURATION, -1.0f, 5.0f, 0.01f);
	obs_properties_add_float_slider(props, SETTING_HUESHIFT,
			TEXT_HUESHIFT, -180.0f, 180.0f, 0.01f);
	obs_properties_add_int_slider(props, SETTING_OPACITY,
			TEXT_OPACITY, 0, 100, 1);

	obs_properties_add_color(props, SETTING_COLOR, TEXT_COLOR);

	UNUSED_PARAMETER(data);
	return props;
}

/*
 * As the functions' namesake, this provides the default settings for any
 * options you wish to provide a default for. Try to select defaults that
 * make sense to the end user, or that don't effect the data.
 * *NOTE* this function is completely optional, as is providing a default
 * for any particular setting.
 */
static void color_correction_filter_defaults(obs_data_t *settings)
{
	obs_data_set_default_double(settings, SETTING_GAMMA, 0.0);
	obs_data_set_default_double(settings, SETTING_CONTRAST, 0.0);
	obs_data_set_default_double(settings, SETTING_BRIGHTNESS, 0.0);
	obs_data_set_default_double(settings,
			SETTING_SATURATION, 0.0);
	obs_data_set_default_double(settings, SETTING_HUESHIFT, 0.0);
	obs_data_set_default_double(settings, SETTING_OPACITY, 100.0);
	obs_data_set_default_int(settings, SETTING_COLOR, 0xFFFFFF);
}

/*
 * So how does OBS keep track of all these plug-ins/filters? How does OBS know
 * which function to call when it needs to update a setting? Or a source? Or
 * what type of source this is?
 *
 * OBS does it through the obs_source_info_struct. Notice how variables are
 * assigned the name of a function? Notice how the function name has the
 * variable name in it? While not mandatory, it helps a ton for you (and those
 * reading your code) to follow this convention.
 */
struct obs_source_info color_filter = {
	.id = "color_filter",
	.type = OBS_SOURCE_TYPE_FILTER,
	.output_flags = OBS_SOURCE_VIDEO,
	.get_name = color_correction_filter_name,
	.create = color_correction_filter_create,
	.destroy = color_correction_filter_destroy,
	.video_render = color_correction_filter_render,
	.update = color_correction_filter_update,
	.get_properties = color_correction_filter_properties,
	.get_defaults = color_correction_filter_defaults
};
Esempio n. 30
0
union vec3* vec3_mul_self(union vec3 *vi, float scalar)
{
	return vec3_mul(vi, vi, scalar);
}