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 #2
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);
}
Example #3
0
void position_rotateOnMouseInput (Entity e, const struct input_event * ie)
{
	POSITION
		pdata = NULL;
	QUAT
		q;
	float
		mag,
		newPitch;
	int
		sq,
		xrel,
		yrel;
	if (ie->event->type != SDL_MOUSEMOTION)
		return;
	pdata = component_getData (entity_getAs (e, "position"));
	if (pdata == NULL)
		return;
	xrel = ie->event->motion.xrel;
	yrel = ie->event->motion.yrel;
	sq = xrel * xrel + yrel * yrel;
	if (sq > 2500)
	{
		mag = 50.0 / sqrt (sq);
		xrel *= mag;
		yrel *= mag;
		return;
	}
	// we manually recalculate the one orientation axis value (front y component) we care about right here, instead of updating every single one
	newPitch =
		(pdata->orientation.y * pdata->orientation.z +
		pdata->orientation.w * pdata->orientation.x) * 180.0;
	newPitch += yrel * pdata->sensitivity;
	//printf ("front: %7.3f, %7.3f, %7.3f\n", pdata->view.front.x, pdata->view.front.y, pdata->view.front.z);
	//printf ("pitch: %7.3f\n", newPitch);
	if (newPitch < 90.0 && newPitch > -90.0)
	{
		// pitch relative to the object's axes
		q = quat_eulerToQuat (
			yrel * pdata->sensitivity,
			0,
			0
		);
		pdata->orientation = quat_multiply (&q, &pdata->orientation);
	}
	// (roll would also be relative to the world axis, if it's ever added)
	// heading relative to the world's axes
	q = quat_eulerToQuat (
		0,
		xrel * pdata->sensitivity,
		0
	);
	pdata->orientation = quat_multiply (&pdata->orientation, &q);
	pdata->dirty = true;
	entity_speak (e, "orientationUpdate", NULL);
	//printf ("view quat: %7.2f, %7.2f, %7.2f, %7.2f\n", cdata->viewQuat.w, cdata->viewQuat.x, cdata->viewQuat.y, cdata->viewQuat.z);
}
Example #4
0
void position_face (Entity e, const VECTOR3 * face)
{
	POSITION
		pos = component_getData (entity_getAs (e, "position"));
	float
		faceRot = atan2 (face->z, face->x),
		currentRot = position_getHeading (e),
		faceAngle;
	QUAT
		q;
	if (!pos)
		return;
	faceAngle = (faceRot - currentRot);
	faceAngle = faceAngle * (180.0 / M_PI);
	//printf ("face angle used: %f\n", faceAngle);
	q = quat_eulerToQuat (0, faceAngle, 0);
	//printf ("rotation: (%f; %f) %.2f, %.2f, %.2f, %.2f\n", faceRot, currentRot, q.x, q.y, q.z, q.w);
	pos->orientation = quat_multiply (&pos->orientation, &q);
	pos->dirty = true;
	entity_speak (e, "orientationUpdate", NULL);
}
Example #5
0
void jedi_processInput_RotationSpeed(double speed[3], uint32_t gyro_time) {
  // if (!global_quat)
  //   jedi_initQuat();
  if (fabs(speed[0]) > GYRO_THRESHOLD)
    speed[0] *= 0.07 * gyro_time / 10000.0;
  else
    speed[0] = 0.0;
  if (fabs(speed[1]) > GYRO_THRESHOLD)
    speed[1] *= 0.07 * gyro_time / 10000.0;
  else
    speed[1] = 0.0;
  if (fabs(speed[2]) > GYRO_THRESHOLD)
    speed[2] *= 0.07 * gyro_time / 10000.0;
  else
    speed[2] = 0.0;
  quat *local = quat_fromAngles(speed);
  global_quat = *quat_normalize(quat_multiply(&global_quat, local));
  free(local);
  // fprintf(stderr, "global_quat %3.2f %3.2f %3.2f %3.2f\n", global_quat.W,
  //         global_quat.X, global_quat.Y, global_quat.Z);
}