Esempio n. 1
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);
}
Esempio n. 2
0
File: model.c Progetto: ccxvii/mio
struct model *load_model(const char *name)
{
	char filename[1024];
	unsigned char *data = NULL;
	struct model *model;
	int i, len;

	model = lookup(model_cache, name);
	if (model)
		return model;

	for (i = 0; i < nelem(formats); i++) {
		strlcpy(filename, name, sizeof filename);
		strlcat(filename, formats[i].suffix, sizeof filename);
		data = load_file(filename, &len);
		if (data)
			break;
	}

	if (!data) {
		warn("error: cannot find model: '%s'", name);
		return NULL;
	}

	model = formats[i].load(filename, data, len);
	if (!model)
		warn("error: cannot load model: '%s'", filename);

	free(data);

	if (model)
		model_cache = insert(model_cache, name, model);

	if (model && model->anim) {
		struct anim *anim = model->anim;
		struct pose a_from_org, b_from_org;
		vec4 org_from_a;
		extract_frame_root(&a_from_org, anim, 0);
		extract_frame_root(&b_from_org, anim, anim->frames - 1);
		vec_sub(anim->motion.position, b_from_org.position, a_from_org.position);
		quat_conjugate(org_from_a, a_from_org.rotation);
		quat_mul(anim->motion.rotation, b_from_org.rotation, org_from_a);
		vec_div(anim->motion.scale, b_from_org.scale, a_from_org.scale);
	}

	return model;
}
Esempio n. 3
0
/*
rotate
Internally used helper for CCameraObject::RotateByMouse
*/
static void rotate(float* camPos, float* lookAtPos, float* upVec, float xDir)
{
	quat qRot, qView, qNewView;
	quat_rotate(qRot, deg_2_rad(xDir), upVec);

	qView[0] = lookAtPos[0] - camPos[0];
	qView[1] = lookAtPos[1] - camPos[1];
	qView[2] = lookAtPos[2] - camPos[2];
	qView[3] = 0.0f;

	quat_mul(qRot, qView, qNewView);
	quat_conjugate(qRot);
	quat_mul(qNewView, qRot, qNewView);

	lookAtPos[0] = camPos[0] + qNewView[0];
	lookAtPos[1] = camPos[1] + qNewView[1];
	lookAtPos[2] = camPos[2] + qNewView[2];
}
Esempio n. 4
0
void quat_invert(const Quat q, Quat r) {
    Quat conj = {0};
    quat_conjugate(q, conj);

    /* r[0] = conj[0] * (1 / qdot( q, conj ) ); */
    /* r[1] = conj[1] * (1 / qdot( q, conj ) ); */
    /* r[2] = conj[2] * (1 / qdot( q, conj ) ); */
    /* r[3] = conj[3] * (1 / qdot( q, conj ) ); */

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wconversion"
#pragma warning(push)
#pragma warning(disable : 4244)
    r[0] = conj[0] / pow(qmagnitude(q), 2.0);
    r[1] = conj[1] / pow(qmagnitude(q), 2.0);
    r[2] = conj[2] / pow(qmagnitude(q), 2.0);
    r[3] = conj[3] / pow(qmagnitude(q), 2.0);
#pragma warning(pop)
#pragma GCC diagnostic pop
}
Esempio n. 5
0
/* quat_inverse:
 *  A quaternion inverse is the conjugate divided by the normal.
 */
static INLINE void quat_inverse(AL_CONST QUAT *q, QUAT *out)
{
   QUAT  con;
   float norm;
   ASSERT(q);
   ASSERT(out);

   /* q^-1 = q^* / N(q) */

   quat_conjugate(q, &con);
   norm = quat_normal(q);

   /* NOTE: If the normal is 0 then a divide-by-zero exception will occur, we
    *       let this happen because the inverse of a zero quaternion is
    *       undefined
    */
   ASSERT(norm != 0);

   out->w = con.w / norm;
   out->x = con.x / norm;
   out->y = con.y / norm;
   out->z = con.z / norm;
}
Esempio n. 6
0
/* Apply incremental yaw, pitch and roll relative to the quaternion.
 * For example, if the quaternion represents an orientation of a ship,
 * this will apply yaw/pitch/roll *in the ship's local coord system to the
 * orientation.
 */
