static void spherical_lerp(float *v1, float *v2, float d, float *vout)
{
	float v1xv2[3];
	float v3[3];

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

	vec3_cross(v1, v2, v1xv2);

	double theta;

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

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

	double phi = d * theta;

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

	int i = 0;
	float cos_phi = cos(phi);
	float sin_phi = sin(phi);
	for (i = 0; i < 3; i++) {
		vout[i] = (cos_phi * v1[i] + sin_phi * v3[i]) * (v1_norm * (1-d) + v2_norm * d);
	}
}
Exemple #2
0
Camera::Camera(vec3 u, vec3 loc, vec3 la, float a, int width, int height): angle(a){
  up = u;
  location = loc;
  lookat = la;

  camz = vec3_norm(vec3_sub(lookat, location));
  camx = vec3_norm(vec3_mul_cross(up, camz));

  camy = vec3_mul_cross(camx, vec3_sub((vec3) {0., 0., 0.}, camz));
  camy = vec3_norm(camy);

  tax = tan(angle);
  tay = tan(((float) height / (float) width) * angle);
}
Exemple #3
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;
}
Exemple #4
0
static t_rgb	compute_gradient(double *grad, t_obj *obj)
{
	t_vec3		color;
	double		diffx;
	double		diffy;
	double		scale;

	scale = obj->mat.texture.normal_strength;
	diffx = grad[1] - grad[2];
	diffy = grad[0] - grad[3];
	color.x = vec3_norm(vec3(1, diffx * scale, 0)).y;
	color.y = vec3_norm(vec3(1, diffy * scale, 0)).y;
	color.z = sqrt(1 - ft_clampf(color.x * color.x + color.y * color.y, 0, 1));
	vec3_normalize(&color);
	return (vec3_to_rgb(vec3_add(vec3_fmul(color, 0.5), vec3(0.5, 0.5, 0.5))));
}
Exemple #5
0
void		set_light(t_vec3 hit, t_obj *obj, t_lgt *light)
{
	double	theta;
	double	epsilon;

	light->ray.pos = hit;
	if (light->type == DIRECTIONAL)
	{
		light->ray.dir = vec3_fmul(light->dir, -1);
		obj->dist_attenuation = 1.0;
	}
	else
	{
		light->ray.dir = vec3_sub(light->pos, hit);
		obj->t = vec3_magnitude(light->ray.dir);
		obj->dist_attenuation = (1.0 + obj->t * obj->t * light->attenuation);
	}
	if (light->type == SPOT)
	{
		theta = vec3_dot(light->dir, vec3_norm(vec3_fmul(light->ray.dir, -1)));
		epsilon = light->cutoff - light->cutoff_outer;
		light->cutoff_intensity = ft_clampf((theta - light->cutoff_outer) /
			epsilon, 0, 1);
	}
	vec3_normalize(&light->ray.dir);
}
Exemple #6
0
static inline void _setup_camera(game *g) {
    if (g->d.ortho) {
        mat4x4_ortho(g->d.proj, -g->aspect, g->aspect, -1, 1, 0.001, 1000);
    } else {
        mat4x4_perspective(g->d.proj, 45.0, g->aspect, 0.001, 1000.0);
    }

    vec3_sub(g->d.view_f, g->d.center, g->d.eye);
    vec3_norm(g->d.view_f, g->d.view_f);

    vec3_mul_cross(g->d.view_r, g->d.view_f, g->d.up);
    vec3_norm(g->d.view_r, g->d.view_r);

    vec3_mul_cross(g->d.view_u, g->d.view_r, g->d.view_f);

    _calc_zoom(g, 0); // Update zoom for this view type
}
void vec3_normalize(float *v)
{
	int i;
	float norm = vec3_norm(v);
	if (norm > 0) {
		for (i = 0; i < 3; i++) {
			v[i] *= 1.0/norm;
		}
	}
}
Exemple #8
0
void plane_transform(struct plane *dst, const struct plane *p,
		const struct matrix3 *m)
{
	struct vec3 temp;

	vec3_transform(&dst->dir, &p->dir, m);
	vec3_norm(&dst->dir, &dst->dir);

	vec3_transform(&temp, &m->t, m);
	dst->dist = p->dist - vec3_dot(&dst->dir, &temp);
}
Exemple #9
0
void GetRotationbyVector(mat33_t *R, const vec3_t *v1, const vec3_t *v2)
{
	 vec3_t diff;
  vec3_sub_vec2(&diff, v1, v2);
    
  if( vec3_norm(&diff) < 1e-3 ){
    mat33_assign(R,1,0,0,0,1,0,0,0,1);
  }else
  {
		if( fabs((vec3_norm(&diff)-2)) < 1e-3 ){
		  mat33_assign(R,1,0,0 ,0,-1,0, 0,0,-1);
		}else
		  { 
			real_t winkel = _acos(vec3_dot(v1,v2));
			quat_t QU;
			vec3_t vc;
			vec3_cross(&vc,v2,v1);
			Quaternion_byAngleAndVector(&QU,winkel,&vc);
			mat33_from_quat(R,&QU);
		}
	}
}
Exemple #10
0
t_vec3		set_specular(t_obj *obj, t_cam *cam, t_lgt *light)
{
	t_vec3	halfdir;
	float	theta;
	float	res;

	halfdir = vec3_norm(vec3_sub(light->ray.dir, cam->ray.dir));
	theta = ft_clampf(vec3_dot(obj->mat.texture.normal, halfdir), 0, 1);
	res = pow(theta, obj->mat.shininess);
	res = res * obj->mat.specular * light->intensity / obj->dist_attenuation;
	light->type == SPOT ? res *= light->cutoff_intensity : 0;
	return (vec3_fmul(light->color, res));
}
Exemple #11
0
void plane_from_tri(struct plane *dst,
                    const struct vec3 *v1,
                    const struct vec3 *v2,
                    const struct vec3 *v3)
{
	struct vec3 temp;

	vec3_sub(&temp, v2, v1);
	vec3_sub(&dst->dir, v3, v1);
	vec3_cross(&dst->dir, &temp, &dst->dir);
	vec3_norm(&dst->dir, &dst->dir);
	dst->dist = vec3_dot(v1, &dst->dir);
}
Exemple #12
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);
}
Exemple #13
0
/**
 * @brief CM_PlaneFromPoints
 * @details The normal will point out of the clock for clockwise ordered points
 * @param[in,out] plane
 * @param[in] a
 * @param[in] b
 * @param[in] c
 * @return false if the triangle is degenrate.
 */
