Exemplo n.º 1
0
t_bool          dielectric(t_material *material, const t_ray *r, const t_hit_record *h, t_vec3 *attenuation, t_ray *scattered)
{
    t_vec3      outward_normal;
    t_vec3      reflected;
    t_vec3      refracted;
    float       ni_over_nt;
    float       reflect_probe;
    float       cosine;

    vec3_reflect(&reflected, &RAY_DIRECTION(r), &h->normal);
    vec3_assign(attenuation, &material->texture.albedo);
    if (vec3_dot(&RAY_DIRECTION(r), &h->normal) > 0)
    {
        vec3_mul_f(&outward_normal, &h->normal, -1.f);
        //TODO pass idx
        ni_over_nt = REF_IDX;
        cosine = REF_IDX * vec3_dot(&RAY_DIRECTION(r), &h->normal) / vec3_length(&RAY_DIRECTION(r));
    }
    else
    {
        vec3_assign(&outward_normal, &h->normal);
        ni_over_nt = 1.0f / REF_IDX;
        cosine = - vec3_dot(&RAY_DIRECTION(r), &h->normal) / vec3_length(&RAY_DIRECTION(r));
    }
    if (refract(&RAY_DIRECTION(r), &outward_normal, ni_over_nt, &refracted))
        reflect_probe = schlick(cosine, REF_IDX);
    else
        reflect_probe = 1.0f;
    if (drand48() < reflect_probe)
        ray_assign(scattered, &h->pos, &reflected);
    else
        ray_assign(scattered, &h->pos, &refracted);
    return (TRUE);
}
Exemplo n.º 2
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);
  

}
Exemplo n.º 3
0
/**
 * @brief CM_NeedsSubdivision
 * @param a
 * @param b
 * @param c
 * @return true if the given quadratic curve is not flat enough for our
 * collision detection purposes
 */
static qboolean CM_NeedsSubdivision(vec3_t a, vec3_t b, vec3_t c)
{
	vec3_t cmid;
	vec3_t lmid;
	vec3_t delta;
	float  dist;
	int    i;

	// calculate the linear midpoint
	for (i = 0 ; i < 3 ; i++)
	{
		lmid[i] = 0.5f * (a[i] + c[i]);
	}

	// calculate the exact curve midpoint
	for (i = 0 ; i < 3 ; i++)
	{
		cmid[i] = 0.5f * (0.5f * (a[i] + b[i]) + 0.5f * (b[i] + c[i]));
	}

	// see if the curve is far enough away from the linear mid
	VectorSubtract(cmid, lmid, delta);
	dist = vec3_length(delta);

	return dist >= SUBDIVIDE_DISTANCE;
}
Exemplo n.º 4
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.º 5
0
static int player_in_fov(vec3_t viewangle, vec3_t ppos, vec3_t opos)
{
	float  yaw, pitch, cos_angle;
	vec3_t dir, los;

	VectorSubtract(opos, ppos, los);

	// Check if the two players are roughly on the same X/Y plane
	// and skip the test if not. We only want to eliminate info that
	// would reveal the position of opponents behind the player on
	// the same X/Y plane (e.g. on the same floor in a room).
	if (vec3_length(los) < 5 * fabs(opos[2] - ppos[2]))
	{
		return 1;
	}

	// calculate unit vector of the direction the player looks at
	yaw    = viewangle[YAW] * (M_PI * 2 / 360);
	pitch  = viewangle[PITCH] * (M_PI * 2 / 360);
	dir[0] = cos(yaw) * cos(pitch);
	dir[1] = sin(yaw);
	dir[2] = cos(yaw) * sin(pitch);

	// calculate unit vector corresponding to line of sight to opponent
	vec3_norm(los);

	// calculate and test the angle between the two vectors
	cos_angle = DotProduct(dir, los);
	if (cos_angle > 0)      // +/- 90 degrees (fov = 180)
	{
		return 1;
	}

	return 0;
}
Exemplo n.º 6
0
float rayIntersectDisk(ShadeRec* sr, Disk* disk, const Ray ray)
{
    vec3 displacement;
    vec3_sub(displacement, disk->center, ray.origin);
    float t = vec3_dot(displacement, disk->normal) / vec3_dot(ray.direction, disk->normal);
    if(t > K_EPSILON)
    {
        vec3 hit_point;
        getPointOnRay(hit_point, ray, t);
        vec3_sub(displacement, hit_point, disk->center);
        if(vec3_length(displacement) <= disk->radius)
        {
            vec3_negate(sr->wo, ray.direction);
            if(vec3_dot(sr->wo, disk->normal) < 0)
            {
                vec3_negate(sr->wo, disk->normal);
            }else
            {
                vec3_copy(sr->normal, disk->normal);
            }
            vec3_copy(sr->hit_point, hit_point);
            sr->mat = *(disk->mat);
            return t;
        }
    }
    return TMAX;
}
Exemplo n.º 7
0
	/* Calculates if a position is eclipsed.  */