union quat *quat_apply_relative_yaw_pitch_roll(union quat *q,
					double yaw, double pitch, double roll)
{
	union quat qyaw, qpitch, qroll, qrot, tempq, local_rotation, rotated_q;

	/* calculate amount of yaw to impart this iteration... */
	quat_init_axis(&qyaw, 0.0, 1.0, 0.0, yaw);
	/* Calculate amount of pitch to impart this iteration... */
	quat_init_axis(&qpitch, 0.0, 0.0, 1.0, pitch);
	/* Calculate amount of roll to impart this iteration... */
	quat_init_axis(&qroll, 1.0, 0.0, 0.0, roll);
	/* Combine pitch, roll and yaw */
	quat_mul(&tempq, &qyaw, &qpitch);
	quat_mul(&qrot, &tempq, &qroll);

	/* Convert rotation to local coordinate system */
	quat_conjugate(&local_rotation, &qrot, q);
	/* Apply to local orientation */
	quat_mul(&rotated_q, &local_rotation, q);
	quat_normalize_self(&rotated_q);
	*q = rotated_q;
	return q;
}
Esempio n. 7
0
/* Renders the frame and calls calcFps() */
static void render(RenderConf *rc)
{
	double ws = world.worldSize;
	RenderMat3 m3;
	double m4[16];

	calcFps();

	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	/* 3D */
	renderSet3D();

	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	mat3_from_quat(m3, quat_conjugate(cam_orientation));
	mat4_from_mat3(m4, m3);
	glMultMatrixd(m4);
	glTranslatef(-cam_position.x, -cam_position.y, -cam_position.z);

	if (autorotate)
		camOrbit(5, 0);

	if (renderSPGridBoxes)
		renderBoxes(rc->numBoxes);

	if (renderWorldLoops) {
		/* Line loops for world box */
		glColor3f(0.0, 1.0, 0.0);
		glBegin(GL_LINE_LOOP);
			glVertex3f(-ws/2, -ws/2, -ws/2);
			glVertex3f(-ws/2, -ws/2, +ws/2);
			glVertex3f(-ws/2, +ws/2, +ws/2);
			glVertex3f(-ws/2, +ws/2, -ws/2);
		glEnd();

		glBegin(GL_LINE_LOOP);
			glVertex3f(+ws/2, -ws/2, -ws/2);
			glVertex3f(+ws/2, -ws/2, +ws/2);
			glVertex3f(+ws/2, +ws/2, +ws/2);
			glVertex3f(+ws/2, +ws/2, -ws/2);
		glEnd();
	}


	/* Strands */
	for (int s = 0; s < world.numStrands; s++)
		renderStrand(&world.strands[s], rc);


	/* Text */
	renderSet2D();
	const int n = 64;
	char string[n];

	snprintf(string, n, "T = %lf K", getKineticTemperature());
	renderString(string, 10, 40);

	snprintf(string, n, "t = %lf µs   (dt = %lf fs)",
			getTime() / MICROSECONDS, getIntegratorTimeStep() / FEMTOSECONDS);
	renderString(string, 10, 25);

	int ips;
	double tps;
	getProgressPerSecond(&ips, &tps);
	snprintf(string, n, "ips = %d   (time/min = %lf ns)",
			ips, tps / NANOSECONDS * 60);
	renderString(string, 10, 10);

	glLoadIdentity();
	renderString(fps_string, 10, SCREEN_H - 10);


	StringList *node = strings;
	while (node != NULL) {
		renderString(node->rsc.string, node->rsc.x, node->rsc.y);
		node = node->next;
	}

	SDL_GL_SwapBuffers();

}
Esempio n. 8
0
vec quat_rotate_vec(avec v, aquat q)
{
    // ASSUME v3 == 0
    return quat_quat_mul(quat_quat_mul(q, v), quat_conjugate(q));
}
Esempio n. 9
0
vec3 quat_transform(quat q, vec3 v) {
    quat qv = (quat) { v.x, v.y, v.z, 0.0 };
    qv = quat_mult(q, quat_mult(qv, quat_conjugate(q)));
    return (vec3) { q.x, q.y, q.z };
}