static qboolean CM_PlaneFromPoints(vec4_t plane, vec3_t a, vec3_t b, vec3_t c)
{
	vec3_t d1, d2;

	VectorSubtract(b, a, d1);
	VectorSubtract(c, a, d2);
	vec3_cross(d2, d1, plane);
	if (vec3_norm(plane) == 0.f)
	{
		return qfalse;
	}

	plane[3] = DotProduct(a, plane);
	return qtrue;
}
Exemple #14
0
vec3 *vec3_get_surface_normal(const vec3 *v1, const vec3 *v2, const vec3 *v3) {
	vec3 u, v;
	u.x = v2->x - v1->x;
	u.y = v2->y - v1->y;
	u.z = v2->z - v1->z;
	v.x = v3->x - v1->x;
	v.y = v3->y - v1->y;
	v.z = v3->z - v1->z;

	vec3 *normal = vec3_create(0, 0, 0);
	normal->x = u.x * v.x - u.z * v.z; 
	normal->y = u.z * v.x - u.x * v.z; 
	normal->z = u.x * v.y - u.y * v.x;
	vec3_norm(normal);
  	return normal;
}
Exemple #15
0
void cubeUpdate(CubeRenderPacket* cube, vec3 rot, float angle, float x, float y, float z, float* view, float* proj)
{
    static mat4x4 temp;
    memcpy(cube->transforms.view, view, 16 * sizeof(float));
    memcpy(cube->transforms.proj, proj, 16 * sizeof(float));

    vec3_norm(rot, rot);

    mat4x4_identity(cube->transforms.world);
    mat4x4_translate_in_place(cube->transforms.world, x, y, z);
    mat4x4_rotate(cube->transforms.world, cube->transforms.world, rot[0], rot[1], rot[2], angle);

    mat4x4_mul(temp, cube->transforms.view, cube->transforms.world);
    mat4x4_mul(cube->transforms.proj_view_world, cube->transforms.proj, temp);
    gfxBindUniformBuffer(cube->ubo, &cube->transforms, sizeof(struct Transforms), 0);
}
Exemple #16
0
void Camera_offset_orientation(Camera* const camera, float yaw, float pitch) {

    quat pitch_rotation, yaw_rotation;

    quat_rotate(yaw_rotation, yaw, G_UP);

    vec3 right;
    quat_mul_vec3(right, camera->transform.orientation, G_RIGHT);
    vec3_norm(right, right);
    quat_rotate(pitch_rotation, pitch, right);

    quat orientation;
    quat_mul(orientation, yaw_rotation, pitch_rotation);
    quat_mul(
        camera->transform.orientation,
        orientation,
        camera->transform.orientation
    );
    quat_norm(camera->transform.orientation, camera->transform.orientation);
}
Exemple #17
0
void point_calc_normal(Point *point, distance_func sdf)
{
  float eps = 0.1e-4;
  vec4 pos = {point->pos[0], point->pos[1], point->pos[2], 1.0};
  vec4 epsX = {eps, 0.f, 0.f, 0.0f};
  vec4 epsY = {0.f, eps, 0.f, 0.0f};
  vec4 epsZ = {0.f, 0.f, eps, 0.0f};

  vec4 ppx, psx, ppy, psy, ppz, psz;
  vec4_add(ppx, pos, epsX);
  vec4_add(ppy, pos, epsY);
  vec4_add(ppz, pos, epsZ);
  vec4_sub(psx, pos, epsX);
  vec4_sub(psy, pos, epsY);
  vec4_sub(psz, pos, epsZ);

  point->norm[0] = sdf(ppx) - sdf(psx);
  point->norm[1] = sdf(ppy) - sdf(psy);
  point->norm[2] = sdf(ppz) - sdf(psz);
  vec3_norm(point->norm, point->norm);
}
Exemple #18
0
int  SSBoneFrame_CheckTargetBoneLimit(struct ss_bone_frame_s *bf, struct ss_bone_tag_s *b_tag, float target[3])
{
    float target_dir[3], target_local[3], limit_dir[3], t;

    Mat4_vec3_mul_inv(target_local, bf->transform->M4x4, target);
    if(b_tag->parent)
    {
        Mat4_vec3_mul_inv(target_local, b_tag->parent->current_transform, target_local);
    }
    vec3_sub(target_dir, target_local, b_tag->local_transform + 12);
    vec3_norm(target_dir, t);
    vec3_copy(limit_dir, b_tag->mod.limit);

    if((b_tag->mod.limit[3] == -1.0f) ||
       (vec3_dot(limit_dir, target_dir) > b_tag->mod.limit[3]))
    {
        return 1;
    }

    return 0;
}
Exemple #19
0
int  SSBoneFrame_CheckTargetBoneLimit(struct ss_bone_frame_s *bf, struct ss_animation_s *ss_anim)
{
    ss_bone_tag_p b_tag = b_tag = bf->bone_tags + ss_anim->targeting_bone;
    float target_dir[3], target_local[3], limit_dir[3], t;

    Mat4_vec3_mul_inv(target_local, bf->transform, ss_anim->target);
    if(b_tag->parent)
    {
        Mat4_vec3_mul_inv(target_local, b_tag->parent->full_transform, target_local);
    }
    vec3_sub(target_dir, target_local, b_tag->transform + 12);
    vec3_norm(target_dir, t);
    vec3_copy(limit_dir, ss_anim->targeting_limit);

    if((ss_anim->targeting_limit[3] == -1.0f) ||
       (vec3_dot(limit_dir, target_dir) > ss_anim->targeting_limit[3]))
    {
        return 1;
    }

    return 0;
}
Exemple #20
0
t_vec3			bump_normal(t_obj *obj, t_ray *ray)
{
	t_vec3		normal;
	t_vec3		tangent;
	t_vec3		binormal;
	t_vec3		bump;
	t_vec3		c[2];

	normal = obj->normal;
	bump = texture_mapping(obj, obj->mat.texture.bump, ray->hit);
	bump = vec3_sub(vec3_fmul(bump, 2), vec3(1, 1, 1));
	c[0] = vec3_cross(normal, vec3(0, 0, 1));
	c[1] = vec3_cross(normal, vec3(0, 1, 0));
	tangent = (vec3_magnitude(c[0]) > vec3_magnitude(c[1]) ? c[0] : c[1]);
	tangent = vec3_sub(tangent, vec3_fmul(normal, vec3_dot(tangent, normal)));
	vec3_normalize(&tangent);
	binormal = vec3_norm(vec3_cross(normal, tangent));
	normal.x = vec3_dot(bump, vec3(tangent.x, binormal.x, normal.x));
	normal.y = vec3_dot(bump, vec3(tangent.y, binormal.y, normal.y));
	normal.z = vec3_dot(bump, vec3(tangent.z, binormal.z, normal.z));
	vec3_normalize(&normal);
	return (normal);
}
Exemple #21
0
static int predict_slide_move(sharedEntity_t *ent, float frametime, trajectory_t *tr, vec3_t result)
{
	int    count, numplanes = 0, i, j, k;
	float  d, time_left = frametime, into;
	vec3_t planes[MAX_CLIP_PLANES],
	       velocity, origin, clipVelocity, endVelocity, endClipVelocity, dir, end;
	trace_t trace;

	VectorCopy(tr->trBase, origin);
	origin[2] += Z_ADJUST;  // move it off the floor

	VectorCopy(tr->trDelta, velocity);
	VectorCopy(tr->trDelta, endVelocity);

	for (count = 0; count < NUMBUMPS; count++)
	{
		// calculate position we are trying to move to
		VectorMA(origin, time_left, velocity, end);

		// see if we can make it there
		SV_Trace(&trace, origin, ent->r.mins, ent->r.maxs, end, ent->s.number, CONTENTS_SOLID, qfalse);

		if (trace.allsolid)
		{
			// entity is completely trapped in another solid
			VectorCopy(origin, result);
			return 0;
		}

		if (trace.fraction > 0.99) // moved the entire distance
		{
			VectorCopy(trace.endpos, result);
			return 1;
		}

		if (trace.fraction > 0) // covered some distance
		{
			VectorCopy(trace.endpos, origin);
		}

		time_left -= time_left * trace.fraction;

		if (numplanes >= MAX_CLIP_PLANES)
		{
			// this shouldn't really happen
			VectorCopy(origin, result);
			return 0;
		}

		// if this is the same plane we hit before, nudge velocity
		// out along it, which fixes some epsilon issues with
		// non-axial planes
		for (i = 0; i < numplanes; i++)
		{
			if (DotProduct(trace.plane.normal, planes[i]) > 0.99)
			{
				VectorAdd(trace.plane.normal, velocity, velocity);
				break;
			}
		}

		if (i < numplanes)
		{
			continue;
		}

		VectorCopy(trace.plane.normal, planes[numplanes]);
		numplanes++;

		// modify velocity so it parallels all of the clip planes
		// find a plane that it enters
		for (i = 0; i < numplanes; i++)
		{
			into = DotProduct(velocity, planes[i]);
			if (into >= 0.1) // move doesn't interact with the plane
			{
				continue;
			}

			// slide along the plane
			predict_clip_velocity(velocity, planes[i], clipVelocity);

			// slide along the plane
			predict_clip_velocity(endVelocity, planes[i], endClipVelocity);

			// see if there is a second plane that the new move enters
			for (j = 0; j < numplanes; j++)
			{
				if (j == i)
				{
					continue;
				}

				if (DotProduct(clipVelocity, planes[j]) >= 0.1) // move doesn't interact with the plane
				{
					continue;
				}

				// try clipping the move to the plane
				predict_clip_velocity(clipVelocity, planes[j], clipVelocity);
				predict_clip_velocity(endClipVelocity, planes[j], endClipVelocity);

				// see if it goes back into the first clip plane
				if (DotProduct(clipVelocity, planes[i]) >= 0)
				{
					continue;
				}

				// slide the original velocity along the crease
				vec3_cross(planes[i], planes[j], dir);
				vec3_norm(dir);
				d = DotProduct(dir, velocity);
				VectorScale(dir, d, clipVelocity);

				vec3_cross(planes[i], planes[j], dir);
				vec3_norm(dir);
				d = DotProduct(dir, endVelocity);
				VectorScale(dir, d, endClipVelocity);

				// see if there is a third plane the new move enters
				for (k = 0; k < numplanes; k++)
				{
					if (k == i || k == j)
					{
						continue;
					}

					if (DotProduct(clipVelocity, planes[k]) >= 0.1) // move doesn't interact with the plane
					{
						continue;
					}

					// stop dead at a tripple plane interaction
					VectorCopy(origin, result);
					return 1;
				}
			}

			// if we have fixed all interactions, try another move
			VectorCopy(clipVelocity, velocity);
			VectorCopy(endClipVelocity, endVelocity);
			break;
		}
	}

	VectorCopy(origin, result);

	if (count == 0)
	{
		return 1;
	}

	return 0;
}
Exemple #22
0
void gfx_csm_prepare(const struct gfx_view_params* params, const struct vec3f* light_dir,
    const struct aabb* world_bounds)
{
    static const float tolerance = 10.0f;

    struct vec3f dir;
    vec3_setv(&dir, light_dir);

    float texoffset_x = 0.5f + (0.5f/g_csm->shadowmap_size);
    float texoffset_y = 0.5f + (0.5f/g_csm->shadowmap_size);

    struct mat3f view_inv;
    struct mat4f tex_mat;
    struct mat4f tmp_mat;
    float splits[CSM_CASCADE_CNT+1];

    mat3_setf(&view_inv,
        params->view.m11, params->view.m21, params->view.m31,
        params->view.m12, params->view.m22, params->view.m32,
        params->view.m13, params->view.m23, params->view.m33,
        params->cam_pos.x, params->cam_pos.y, params->cam_pos.z);
    mat4_setf(&tex_mat,
        0.5f, 0.0f, 0.0f, 0.0f,
        0.0f, -0.5f, 0.0f, 0.0f,
        0.0f, 0.0f, 1.0f, 0.0f,
        texoffset_x, texoffset_y, 0.0f, 1.0f);

    float csm_far = minf(CSM_FAR_MAX, params->cam->ffar);
    csm_split_range(params->cam->fnear, csm_far, splits);

    /* calculate cascades */
    struct frustum f;   /* frustum points for cascades */
    struct plane vp_planes[6];

    for (uint i = 0; i < CSM_CASCADE_CNT; i++)    {
        cam_calc_frustumcorners(params->cam, (struct vec3f*)f.points, &splits[i], &splits[i+1]);
        csm_calc_minsphere(&g_csm->cascades[i].bounds, &f, &params->view, &view_inv);
        memcpy(&g_csm->cascade_frusts[i], &f, sizeof(f));

        /* cascade matrixes: first we find two extreme points of the world, related to cascade */
        struct vec3f scenter;
        struct ray r;
        struct plane upper_plane;
        struct plane lower_plane;
        struct vec3f upper_pt;
        struct vec3f lower_pt;
        struct vec3f xaxis;
        struct vec3f yaxis;
        struct vec3f viewpos;
        struct vec3f tmp;
        struct vec3f lowerpt_vs;

        float sr = g_csm->cascades[i].bounds.r;
        vec3_setf(&scenter, g_csm->cascades[i].bounds.x, g_csm->cascades[i].bounds.y,
            g_csm->cascades[i].bounds.z);
        ray_setv(&r, &scenter, &dir);
        plane_setv(&upper_plane, &g_vec3_unity_neg, fabs(world_bounds->maxpt.y));
        plane_setv(&lower_plane, &g_vec3_unity, fabs(world_bounds->minpt.y));
        vec3_sub(&upper_pt, &r.pt,
            vec3_muls(&tmp, &dir, fabs(ray_intersect_plane(&r, &upper_plane)) + tolerance));
        vec3_add(&lower_pt, &r.pt,
            vec3_muls(&tmp, &dir, fabs(ray_intersect_plane(&r, &lower_plane)) + tolerance));

        /* view matrix of light view for the cascade :
         * dir = light_dir
         * up = (1, 0, 0)
         * pos = sphere center
         */
        vec3_norm(&xaxis, vec3_cross(&tmp, &g_vec3_unitx, &dir));
        vec3_cross(&yaxis, &dir, &xaxis);
        vec3_sub(&viewpos, &upper_pt, vec3_muls(&tmp, &dir, tolerance));
        mat3_setf(&g_csm->cascades[i].view,
            xaxis.x, yaxis.x, dir.x,
            xaxis.y, yaxis.y, dir.y,
            xaxis.z, yaxis.z, dir.z,
            -vec3_dot(&xaxis, &viewpos), -vec3_dot(&yaxis, &viewpos), -vec3_dot(&dir, &viewpos));

        /* orthographic projection matrix for cascade */
        vec3_transformsrt(&lowerpt_vs, &lower_pt, &g_csm->cascades[i].view);
        float nnear = tolerance*0.5f;
        float nfar = lowerpt_vs.z + sr;
        csm_calc_orthoproj(&g_csm->cascades[i].proj,
            sr*2.0f + 1.0f/g_csm->shadowmap_size,
            sr*2.0f + 1.0f/g_csm->shadowmap_size,
            nnear, nfar);
        g_csm->cascades[i].nnear = nnear;
        g_csm->cascades[i].nfar = nfar;

        /* calculate final matrix */
        mat3_mul4(&g_csm->cascade_vps[i], &g_csm->cascades[i].view, &g_csm->cascades[i].proj);

        cam_calc_frustumplanes(vp_planes, &g_csm->cascade_vps[i]);
        csm_calc_cascadeplanes(&g_csm->cascade_planes[i*4], vp_planes, &g_csm->cascade_vps[i]);

        csm_round_mat(&g_csm->cascade_vps[i], &g_csm->cascade_vps[i], g_csm->shadowmap_size);

        mat4_mul(&g_csm->shadow_mats[i],
            mat3_mul4(&tmp_mat, &view_inv, &g_csm->cascade_vps[i]), &tex_mat);
    }

    /* caculate shadow area bounds (aabb) */
    struct aabb cascade_near;
    struct aabb cascade_far;
    aabb_setzero(&g_csm->frustum_bounds);

    aabb_from_sphere(&cascade_near, &g_csm->cascades[0].bounds);
    aabb_from_sphere(&cascade_far, &g_csm->cascades[CSM_CASCADE_CNT-1].bounds);
    aabb_merge(&g_csm->frustum_bounds, &cascade_near, &cascade_far);

    vec3_setv(&g_csm->light_dir, &dir);
}
Exemple #23
0
/**
 * @brief CM_AddFacetBevels
 * @param[in,out] facet
 */