bool is_eclipsed(const double pos[3], const double sol[3], double *depth)
{
	double Rho[3], earth[3];

	/* Determine partial eclipse */
	double sd_earth = ArcSin(xkmper / vec3_length(pos));
	vec3_sub(sol, pos, Rho);
	double sd_sun = ArcSin(sr / vec3_length(Rho));
	vec3_mul_scalar(pos, -1, earth);
	
	double delta = ArcCos( vec3_dot(sol, earth) / vec3_length(sol) / vec3_length(earth) );
	*depth = sd_earth - sd_sun - delta;

	if (sd_earth < sd_sun) return false;
	else if (*depth >= 0) return true;
	else return false;
}
Exemplo n.º 8
0
Arquivo: vec3.c Projeto: Raphy42/RT
inline t_vec3      *vec3_normalize(t_vec3 *v)
{
    float   length;

    length = vec3_length(v);
    v = vec3_div_f(v, v, length);
    return (v);
}
Exemplo n.º 9
0
vec3
vec3_normalize(const vec3 *v)
{
	float len = vec3_length(v);
	vec3 u;
	
	u.x = v->x / len;
	u.y = v->y / len;
	u.z = v->z / len;
	
	return u;
}
Exemplo n.º 10
0
/*
=======================================================================================================================================
WindingArea
=======================================================================================================================================
*/
vec_t WindingArea(winding_t *w) {
	int i;
	vec3_t d1, d2, cross;
	vec_t total = 0;

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

	return total;
}
Exemplo n.º 11
0
float shadowRayIntersectDisk(const Disk* disk, const Ray ray)
{
    vec3 displacement;
    vec3_sub(displacement, disk->center, ray.origin);
    float t = vec3_dot(displacement, disk->normal) / vec3_dot(ray.direction, disk->normal);
    if(t > K_EPSILON)
    {
        vec3 hit_point;
        getPointOnRay(hit_point, ray, t);        
        vec3_sub(displacement, hit_point, disk->center);
        if(vec3_length(displacement) <= disk->radius)
        {
            return t;
        }
    }
    return TMAX;
}
Exemplo n.º 12
0
quat
quat_to_axis(const quat *q)
{
	vec3 axis = {q->x, q->y, q->z};
	quat tmp = {0.f, 1.f, 0.f, 0.f};
	float length;

	tmp.w = 2 * acos(q->w);
	//if ((int)(tmp.w) > 0 || (int)(tmp.w) < 0) {
		length = vec3_length(&axis);
		tmp.x = q->x / length;
		tmp.y = q->y / length;
		tmp.z = q->z / length;
		tmp.w = tmp.w * (180.f/M_PI); /* To degrees */
	//}

	return tmp;
}
Exemplo n.º 13
0
/**
 * @brief Changes the position of client 'other' so that it is directly
 * below 'player'. The distance is maintained so that sound scaling
 * will work correctly.
 */
