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;
}
예제 #2
0
static RigTForm getMRbt(int x, int y,double dx, double dy, bool isSkySky){
	RigTForm m;
	y = g_windowHeight - y -1;
	if (g_mouseLClickButton && !g_mouseRClickButton) { // left button down?
		// are we showing the arcball?
	  if(g_showArcBall){
			const RigTForm eyeRbt = *g_currViewRbt;
			const RigTForm invEyeRbt = inv(eyeRbt);
			Matrix4 projMatrix = makeProjectionMatrix();
			Cvec3 arcWRTeye = Cvec3(invEyeRbt * (Cvec4(getArcBallRBT().getTranslation(),1)));
			Cvec2 arcBall_center;
			arcBall_center = getScreenSpaceCoord(arcWRTeye,projMatrix,g_frustNear,
					g_frustFovY,g_windowWidth,g_windowHeight);
			const Cvec3 v0 = normalize(getDirection(arcBall_center, g_mouseClickX, g_mouseClickY));
			const Cvec3 v1 = normalize(getDirection(arcBall_center, x,y));
			if(g_currObj != SKY)
				m = RigTForm(Quat(0,v1[0],v1[1],v1[2]) * Quat(0, -v0[0],-v0[1],-v0[2]));
			else
				m = RigTForm(Quat(0,v0[0],v0[1],v0[2]) * Quat(0, -v1[0],-v1[1],-v1[2]));
	  }
	  else if(g_viewmode == g_currObj){
		m= RigTForm(Quat::makeXRotation(dy)*Quat::makeYRotation(-dx));//m = Matrix4::makeXRotation(dy) * Matrix4::makeYRotation(-dx);
		}
	  else{
		m= RigTForm(Quat::makeXRotation(-dy)*Quat::makeYRotation(dx));
	  }
  }
  else if (g_mouseRClickButton && !g_mouseLClickButton) { // right button down?
	if(g_showArcBall && !isSkySky){
		m = m.setTranslation(Cvec3(dx, dy, 0) * g_arcBallScale);	
	}
	else if(isSkySky && !g_egoMotion)
		m = m.setTranslation(Cvec3(-dx, -dy, 0) * g_arcBallScale);
	else 
		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 = m.setTranslation(Cvec3(0, 0, -dy) * 0.01);
  }
  return m;
}
예제 #3
0
static RigTForm getMRbt(const double dx, const double dy){
	RigTForm m;
	if (g_mouseLClickButton && !g_mouseRClickButton) { // left button down?
		if(!g_isArcBallDisable && getMode()!=2){
		  const RigTForm eyeRbt = getPathAccumRbt(g_world,g_currViewRbt);
		  const RigTForm invEyeRbt = inv(eyeRbt);
		  Matrix4 projMatrix = makeProjectionMatrix();
		  Cvec3 arcWRTeye = Cvec3(invEyeRbt * Cvec4(getArcBallRBT().getTranslation(),1));
		  Cvec2 arcBall_center;
		  arcBall_center = getScreenSpaceCoord(arcWRTeye,projMatrix,g_frustNear,
					g_frustFovY,g_windowWidth,g_windowHeight);
		  const Cvec3 v0 = normalize(getDirection((Cvec2(g_mouseClickX, g_mouseClickY)-arcBall_center)));
		  const Cvec3 v1 = normalize(getDirection((Cvec2(g_mouseClickX + dx, g_mouseClickY + dy)-arcBall_center)));
		  m = RigTForm(Quat(0,v1[0],v1[1],v1[2]) * Quat(0, -v0[0],-v0[1],-v0[2]));
		  }
		else
			m= RigTForm(Quat::makeXRotation(-dy)*Quat::makeYRotation(dx));
	}
  else if (g_mouseRClickButton && !g_mouseLClickButton) { // right button down?
	if(!g_isArcBallDisable)
			m = m.setTranslation(Cvec3(dx, dy, 0) * g_arcBallScale);	
	else
			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 = m.setTranslation(Cvec3(0, 0, -dy) * 0.01);
  }
  switch (getMode()){
  case 1:
	  m = inv(m);
	  break;
  case 2:
	  if(g_mouseLClickButton && !g_mouseRClickButton)
		  m = inv(m);
	  break;
  }
  return m;
}
예제 #4
0
파일: asst7.cpp 프로젝트: thewinniewu/CS175
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();
}
예제 #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);

}
예제 #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();
	}
}
예제 #8
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();
}