void CM_AddFacetBevels(facet_t *facet)
{
	int       i, j, k, l;
	int       axis, dir, flipped;
	float     plane[4], d, minBack, newplane[4];
	winding_t *w, *w2;
	vec3_t    mins, maxs, vec, vec2;

#ifndef ADDBEVELS
	return;
#endif

	Vector4Copy(planes[facet->surfacePlane].plane, plane);

	w = BaseWindingForPlane(plane, plane[3]);
	for (j = 0 ; j < facet->numBorders && w ; j++)
	{
		if (facet->borderPlanes[j] == facet->surfacePlane)
		{
			continue;
		}
		Vector4Copy(planes[facet->borderPlanes[j]].plane, plane);

		if (!facet->borderInward[j])
		{
			VectorSubtract(vec3_origin, plane, plane);
			plane[3] = -plane[3];
		}

		ChopWindingInPlace(&w, plane, plane[3], 0.1f);
	}
	if (!w)
	{
		return;
	}

	WindingBounds(w, mins, maxs);

	// add the axial planes
	for (axis = 0; axis < 3; axis++)
	{
		for (dir = -1; dir <= 1; dir += 2)
		{
			VectorClear(plane);
			plane[axis] = dir;
			if (dir == 1)
			{
				plane[3] = maxs[axis];
			}
			else
			{
				plane[3] = -mins[axis];
			}
			// if it's the surface plane
			if (CM_PlaneEqual(&planes[facet->surfacePlane], plane, &flipped))
			{
				continue;
			}
			// see if the plane is already present
			for (i = 0; i < facet->numBorders; i++)
			{
				if (CM_PlaneEqual(&planes[facet->borderPlanes[i]], plane, &flipped))
				{
					break;
				}
			}

			if (i == facet->numBorders)
			{
				if (facet->numBorders >= 4 + 6 + 16)
				{
					Com_Printf("CM_AddFacetBevels: ERROR - too many bevels\n");
					continue;
				}
				facet->borderPlanes[facet->numBorders]   = CM_FindPlane2(plane, &flipped);
				facet->borderNoAdjust[facet->numBorders] = 0;
				facet->borderInward[facet->numBorders]   = flipped;
				facet->numBorders++;
			}
		}
	}

	// add the edge bevels
	// test the non-axial plane edges
	for (j = 0; j < w->numpoints; j++)
	{
		k = (j + 1) % w->numpoints;
		VectorSubtract(w->p[j], w->p[k], vec);
		// if it's a degenerate edge
		if (vec3_norm(vec) < 0.5f)
		{
			continue;
		}
		CM_SnapVector(vec);
		for (k = 0; k < 3; k++)
		{
			if (vec[k] == -1.0f || vec[k] == 1.0f || (vec[k] == 0.0f && vec[(k + 1) % 3] == 0.0f))
			{
				break;  // axial
			}
		}
		if (k < 3)
		{
			continue;   // only test non-axial edges
		}

		// try the six possible slanted axials from this edge
		for (axis = 0 ; axis < 3 ; axis++)
		{
			for (dir = -1 ; dir <= 1 ; dir += 2)
			{
				// construct a plane
				VectorClear(vec2);
				vec2[axis] = dir;
				vec3_cross(vec, vec2, plane);
				if (vec3_norm(plane) < 0.5f)
				{
					continue;
				}
				plane[3] = DotProduct(w->p[j], plane);

				// if all the points of the facet winding are
				// behind this plane, it is a proper edge bevel
				minBack = 0.0f;
				for (l = 0; l < w->numpoints; l++)
				{
					d = DotProduct(w->p[l], plane) - plane[3];
					if (d > 0.1f)
					{
						break;  // point in front
					}
					if (d < minBack)
					{
						minBack = d;
					}
				}
				// if some point was at the front
				if (l < w->numpoints)
				{
					continue;
				}

				// if no points at the back then the winding is on the bevel plane
				if (minBack > -0.1f)
				{
					break;
				}

				// if it's the surface plane
				if (CM_PlaneEqual(&planes[facet->surfacePlane], plane, &flipped))
				{
					continue;
				}
				// see if the plane is already present
				for (i = 0; i < facet->numBorders; i++)
				{
					if (CM_PlaneEqual(&planes[facet->borderPlanes[i]], plane, &flipped))
					{
						break;
					}
				}

				if (i == facet->numBorders)
				{
					if (facet->numBorders >= 4 + 6 + 16)
					{
						Com_Printf("CM_AddFacetBevels: ERROR - too many bevels\n");
						continue;
					}
					facet->borderPlanes[facet->numBorders] = CM_FindPlane2(plane, &flipped);

					for (k = 0; k < facet->numBorders; k++)
					{
						if (facet->borderPlanes[facet->numBorders] == facet->borderPlanes[k])
						{
							Com_Printf("CM_AddFacetBevels: WARNING - bevel plane already used\n");
						}
					}

					facet->borderNoAdjust[facet->numBorders] = 0;
					facet->borderInward[facet->numBorders]   = flipped;
					//
					w2 = CopyWinding(w);
					Vector4Copy(planes[facet->borderPlanes[facet->numBorders]].plane, newplane);
					if (!facet->borderInward[facet->numBorders])
					{
						VectorNegate(newplane, newplane);
						newplane[3] = -newplane[3];
					}
					ChopWindingInPlace(&w2, newplane, newplane[3], 0.1f);
					if (!w2)
					{
						// any map load spams with this error .. don't print it anymore
						//Com_DPrintf("WARNING: CM_AddFacetBevels... invalid bevel\n");
						continue;
					}
					else
					{
						FreeWinding(w2);
					}

					facet->numBorders++;
					// already got a bevel
					//break;
				}
			}
		}
	}
	FreeWinding(w);

	// add opposite plane
	if (facet->numBorders >= 4 + 6 + 16)
	{
		Com_Printf("CM_AddFacetBevels: ERROR - too many bevels at end\n");
		return;
	}

	facet->borderPlanes[facet->numBorders]   = facet->surfacePlane;
	facet->borderNoAdjust[facet->numBorders] = 0;
	facet->borderInward[facet->numBorders]   = qtrue;
	facet->numBorders++;
}
Exemple #24
0
void render_screen_area(void *args) {
  ray3 ray;
  float t = 0;

  screen_area *c = (screen_area *)args;
  int width = c->width;
  int height = c->height;
  int stride = c->stride;
  vec3 planeXPosition;

  vec3 dcol, drow, ro, rd, normal, o;
  dcol = c->dcol;
  drow = c->drow;
  ro = c->ro;
  uint8_t *data = c->data;
  ray_packet3 packet;
  packet.origin[0] = vec3f(ro[0]);
  packet.origin[1] = vec3f(ro[1]);
  packet.origin[2] = vec3f(ro[2]);
  vec3 planeYPosition = dcol * vec3f(c->y) + c->pos;
  vec3 invdir[4], dir[4];
  vec3 m;
  float r = VOXEL_BRICK_HALF_SIZE * 0.99f;
  int result;
  int x, y;

  aabb_packet bounds;
  bounds[0] = _mm_sub_ps(c->brick->bounds_packet[0], vec3f(ro[0]));
  bounds[1] = _mm_sub_ps(c->brick->bounds_packet[1], vec3f(ro[1]));
  bounds[2] = _mm_sub_ps(c->brick->bounds_packet[2], vec3f(ro[2]));
  bounds[3] = _mm_sub_ps(c->brick->bounds_packet[3], vec3f(ro[0]));
  bounds[4] = _mm_sub_ps(c->brick->bounds_packet[4], vec3f(ro[1]));
  bounds[5] = _mm_sub_ps(c->brick->bounds_packet[5], vec3f(ro[2]));

  for (y=c->y; y<height; ++y) {
    planeXPosition = planeYPosition;
    for (x=0; x<width; x+=4) {
      for (int i=0; i<4; i++) {
        planeXPosition += drow;
        rd = planeXPosition - ro;
        dir[i] = rd;
        invdir[i] = vec3_reciprocal(rd);
        packet.invdir[0][i] = invdir[i][0];
        packet.invdir[1][i] = invdir[i][1];
        packet.invdir[2][i] = invdir[i][2];
      }

      result = ray_isect_packet(packet, bounds, &m);
      for (int j=0; j<4; j++) {
        unsigned long where = y * width * stride + (x + j) * stride;

        int cr = floor(((x+j)/(float)width) * 255);
        int cg = floor((y/(float)c->screen_height) * 255);
        int cb = 0;

        if (result & (1<<j)) {
          vec3 isect = ro + dir[j] * vec3f(m[j]);
          o = isect - c->brick->center;

          for (int k=0; k<3; k++) {
            if (fabsf(o[k]) >= r) {
              normal[k] = o[k] > 0.0f ? 1.0f : -1.0f;
            } else {
              normal[k] = 0.0f;
            }
          }

          float sum = fabsf(normal[0]) + fabsf(normal[1]) + fabsf(normal[2]);

          int voxel_pos[3] = { 0, 0, 0 };
          int found = voxel_brick_traverse(
            c->brick,
            isect,
            vec3_norm(dir[j]),
            1.0f,
            voxel_pos
          );

          if (found) {
            cr = (int)((voxel_pos[0] / (float)VOXEL_BRICK_WIDTH) * 255.0f);
            cg = (int)((voxel_pos[1] / (float)VOXEL_BRICK_WIDTH) * 255.0f);
            cb = (int)((voxel_pos[2] / (float)VOXEL_BRICK_WIDTH) * 255.0f);
          } else {
            cr = fmaxf(0, cr - 20);
            cg = fmaxf(0, cg - 20);
            cb = fmaxf(0, cb - 20);
          }

          if (sum >= 2) {
            cr = fmaxf(0, cr - 20);
            cg = fmaxf(0, cg - 20);
            cb = fmaxf(0, cb - 20);
          }
        }
        data[where+0] = cr;
        data[where+1] = cg;
        data[where+2] = cb;
      }
    }
    planeYPosition += dcol;
  }
}
Exemple #25
0
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;
}
Exemple #26
0
void Vector::normalize()
{
    vec3_norm(&v_, &v_);
}
Exemple #27
0
void vec3_normalize(Vec3* v) {
    float norm = vec3_norm(v);
    v->x /= norm;
    v->y /= norm;
    v->z /= norm;
}
Exemple #28
0
/*
 * animated textures coordinates splits too!
 */
