Esempio n. 1
0
static void lookAtOrigin()
{
	// Set angle to look at the origin
	Cvec3 eye = g_eyeRbt.getTranslation();
	Cvec3 up = Cvec3(0,1,0);
	g_eyeRbt.setRotation(Quat().makeXRotation(lookAt(eye,up)));
}
static void motion(const int x, const int y) {
	const double dx = x - g_mouseClickX;
	const double dy = g_windowHeight - y - 1 - g_mouseClickY;

	//Matrix4 m;
  RigTForm m;
	if (g_mouseLClickButton && !g_mouseRClickButton) { // left button down?
		//m = Matrix4::makeXRotation(-dy) * Matrix4::makeYRotation(dx);
    m = m.setRotation( Quat::makeXRotation(-dy) * Quat::makeYRotation(dx) );
    
	}
	else if (g_mouseRClickButton && !g_mouseLClickButton) { // right button down?
		//m = Matrix4::makeTranslation(Cvec3(dx, dy, 0) * 0.01);
    m = m.setTranslation(Cvec3(dx, dy, 0) * 0.01);
	}
	else if (g_mouseMClickButton || (g_mouseLClickButton && g_mouseRClickButton)) {  // middle or (left and right) button down?
		//m = Matrix4::makeTranslation(Cvec3(0, 0, -dy) * 0.01);
    m = m.setTranslation(Cvec3(0, 0, -dy) * 0.01);
	}

	if (g_mouseClickDown) {

    //noInterfaceRotation(m);
    arcBallRotation(m);

		glutPostRedisplay(); // we always redraw if we changed the scene
	}

	g_mouseClickX = x;
	g_mouseClickY = g_windowHeight - y - 1;
}
Esempio n. 3
0
/*-----------------------------------------------*/
static void initCamera()
{
	Cvec3 eye = Cvec3(0.0, 3.0, 10.0);
	Cvec3 at = Cvec3(0.0, 0.0, 0.0);
	Cvec3 up = Cvec3(0.0,1.0,0.0);
	//g_skyRbt = lookAt(eye, at, up); // Default camera
	g_skyRbt.setRotation(Quat().makeXRotation(lookAt(eye,up)));
	g_eyeRbt = g_skyRbt;
}
Esempio n. 4
0
static void readFrameDataFromFile() {
	ifstream myfile; 
	string line; 
	myfile.open("animation.txt");
	getline(myfile, line);
	int num_frames = atoi(line.c_str());
	getline(myfile, line);
	int num_nodes = atoi(line.c_str());
	printf("%d %d\n", num_frames, num_nodes);
	
	keyframeList.clear();
	for (int i = 0; i < num_frames; i++) {
		RigTFormVector frame; 
		for (int j = 0; j < num_nodes; j++) {
			RigTForm node; 
			Cvec3 translation;
			Quat rotation;
			std::string line;
			std::getline(myfile, line);
			std::stringstream stream(line);
			for (int k = 0; k < 3; k++) {
				double cvec_double;
				stream >> cvec_double;
				translation[k] = cvec_double;
			}
			for (int l = 0; l < 4; l++) {
				double quat_double;
				stream >> quat_double;
				rotation[l] = quat_double;
			}
			printf("\n");
			node.setTranslation(translation); 
			node.setRotation(rotation);
			frame.push_back(node);
		}
		keyframeList.push_back(frame);
	}
	g_currentKeyframe = keyframeList.begin();

	copyCurrentKeyframe();

	myfile.close();
}
Esempio n. 5
0
static void motion(const int x, const int y) {
  const double dx = x - g_mouseClickX;
  const double dy = g_windowHeight - y - 1 - g_mouseClickY;
  
  //initialize the outCenter and outRadius for the screenSpaceCircle 
  Cvec2 outCenter;
  double outRadius;
  
  //initialize the projection matrix for the screenSpaceCircle
  const Matrix4 projmat = Matrix4::makeProjection(
  g_frustFovY, g_windowWidth / static_cast <double> (g_windowHeight),
  g_frustNear, g_frustFar);
 
  if(currentView == 0)
	  eyeRbt = g_skyRbt;
  else if (currentView == 1)
	  eyeRbt = g_objectRbt[0];
  else
	  eyeRbt = g_objectRbt[1];
  
  //gets the center for the screenSpaceCircle by passing in the center of the sphere in eye-coordinates
  Cvec3 center = (inv(eyeRbt) * g_objectRbt[2]).getTranslation();

  //getsthe screenSpaceCircle
  getScreenSpaceCircle(center, 1, projmat, g_frustNear, g_frustFovY, g_windowWidth, g_windowHeight, outCenter, outRadius);
  
  //get the two screen space vectors
  Cvec2 p1((g_mouseClickX+dx)-outCenter(0), (dy + g_mouseClickY)-outCenter(1));
  Cvec2 p2(g_mouseClickX-outCenter(0), g_mouseClickY-outCenter(1));

  //clamp if we go outside the radius of the sphere
  double dist1 = sqrt(pow(p1(0),2) + pow(p1(1),2));
  if(dist1 > outRadius){
	  p1 = p1 * outRadius/(dist1+10);  //+10 to avoid random rounding errors and stuff
  }

  double dist2 = sqrt(pow(p2(0),2) + pow(p2(1),2));
  if (dist2 > outRadius){
	  p2 = p2 * outRadius/(dist2+10);
  }
  
  //Z-components for the projection
  double currentZ = sqrt(pow(outRadius,2) - pow(p1(0),2) - pow(p1(1),2));
  double transZ = sqrt(pow(outRadius,2) - pow(p2(0),2) - pow(p2(1),2));

  //create two vectors for each mouse click with the tails at the origin of the sphere
  Cvec3 currentV(p1, currentZ);
  Cvec3 transV(p2, transZ);

  //create two quaternions with normalized vectors
  Quat qV1(0, normalize(currentV));
  Quat qV2(0, normalize(transV));

  //calculate the rotation quaternion
  Quat Q = qV2 * inv(qV1);

  RigTForm m;
  if (g_mouseLClickButton && !g_mouseRClickButton){ // left button down? 
	  m.setRotation(Q);  //set the rotation quaternion
  }
  else if (g_mouseRClickButton && !g_mouseLClickButton) { // right button down?
	if(currentObj==2 && currentAuxFrame==0)
		m.setTranslation(Cvec3(dx, dy, 0) * -0.01);
	else
		m.setTranslation(Cvec3(dx, dy, 0) * 0.01);
  }	
  else if (g_mouseMClickButton || (g_mouseLClickButton && g_mouseRClickButton)) {  // middle or (left and right) button down?
    m.setTranslation(Cvec3(0, 0, -dy) * 0.01);
  }

  RigTForm auxFrame;  //initialize the auxillary frame

  if (g_mouseClickDown) {
	  if(currentObj != 2){
		  m.setRotation(inv(m.getRotation()));
		  auxFrame.setTranslation(g_objectRbt[currentObj].getTranslation());
		  auxFrame.setRotation(eyeRbt.getRotation());
		  g_objectRbt[currentObj] = auxFrame * m * inv(auxFrame) * g_objectRbt[currentObj];//rotate around the object frame, translate around the sky frame
	  }
	  else if (currentObj == 2 && currentAuxFrame == 0){
		  auxFrame.setRotation(eyeRbt.getRotation());         
		  g_skyRbt = auxFrame * m * inv(auxFrame) * g_skyRbt;  //world-sky aux frame
	  }
	  else if (currentObj == 2 && currentAuxFrame == 1){
		  auxFrame.setTranslation(eyeRbt.getTranslation());
		  auxFrame.setRotation(eyeRbt.getRotation());
		  g_skyRbt = auxFrame * m * inv(auxFrame) * g_skyRbt;  //sky-sky aux frame
	  }
    glutPostRedisplay(); // we always redraw if we change the scene
  }

  g_mouseClickX = x;
  g_mouseClickY = g_windowHeight - y - 1;
}
static void drawStuff() {
  // short hand for current shader state
  const ShaderState& curSS = *g_shaderStates[g_activeShader];

  // build & send proj. matrix to vshader
  const Matrix4 projmat = makeProjectionMatrix();
  sendProjectionMatrix(curSS, projmat);

  // assign eye rigid body matrix;
  //Matrix4 eyeRbt;
  RigTForm eyeRbt;
  switch(viewState){
  case 0:
	  eyeRbt = g_skyRbt;
	  break;
  case 1:                                     
	  eyeRbt = g_objRbt[0];
    break;
  case 2:       
	  eyeRbt = g_objRbt[1];
	  break;
  }
  
  const RigTForm invEyeRbt = inv(eyeRbt);

  const Cvec3 eyeLight1 = Cvec3(invEyeRbt * Cvec4(g_light1, 1)); // g_light1 position in eye coordinates
  const Cvec3 eyeLight2 = Cvec3(invEyeRbt * Cvec4(g_light2, 1)); // g_light2 position in eye coordinates
  safe_glUniform3f(curSS.h_uLight, eyeLight1[0], eyeLight1[1], eyeLight1[2]);
  safe_glUniform3f(curSS.h_uLight2, eyeLight2[0], eyeLight2[1], eyeLight2[2]);

  // draw ground
  // ===========
  //
  //const Matrix4 groundRbt = Matrix4();  // identity
  const RigTForm groundRbt;
  Matrix4 MVM = rigTFormToMatrix(invEyeRbt * groundRbt);
  Matrix4 NMVM = normalMatrix(MVM);
  sendModelViewNormalMatrix(curSS, MVM, NMVM);
  safe_glUniform3f(curSS.h_uColor, 0.1, 0.95, 0.1); // set color
  g_ground->draw(curSS);

  // draw cubes
  // ==========
  //MVM = invEyeRbt * g_objectRbt[0];
  MVM = rigTFormToMatrix(inv(eyeRbt) * g_objRbt[0]);
  NMVM = normalMatrix(MVM);
  sendModelViewNormalMatrix(curSS, MVM, NMVM);
  safe_glUniform3f(curSS.h_uColor, g_objectColors[0][0], g_objectColors[0][1], g_objectColors[0][2]);
  g_cube->draw(curSS);

  //MVM = invEyeRbt * g_objectRbt[1];
  MVM = rigTFormToMatrix(inv(eyeRbt) * g_objRbt[1]);
  NMVM = normalMatrix(MVM);
  sendModelViewNormalMatrix(curSS, MVM, NMVM);
  safe_glUniform3f(curSS.h_uColor, g_objectColors[1][0], g_objectColors[1][1], g_objectColors[1][2]);
  g_cube->draw(curSS);

  // draw arcball
  // ============
  
  // fix scale and you're good to go
  //g_arcballScale = getScreenToEyeScale(0, g_frustFovY, g_windowHeight);
  g_arcballScale = 1; 

  switch(manipState){
  case 0:                                  
    g_sphereRbt.setTranslation(Cvec3(0,0,0));
    break;
  case 1:
    g_sphereRbt.setTranslation(g_objRbt[0].getTranslation());
    g_sphereRbt.setRotation(g_objRbt[0].getRotation());
    break;
  case 2:                                                    
    g_sphereRbt.setTranslation(g_objRbt[1].getTranslation());
    g_sphereRbt.setRotation(g_objRbt[1].getRotation());
    break;
  }

  glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);  // draw wireframe

  // compute MVM, taking into account the dynamic radius
  float scale =  g_arcballScale * g_arcballScreenRadius;
  MVM = rigTFormToMatrix(inv(eyeRbt) * g_sphereRbt) * g_arcballScale;
  NMVM = normalMatrix(MVM);

  // send MVM and NMVM and colors
  sendModelViewNormalMatrix(curSS, MVM, NMVM);
  safe_glUniform3f(curSS.h_uColor, g_objectColors[2][0], g_objectColors[2][1], g_objectColors[2][2]);
  g_sphere->draw(curSS);

  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

}
Esempio n. 7
0
/*-----------------------------------------------*/
static void animateCamera(int value)
{
	static float stopwatch = 0;
	float msecsPerFrame = 1/(g_framesPerSecond / 1000);
	static int animationPart = 0;
	static bool isAnimating = true;
	const static float stepsPerSecond = 10.0/2.0; // Time Allowed / Steps taken
	static float totalTime = stepsPerSecond * 1 * 1000;
	static float elapsedTime = 0;
	static float x;
	static float z;
	static float radius = g_eyeRbt.getTranslation()[2];
	static float helperDegrees = 0;
	static float offsetDegrees = 90;
	static bool isFirstEntry = true;
	
	static RigTForm start = g_eyeRbt;
	static RigTForm end = RigTForm(g_eyeRbt.getTranslation(), Quat::makeYRotation(-180) * start.getRotation());
	//static RigTForm end = RigTForm();

	// Used to reset variables every time animation is run
	if (isFirstEntry)
	{
		start = g_eyeRbt;
		radius = g_eyeRbt.getTranslation()[2];
		end = RigTForm(g_eyeRbt.getTranslation(), Quat::makeYRotation(-180) * start.getRotation());
		isFirstEntry = false;
		//lookAtOrigin();
	}

	//Handles which part of animation is currently running
	if (elapsedTime >= totalTime)
	{
		g_eyeRbt.setRotation(end.getRotation());

		if (animationPart == 0)
		{
			start = end;
			end = RigTForm(g_eyeRbt.getTranslation(), Quat::makeYRotation(-180) * start.getRotation());
			helperDegrees = 180;
		}
		else
		{
			glutPostRedisplay();
			isAnimating = false;
		}
		//Reset values to default		
		totalTime = stepsPerSecond * 1 * 1000;
		elapsedTime = 0;

		animationPart++;
	}

	if (isAnimating)
	{
		float alpha = elapsedTime / totalTime;
///*
		//Handle Translation Interpolation
		Cvec3 startVec = g_eyeRbt.getTranslation();
		float degree = ((alpha * 180) + helperDegrees) + offsetDegrees;
		float toRadians = CS175_PI / 180.0;
		x = cos(degree * toRadians) * radius;
		z = sin(degree * toRadians) * radius;
		g_eyeRbt.setTranslation(Cvec3(x,g_eyeRbt.getTranslation()[1],z));
//*/
		// Initial rotations
		Quat startQ = start.getRotation();

		// Final rotations
		Quat endQ = end.getRotation();

		// Handle Rotational Interpolation
		if (g_interpolationType == I_POWER) // Quaternion Powering
		{	
			if (endQ - startQ != Quat(0,0,0,0)) // Check for actual rotation
			{
				Quat currentQ = Quat::pow(endQ, alpha);
				g_eyeRbt.setRotation(startQ * currentQ); // Apply rotation with respect to starting Position //Double rotates
			}
		}
		else if (g_interpolationType == I_SLERP) //Spherical linear interpolation
		{
			//startQ = inv(Quat()) * startQ;// * Quat();
			//endQ = inv(Quat()) * endQ;// * Quat();
			g_eyeRbt.setRotation(Quat::slerp(startQ, endQ, alpha) * startQ);
		}
		else if (g_interpolationType == I_LERP)
		{
			//Normalize quaternions
			Quat q = normalize(Quat::lerp(startQ, endQ, alpha));

			g_eyeRbt.setRotation(q);
		}

		elapsedTime += msecsPerFrame;
		glutPostRedisplay();
	
		//Time total animation
		stopwatch += msecsPerFrame;

		glutTimerFunc(msecsPerFrame, animateCamera, 0);
	}
	else
	{
		isAnimating =  true;
		//cout << "Stopwatch Camera = " << (stopwatch - msecsPerFrame * 2) / 1000 << "\n"; // Display final time not counting first and last frame
		stopwatch = 0;
		animationPart = 0;
		helperDegrees = 0;
		isFirstEntry = true;

		glutPostRedisplay();
	}
}
Esempio n. 8
0
/*-----------------------------------------------*/
static void animateLegs(int value)
{
	static float stopwatch = 0;
	float msecsPerFrame = 1/(g_framesPerSecond / 1000);
	static int animationPart = 0;
	static bool isAnimating = true;
	const static float degreesPerStep = 30;
	const static float stepsPerSecond = 20.0/34.0; // Time Allowed / Steps taken
	RigTForm *leftLeg = &g_rigidBodies[0].children[0]->children[2]->children[2]->rtf;
	RigTForm *rightLeg = &g_rigidBodies[0].children[0]->children[2]->children[3]->rtf;

	static RigTForm startLeftLeg = *leftLeg;
	static RigTForm endLeftLeg = startLeftLeg;
	static RigTForm startRightLeg = *rightLeg;
	static RigTForm endRightLeg = startRightLeg;

	static float totalTime = stepsPerSecond * 1 * 1000;
	static float elapsedTime = totalTime;
	
	

	//Handles which part of animation is currently running
	if (elapsedTime >= totalTime)
	{
		leftLeg->setRotation(endLeftLeg.getRotation());
		rightLeg->setRotation(endRightLeg.getRotation());


		// Initialize with first step
		if (animationPart == 0)
		{
			startLeftLeg = endLeftLeg;
			startRightLeg = endRightLeg;

			endLeftLeg = RigTForm(Quat::makeXRotation(-degreesPerStep) * startLeftLeg.getRotation());
			endRightLeg = RigTForm(Quat::makeXRotation(degreesPerStep) * startRightLeg.getRotation());

			//cout << "endLeftLeg Angle = " << endLeftLeg.getRotation().getAngle() << "\n";
			//cout << "endRightLeg Angle = " << endRightLeg.getRotation().getAngle() << "\n";

			totalTime = stepsPerSecond * 0.5 * 1000;
		}
		else if (animationPart < 34)
		{
			startLeftLeg = endLeftLeg;
			startRightLeg = endRightLeg;
			if (animationPart %2 == 0)
			{
				endLeftLeg = RigTForm(Quat::makeXRotation(-degreesPerStep * 2) * startLeftLeg.getRotation());
				endRightLeg = RigTForm(Quat::makeXRotation(degreesPerStep * 2) * startRightLeg.getRotation());
			}
			else
			{
				endLeftLeg = RigTForm(Quat::makeXRotation(degreesPerStep * 2) * startLeftLeg.getRotation());
				endRightLeg = RigTForm(Quat::makeXRotation(-degreesPerStep * 2) * startRightLeg.getRotation());
			}
			//cout << "Degrees = " << degreesPerStep << "\n";
			//cout << "endLeftLeg Angle = " << endLeftLeg.getRotation().getAngle() << "\n";
			//cout << "endRightLeg Angle = " << endRightLeg.getRotation().getAngle() << "\n";

			totalTime = stepsPerSecond * 1 * 1000;
		}
		else if (animationPart == 34)
		{
			startLeftLeg = endLeftLeg;
			startRightLeg = endRightLeg;

			endLeftLeg = RigTForm(Quat());
			endRightLeg = RigTForm(Quat());

			totalTime = stepsPerSecond * 0.5 * 1000;
		}
		else
		{
			glutPostRedisplay();

			isAnimating = false;

			//Reset values to default
			startLeftLeg = *leftLeg;
			startRightLeg = *rightLeg;
			totalTime = stepsPerSecond * 1 * 1000;
		}

		animationPart++;

		elapsedTime = 0;
	}

	if (isAnimating)
	{
		float alpha = elapsedTime / totalTime;

		// Initial rotations
		Quat startLeftLegQ = leftLeg->getRotation();
		Quat startRightLegQ = rightLeg->getRotation();

		// Final rotations
		Quat endLeftLegQ = endLeftLeg.getRotation();
		Quat endRightLegQ = endRightLeg.getRotation();

		// Handle Rotational Interpolation
		if (g_interpolationType == I_POWER) // Quaternion Powering
		{	
			if (endLeftLegQ - startLeftLegQ != Quat(0,0,0,0)) // Check for actual rotation
			{
				Quat currentLeftLegQ = Quat::pow(endLeftLegQ, alpha);
				leftLeg->setRotation(startLeftLegQ * currentLeftLegQ); // Apply rotation with respect to starting Position //Double rotates
			}

			if (endRightLegQ - startRightLegQ != Quat(0,0,0,0)) // Check for actual rotation
			{
				Quat currentRightLegQ = Quat::pow(endRightLegQ, alpha);
				rightLeg->setRotation(startRightLegQ * currentRightLegQ); // Apply rotation with respect to starting Position //Double rotates
			}
		}
		else if (g_interpolationType == I_SLERP) //Spherical linear interpolation
		{
			leftLeg->setRotation(Quat::slerp(startLeftLegQ, endLeftLegQ, alpha) * startLeftLegQ);
			rightLeg->setRotation(Quat::slerp(startRightLegQ, endRightLegQ, alpha) * startRightLegQ);
		}
		else if (g_interpolationType == I_LERP)
		{
			//Normalize quaternions
			Quat leftLegQ = normalize(Quat::lerp(startLeftLegQ, endLeftLegQ, alpha));
			Quat rightLegQ = normalize(Quat::lerp(startRightLegQ, endRightLegQ, alpha));

			leftLeg->setRotation(leftLegQ);
			rightLeg->setRotation(rightLegQ);
		}

		elapsedTime += msecsPerFrame;
		glutPostRedisplay();
	
		//Time total animation
		stopwatch += msecsPerFrame;

		glutTimerFunc(msecsPerFrame, animateLegs, 0);
	}
	else
	{
		isAnimating =  true;
		//cout << "Stopwatch Legs = " << (stopwatch - msecsPerFrame * 2) / 1000 << "\n"; // Display final time not counting first and last frame
		stopwatch = 0;
		animationPart = 0;
		elapsedTime = totalTime;
	}
}
Esempio n. 9
0
/*-----------------------------------------------*/
static void keyboard(const unsigned char key, const int x, const int y) 
{
	/* PURPOSE:		OpenGL Callback for Keyboard presses 
		RECEIVES:	unsigned char key - Key pressed
						int x - Mouse x_position when key pressed
						int y - Mouse y_position when key pressed
		REMARKS:		Handles robot modifications based on key presses and then requests a redisplay
	*/

	if (isKeyboardActive)
	{
		switch (key) 
		{
			case 27:
				exit(0);                                  // ESC
			case 'i':
				cout << " ============== H E L P ==============\n\n"
				<< "i\t\thelp menu\n"
				<< "s\t\tsave screenshot\n"
				<< "f\t\tToggle flat shading on/off.\n"
				<< "o\t\tCycle object to edit\n"
				<< "v\t\tCycle view\n"
				<< "drag left mouse to rotate\n" << endl;
				break;
			case 's':
				glFlush();
				writePpmScreenshot(g_windowWidth, g_windowHeight, "out.ppm");
				break;
			case 'f':
				g_activeShader ^= 1;
				break;
	  }

		if (key == '1')
		{
			g_framesPerSecond = 32;
		}
		else if (key == '2')
		{
			g_framesPerSecond = 16;
		}
		else if (key == '3')
		{
			g_framesPerSecond = 8;
		}
		else if (key == '4')
		{
			g_framesPerSecond = 4;
		}
		else if (key == '5')
		{
			g_framesPerSecond = 2;
		}
		else if (key == '6')
		{
			g_framesPerSecond = 1;
		}
		else if (key == '7')
		{
			g_framesPerSecond = 0.5;
		}
		else if (key == '8')
		{
			g_framesPerSecond = 0.25;
		}
		else if (key == '9')
		{
			g_framesPerSecond = 0.125;
		}
	
		if (key == 'q')
		{
			Quat q = g_rigidBodies[0].rtf.getRotation();
			g_rigidBodies[0].rtf.setRotation(q * Quat::makeYRotation(15));
		}
		else if (key == 'p')
		{
			g_interpolationType = I_POWER;
		}
		else if (key == 's')
		{
			g_interpolationType = I_SLERP;
		}
		else if (key == 'l')
		{
			g_interpolationType = I_LERP;
		}
		else if (key == 'r')
		{
			float msecs =  0 * 1000;
			glutTimerFunc(msecs, timer, PAUSE);
			glutTimerFunc(msecs, animateCamera,0);
		}
		else if (key == 'a')
		{
			float msecs =  0 * 1000;
			glutTimerFunc(msecs, animateRobot, 0);
			glutTimerFunc(msecs, animateLegs, 0);
		}
		else if (key == ',')
		{
			g_eyeRbt.setRotation(g_eyeRbt.getRotation() * Quat().makeZRotation(15));
		}
		else if (key == '.')
		{
			g_eyeRbt.setRotation(g_eyeRbt.getRotation() * Quat().makeZRotation(-15));
		}
		else if (key == '-')
		{
			float max = 20;
			Cvec3 cameraTrans = g_eyeRbt.getTranslation();

			g_eyeRbt.setTranslation(cameraTrans + Cvec3(0,0,1));
		
			if (cameraTrans[2] >= max)
				g_eyeRbt.setTranslation(Cvec3(cameraTrans[0], cameraTrans[1], max));

			lookAtOrigin();

			//cout << "( " << g_eyeRbt.getTranslation()[0] << ", " << g_eyeRbt.getTranslation()[1] << ", " << g_eyeRbt.getTranslation()[2] << "\n";

		}
		else if (key == '=')
		{
			float min = 5;
			Cvec3 cameraTrans = g_eyeRbt.getTranslation();

			g_eyeRbt.setTranslation(cameraTrans - Cvec3(0,0,1));
	
			if (cameraTrans[2] <= min)
				g_eyeRbt.setTranslation(Cvec3(cameraTrans[0], cameraTrans[1], min));

			lookAtOrigin();

			//cout << "( " << g_eyeRbt.getTranslation()[0] << ", " << g_eyeRbt.getTranslation()[1] << ", " << g_eyeRbt.getTranslation()[2] << "\n";
		}
	}

	glutPostRedisplay();
}