void SV_RandomizePos(int player, int other)
{
	sharedEntity_t *pent, *oent;
	vec3_t         los;
	float          dist;

	pent = SV_GentityNum(player);
	oent = SV_GentityNum(other);

	VectorCopy(oent->s.pos.trBase, old_origin[other]);
	origin_changed[other] = 1;

	// get distance (we need it for correct sound scaling)
	VectorSubtract(oent->s.pos.trBase, pent->s.pos.trBase, los);
	dist = vec3_length(los);

	// set the opponent's position directly below the player
	VectorCopy(pent->s.pos.trBase, oent->s.pos.trBase);
	oent->s.pos.trBase[2] -= dist;
}
Exemplo n.º 14
0
// ----------------------------------------------------------------------------
void IKSolver::DrawDebugGeometry(DebugRenderer* debug, bool depthTest)
{
    // Draws all scene segments
    for (auto & it : effectorList_)
        it->DrawDebugGeometry(debug, depthTest);

    ORDERED_VECTOR_FOR_EACH(&solver_->effector_nodes_list, ik_node_t*, pnode)
        ik_effector_t* effector = (*pnode)->effector;

        // Calculate average length of all segments so we can determine the radius
        // of the debug spheres to draw
        int chainLength = effector->chain_length == 0 ? -1 : effector->chain_length;
        ik_node_t* a = *pnode;
        ik_node_t* b = a->parent;
        float averageLength = 0.0f;
        unsigned numberOfSegments = 0;
        while (b && chainLength-- != 0)
        {
            vec3_t v = a->original_position;
            vec3_sub_vec3(v.f, b->original_position.f);
            averageLength += vec3_length(v.f);
            ++numberOfSegments;
            a = b;
            b = b->parent;
        }
        averageLength /= numberOfSegments;

        // connect all chained nodes together with lines
        chainLength = effector->chain_length == 0 ? -1 : effector->chain_length;
        a = *pnode;
        b = a->parent;
        debug->AddSphere(
            Sphere(Vec3IK2Urho(&a->original_position), averageLength * 0.1f),
            Color(0, 0, 255),
            depthTest
        );
        debug->AddSphere(
            Sphere(Vec3IK2Urho(&a->position), averageLength * 0.1f),
            Color(255, 128, 0),
            depthTest
        );
        while (b && chainLength-- != 0)
        {
            debug->AddLine(
                Vec3IK2Urho(&a->original_position),
                Vec3IK2Urho(&b->original_position),
                Color(0, 255, 255),
                depthTest
            );
            debug->AddSphere(
                Sphere(Vec3IK2Urho(&b->original_position), averageLength * 0.1f),
                Color(0, 0, 255),
                depthTest
            );
            debug->AddLine(
                Vec3IK2Urho(&a->position),
                Vec3IK2Urho(&b->position),
                Color(255, 0, 0),
                depthTest
            );
            debug->AddSphere(
                Sphere(Vec3IK2Urho(&b->position), averageLength * 0.1f),
                Color(255, 128, 0),
                depthTest
            );
            a = b;
            b = b->parent;
        }
    ORDERED_VECTOR_END_EACH
}
Exemplo n.º 15
0
/*
=======================================================================================================================================
CheckWinding
=======================================================================================================================================
*/
void CheckWinding(winding_t *w) {
	int i, j;
	vec_t *p1, *p2;
	vec_t d, edgedist;
	vec3_t dir, edgenormal, facenormal;
	vec_t area;
	vec_t facedist;

	if (w->numpoints < 3) {
		Com_Error(ERR_DROP, "CheckWinding: %i points", w->numpoints);
	}

	area = WindingArea(w);

	if (area < 1) {
		Com_Error(ERR_DROP, "CheckWinding: %f area", (double)area);
	}

	WindingPlane(w, facenormal, &facedist);

	for (i = 0; i < w->numpoints; i++) {
		p1 = w->p[i];

		for (j = 0; j < 3; j++) {
			if (p1[j] > MAX_MAP_BOUNDS || p1[j] < -MAX_MAP_BOUNDS) {
				Com_Error(ERR_DROP, "CheckWinding: MAX_MAP_BOUNDS: %f", (double)p1[j]);
			}
		}

		j = i + 1 == w->numpoints ? 0 : i + 1;
		// check the point is on the face plane
		d = DotProduct(p1, facenormal) - facedist;

		if (d < -ON_EPSILON || d > ON_EPSILON) {
			Com_Error(ERR_DROP, "CheckWinding: point off plane");
		}
		// check the edge isn't degenerate
		p2 = w->p[j];

		VectorSubtract(p2, p1, dir);

		if (vec3_length(dir) < ON_EPSILON) {
			Com_Error(ERR_DROP, "CheckWinding: degenerate edge");
		}

		vec3_cross(facenormal, dir, edgenormal);
		vec3_norm2(edgenormal, edgenormal);

		edgedist = DotProduct(p1, edgenormal);
		edgedist += ON_EPSILON;
		// all other points must be on front side
		for (j = 0; j < w->numpoints; j++) {
			if (j == i) {
				continue;
			}

			d = DotProduct(w->p[j], edgenormal);

			if (d > edgedist) {
				Com_Error(ERR_DROP, "CheckWinding: non-convex");
			}
		}
	}
}
Exemplo n.º 16
0
void Calculate_Obs(double time, const double pos[3], const double vel[3], geodetic_t *geodetic, vector_t *obs_set)
{
	/* The procedures Calculate_Obs and Calculate_RADec calculate         */
	/* the *topocentric* coordinates of the object with ECI position,     */
	/* {pos}, and velocity, {vel}, from location {geodetic} at {time}.    */
	/* The {obs_set} returned for Calculate_Obs consists of azimuth,      */
	/* elevation, range, and range rate (in that order) with units of     */
	/* radians, radians, kilometers, and kilometers/second, respectively. */
	/* The WGS '72 geoid is used and the effect of atmospheric refraction */
	/* (under standard temperature and pressure) is incorporated into the */
	/* elevation calculation; the effect of atmospheric refraction on     */
	/* range and range rate has not yet been quantified.                  */

	/* The {obs_set} for Calculate_RADec consists of right ascension and  */
	/* declination (in that order) in radians.  Again, calculations are   */
	/* based on *topocentric* position using the WGS '72 geoid and        */
	/* incorporating atmospheric refraction.                              */

	double sin_lat, cos_lat, sin_theta, cos_theta, el, azim, top_s, top_e, top_z;

	double obs_pos[3];
	double obs_vel[3];
	double range[3];
	double rgvel[3];

	Calculate_User_PosVel(time, geodetic, obs_pos, obs_vel);

	vec3_sub(pos, obs_pos, range);
	vec3_sub(vel, obs_vel, rgvel);
	
	double range_length = vec3_length(range);

	sin_lat=sin(geodetic->lat);
	cos_lat=cos(geodetic->lat);
	sin_theta=sin(geodetic->theta);
	cos_theta=cos(geodetic->theta);
	top_s=sin_lat*cos_theta*range[0]+sin_lat*sin_theta*range[1]-cos_lat*range[2];
	top_e=-sin_theta*range[0]+cos_theta*range[1];
	top_z=cos_lat*cos_theta*range[0]+cos_lat*sin_theta*range[1]+sin_lat*range[2];
	azim=atan(-top_e/top_s); /* Azimuth */

	if (top_s>0.0) 
		azim=azim+pi;

	if (azim<0.0)
		azim = azim + 2*M_PI;

	el=ArcSin(top_z/range_length);
	obs_set->x=azim;	/* Azimuth (radians)   */
	obs_set->y=el;		/* Elevation (radians) */
	obs_set->z=range_length;	/* Range (kilometers)  */

	/* Range Rate (kilometers/second) */
	obs_set->w = vec3_dot(range, rgvel)/vec3_length(range);
	obs_set->y=el;

	/**** End bypass ****/

	if (obs_set->y<0.0)
		obs_set->y=el;  /* Reset to true elevation */
}
Exemplo n.º 17
0
VEC3 vec3_normalize(VEC3 v)
{
  return vec3_divide(v, vec3_length(v));
}
Exemplo n.º 18
0
vec3 *vec3_norm(vec3 *vec) {
	return vec3_div_float(vec, vec3_length(vec));
}
Exemplo n.º 19
0
Vec3 vec3_normalize(Vec3 a)
{
	return vec3_scale(1/vec3_length(a), a);
}
Exemplo n.º 20
0
Arquivo: vec3.c Projeto: Raphy42/RT
/**
 * return src / src.length
 */
inline t_vec3      *vec3_unit_vector(t_vec3 *v, const t_vec3 *src)
{
    return (vec3_assign(v, vec3_div_f(v, src, vec3_length(src))));
}