void Polygon_Split(polygon_p src, float n[4], polygon_p front, polygon_p back)
{
    float t, tmp, dir[3];
    vertex_t *curr_v, *prev_v, tv;
    float dist[2];

    vec4_copy(front->plane, src->plane);
    front->anim_id = src->anim_id;
    front->frame_offset = src->frame_offset;
    front->double_side = src->double_side;
    front->texture_index = src->texture_index;
    front->transparency = src->transparency;

    vec4_copy(back->plane, src->plane);
    back->anim_id = src->anim_id;
    back->frame_offset = src->frame_offset;
    back->double_side = src->double_side;
    back->texture_index = src->texture_index;
    back->transparency = src->transparency;

    curr_v = src->vertices;
    prev_v = src->vertices + src->vertex_count - 1;
    
    dist[0] = vec3_plane_dist(n, prev_v->position);
    for(uint16_t i = 0; i < src->vertex_count; i++)
    {
        dist[1] = vec3_plane_dist(n, curr_v->position);

        if(dist[1] > SPLIT_EPSILON)
        {
            if(dist[0] < -SPLIT_EPSILON)
            {
                vec3_sub(dir, curr_v->position, prev_v->position);
                vec3_ray_plane_intersect(prev_v->position, dir, n, tv.position, t);

                tv.normal[0] = prev_v->normal[0] + t * (curr_v->normal[0] - prev_v->normal[0]);
                tv.normal[1] = prev_v->normal[1] + t * (curr_v->normal[1] - prev_v->normal[1]);
                tv.normal[2] = prev_v->normal[2] + t * (curr_v->normal[2] - prev_v->normal[2]);
                vec3_norm(tv.normal, tmp);

                tv.color[0] = prev_v->color[0] + t * (curr_v->color[0] - prev_v->color[0]);
                tv.color[1] = prev_v->color[1] + t * (curr_v->color[1] - prev_v->color[1]);
                tv.color[2] = prev_v->color[2] + t * (curr_v->color[2] - prev_v->color[2]);
                tv.color[3] = prev_v->color[3] + t * (curr_v->color[3] - prev_v->color[3]);

                tv.tex_coord[0] = prev_v->tex_coord[0] + t * (curr_v->tex_coord[0] - prev_v->tex_coord[0]);
                tv.tex_coord[1] = prev_v->tex_coord[1] + t * (curr_v->tex_coord[1] - prev_v->tex_coord[1]);

                front->vertices[front->vertex_count++] = tv;
                back->vertices[back->vertex_count++] = tv;
            }
            front->vertices[front->vertex_count++] = *curr_v;
        }
        else if(dist[1] < -SPLIT_EPSILON)
        {
            if(dist[0] > SPLIT_EPSILON)
            {
                vec3_sub(dir, curr_v->position, prev_v->position);
                vec3_ray_plane_intersect(prev_v->position, dir, n, tv.position, t);

                tv.normal[0] = prev_v->normal[0] + t * (curr_v->normal[0] - prev_v->normal[0]);
                tv.normal[1] = prev_v->normal[1] + t * (curr_v->normal[1] - prev_v->normal[1]);
                tv.normal[2] = prev_v->normal[2] + t * (curr_v->normal[2] - prev_v->normal[2]);
                vec3_norm(tv.normal, tmp);

                tv.color[0] = prev_v->color[0] + t * (curr_v->color[0] - prev_v->color[0]);
                tv.color[1] = prev_v->color[1] + t * (curr_v->color[1] - prev_v->color[1]);
                tv.color[2] = prev_v->color[2] + t * (curr_v->color[2] - prev_v->color[2]);
                tv.color[3] = prev_v->color[3] + t * (curr_v->color[3] - prev_v->color[3]);

                tv.tex_coord[0] = prev_v->tex_coord[0] + t * (curr_v->tex_coord[0] - prev_v->tex_coord[0]);
                tv.tex_coord[1] = prev_v->tex_coord[1] + t * (curr_v->tex_coord[1] - prev_v->tex_coord[1]);

                front->vertices[front->vertex_count++] = tv;
                back->vertices[back->vertex_count++] = tv;
            }
            back->vertices[back->vertex_count++] = *curr_v;
        }
        else
        {
            front->vertices[front->vertex_count++] = *curr_v;
            back->vertices[back->vertex_count++] = *curr_v;
        }

        prev_v = curr_v;
        curr_v ++;
        dist[0] = dist[1];
    }
}