Пример #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)));
}
Пример #2
0
static void updateArcballScale() {
  RigTForm arcballEye = inv(getNodeForEye(g_activeEye)->getRbt()) * getArcballRbt();
  double depth = arcballEye.getTranslation()[2];
  if (depth > -CS175_EPS)
    g_arcballScale = 0.02;
  else
    g_arcballScale = getScreenToEyeScale(depth, g_frustFovY, g_windowHeight);
}
Пример #3
0
static void updateArcballScale() {
  RigTForm arcballEye = inv(getPathAccumRbt(g_world, g_currentCameraNode)) * getArcballRbt();
  double depth = arcballEye.getTranslation()[2];
  if (depth > -CS175_EPS)
    g_arcballScale = 0.02;
  else
    g_arcballScale = getScreenToEyeScale(depth, g_frustFovY, g_windowHeight);
}
Пример #4
0
static void drawStuff(const ShaderState& curSS, bool picking) {
  // build & send proj. matrix to vshader
  const Matrix4 projmat = makeProjectionMatrix();
  sendProjectionMatrix(curSS, projmat);

  // use the skyRbt as the eyeRbt
  const RigTForm eyeRbt = getPathAccumRbt(g_world, g_currViewRbt);
  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]);

  if (!picking) {
	  Drawer drawer(invEyeRbt, curSS);
	  g_world->accept(drawer);

	  //draw arcBall
	  //============
	  if(g_showArcBall){
		  Matrix4 MVM,NMVM;
	  
		  //Get accumulated path from current view rbt to arcball
		  RigTForm arcballEye = inv(getPathAccumRbt(g_world,g_currViewRbt))*getArcBallRBT();

		  //if not zooming
		  if (!(g_mouseMClickButton || (g_mouseLClickButton && g_mouseRClickButton))){
			  double depth = arcballEye.getTranslation()[2];
			  g_arcBallScale = getScreenToEyeScale(depth, g_frustFovY, g_windowHeight);
		  }
		  double alpha = g_arcBallScale* g_arcBallScreenRadius;
		  //g_objectRbt[2] = RigTForm(g_objectRbt[2].getTranslation(),g_objectRbt[2].getRotation()*alpha);
		  MVM = rigTFormToMatrix( arcballEye) * Matrix4::makeScale(Cvec3(1,1,1)*alpha);
		  NMVM = normalMatrix(MVM);
		  sendModelViewNormalMatrix(curSS, MVM, NMVM);
		  safe_glUniform3f(curSS.h_uColor, g_objectColors[2][0], g_objectColors[2][1], g_objectColors[2][2]);
		  glPolygonMode( GL_FRONT_AND_BACK, GL_LINE);
		  g_arcBall->draw(curSS);
		  glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
	  }
  }
  else {
	  Picker picker(invEyeRbt, curSS);
	  g_world->accept(picker);
	  glFlush();
	  g_currentPickedRbtNode = picker.getRbtNodeAtXY(g_mouseClickX, g_mouseClickY);
	  if(!g_currentPickedRbtNode)
		  cout<<"Nothing Picked"<<endl;
	  if (g_currentPickedRbtNode == g_groundNode)
		g_currentPickedRbtNode = shared_ptr<SgRbtNode>();   // set to NULL
	  cout << "Picking Off" << endl;
	}
}
Пример #5
0
static RigTForm evaluateCatmull_Rom(RigTForm prev, RigTForm from, RigTForm to, RigTForm post, float alpha) {
	// TODO: sanity check for quat negation if first coordinate of the part of D is negative
	Cvec3 BC_CvecD = (to.getTranslation() - prev.getTranslation()) * (1.0 / 6.0) + from.getTranslation();
	Cvec3 BC_CvecE = (post.getTranslation() - from.getTranslation()) * (-1.0 / 6.0) + to.getTranslation();
  
  Quat q = prev.getRotation();
  cout << "GETPREVROTATION: " << q[0] << q[1] << q[2] << q[3] << endl;


	Quat d_pow = cn(to.getRotation() * inv(prev.getRotation()));
	Quat e_pow = post.getRotation() * inv(from.getRotation());
  cout << "=======\n"; 
  cout << d_pow[0] << d_pow[1] << d_pow[2] << d_pow[3] << endl;
    cout << e_pow[0] << e_pow[1] << e_pow[2] << e_pow[3] << endl;
    cout << "------\n";
	/*if (d_pow[0] < 0) {
		d_pow = d_pow.cn;
		printf("%i", d_pow[0]);
	}*/

	//Quat BC_QuatD = (to.getRotation() * inv(prev.getRotation())).quat_pow(1 / 6) * from.getRotation();
	//Quat BC_QuatE = (post.getRotation() * inv(from.getRotation())).quat_pow(-1 / 6) * to.getRotation();
	Quat BC_QuatD = d_pow.quat_pow(1.0 / 6.0) * from.getRotation();
	Quat BC_QuatE = e_pow.quat_pow(-1.0 / 6.0) * to.getRotation();
	
//	Quat BC_QuatD = Quat(1, 0, 0, 0);
//	Quat BC_QuatE = Quat(1, 0, 0, 0);

    RigTForm BC_D = RigTForm(BC_CvecD, BC_QuatD);
	RigTForm BC_E = RigTForm(BC_CvecE, BC_QuatE);

	return evaluateBezier(from, to, BC_D, BC_E, alpha);
}
Пример #6
0
static void reset()
{
  g_view = 0;
  g_object = 1;
  g_skyFrame = 0;
  g_skyRbt = RigTForm(Cvec3(0.0, 0.25, 4.00));
  g_objectRbt[0] = RigTForm(Cvec3(-.75,0,0));
  g_objectRbt[1] = RigTForm(Cvec3(.75,0,0));
  g_viewRbt = g_skyRbt;
  g_objRbt = g_objectRbt[0];
  g_renderArcball = true;
  g_arcballScale = getScreenToEyeScale(g_viewRbt.getTranslation()[2], g_frustFovY, g_windowHeight);
  cout << "reset objects and modes to defaults" << endl;
}
Пример #7
0
static void writeFrameDataToFile() {
	if (!keyframeList.empty()) {
		ofstream myfile;
		myfile.open("animation.txt");
		// myfile << "Writing this to a file.\n";
		// myfile << "testing, testing \n";
		string output = "";
		int num_frames = keyframeList.size();
		list<RigTFormVector>::iterator iter = keyframeList.begin();
		int num_nodes = (*iter).size();
    
    std::ostringstream s;
    s << num_frames
      << "\n"
      << num_nodes
      << "\n";
    output.append(s.str());
		for (iter; iter != keyframeList.end(); ++iter) {
			RigTFormVector scene = (*iter);
			for (int i = 0; i < scene.size(); ++i) {
				RigTForm rigTForm = scene[i];
				Cvec3 translation = rigTForm.getTranslation();
				Quat rotation = rigTForm.getRotation();
				for (int j = 0; j < 3; j++) {
				  s.str(""); 
          s.clear(); 
          s << translation[j] << " ";
          output.append(s.str());
				}
				for (int k = 0; k < 4; k++) {
				  s.str(""); 
          s.clear(); 
          s << rotation[k] << " ";
          output.append(s.str());
				}
				output.append("\n");
			}
		}
		myfile << output;

		myfile.close();
		printf("Writing to animation.txt\n");
	}
}
Пример #8
0
static void calculateDOF(int index){
	Cvec3 c = g_skyRbt.getTranslation();
	float hyperfocalDistance = pow(g_focalLength,2)/(g_circleOfConfusion * g_aperture/g_focalLength * 10) + g_focalLength;
	float nearPlane = c(2) * (hyperfocalDistance - g_focalLength)/(hyperfocalDistance + c(2) - 2 * g_focalLength);
	float farPlane = c(2) * (hyperfocalDistance - g_focalLength)/(hyperfocalDistance - c(2));

	cout << "eyeDepth: " << c(2) << endl;
	cout << "hyperfocal distance: " << hyperfocalDistance << endl;
	cout << "nearPlane: " << nearPlane << endl;
	cout << "farPlane: " << farPlane << endl;
	cout << "Object Depth: " << g_objectRbt[index].getTranslation()(2) << endl;

	if(g_objectRbt[index].getTranslation()(2) < farPlane || g_objectRbt[index].getTranslation()(2) > nearPlane)
		g_objectColors[index] = Cvec3f(1,1,1);
	else{
		cout << "back to original color" << endl;
		g_objectColors[index] = g_originalObjectColors[index];
	}
}
Пример #9
0
static void write_frame() {
  list<vector<RigTForm> >::iterator it = key_frames.begin();
  FILE* output = fopen("animation.txt", "w");
  int n = (*it).size();
  fprintf(output, "%d %d\n", key_frames.size(), n);
  while (it != key_frames.end()) {
    vector<RigTForm> frame = *it;
    for (int i = 0; i < frame.size(); ++i) {
      RigTForm r = frame[i];
      Cvec3 transFact = r.getTranslation();
      Quat linFact = r.getRotation();
      fprintf(output, "%.3f %.3f %.3f %.3f %.3f %.3f %.3f\n",
          transFact[0], transFact[1], transFact[2],
          linFact[0], linFact[1], linFact[2], linFact[3]
      );
    }
    ++it;
  }
  fclose(output);
}
Пример #10
0
static RigTForm evaluateBezier(RigTForm from, RigTForm to, RigTForm d, RigTForm e, float alpha) {
	Cvec3 f_t = lerp(from.getTranslation(), d.getTranslation(), alpha);
	Cvec3 g_t = lerp(d.getTranslation(), e.getTranslation(), alpha);
	Cvec3 h_t = lerp(e.getTranslation(), to.getTranslation(), alpha);
	Cvec3 m_t = lerp(f_t, g_t, alpha);
	Cvec3 n_t = lerp(g_t, h_t, alpha);
	Cvec3 c_t = lerp(m_t, n_t, alpha);

	Quat f_q = slerp(from.getRotation(), d.getRotation(), alpha);
	Quat g_q = slerp(d.getRotation(), e.getRotation(), alpha);
	Quat h_q = slerp(e.getRotation(), to.getRotation(), alpha);
	Quat m_q = slerp(f_q, g_q, alpha);
	Quat n_q = slerp(g_q, h_q, alpha);
	Quat c_q = slerp(m_q, n_q, alpha);

	return RigTForm(c_t, c_q);
}
Пример #11
0
//called on mouse motion
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 mRbt;
  

  if (g_mouseLClickButton && !g_mouseRClickButton && !g_spaceDown) { // left button down?

    if (g_arcballVisible){
      mRbt = RigTForm(arcballRotation(x, y));
    } else {
      mRbt = RigTForm(Quat::makeXRotation(-dy) * Quat::makeYRotation(dx));
    }
  }
  else if (g_mouseRClickButton && !g_mouseLClickButton) { // right button down?

    if (g_arcballVisible) {
      mRbt = RigTForm(Cvec3(dx, dy, 0) * g_arcballScale);
    } else {
      mRbt = RigTForm(Cvec3(dx, dy, 0) * 0.01);
    }
    
  }
  else if (g_mouseMClickButton || (g_mouseLClickButton && g_mouseRClickButton) || (g_mouseLClickButton && !g_mouseRClickButton && g_spaceDown)) {  // middle or (left and right, or left + space) button down?

    if (g_arcballVisible) {
      mRbt = RigTForm(Cvec3(0, 0, -dy) * g_arcballScale);
    } else {
      mRbt = RigTForm(Cvec3(0, 0, -dy) * 0.01);
    }
    
  }

  buildAFrame();

  if (g_mouseClickDown) {
    
    RigTForm curRbt = g_currentPickedRbtNode->getRbt();

    if(g_currentPickedRbtNode == g_skyNode) {

      if (g_skyModMode == 0) {
          Quat rot = mRbt.getRotation();
          mRbt = RigTForm(-(mRbt.getTranslation()), Quat(rot[0], -(rot[1]), -(rot[2]), -(rot[3])));
          g_skyNode->setRbt(g_aFrame * mRbt * inv(g_aFrame) * curRbt);
      } else {
          Quat rot = mRbt.getRotation();
          mRbt = RigTForm(mRbt.getTranslation(), Quat(rot[0], -(rot[1]), -(rot[2]), -(rot[3])));
          g_skyNode->setRbt(g_aFrame * mRbt * inv(g_aFrame) * curRbt);
      }
    }else {
      
      //g_arcballRbt = g_aFrame * mRbt * inv(g_aFrame) * g_arcballRbt;
      RigTForm newAFrame = inv(getPathAccumRbt(g_world, g_currentPickedRbtNode, 1)) * g_aFrame;
      g_currentPickedRbtNode->setRbt(newAFrame * mRbt * inv(newAFrame) * curRbt);
    } 
    glutPostRedisplay(); // we always redraw if we changed the scene
  }

  g_mouseClickX = x;
  g_mouseClickY = g_windowHeight - y - 1;
}
Пример #12
0
//true on intersection, will populate passed Cvec3 pointer with intersection point
bool PhysicsSim::intersect_sphere_plane(shared_ptr<HasPhysicsBody> sphere, shared_ptr<HasPhysicsBody> plane, Cvec3* intersectionPoint) {

	SphericalPhysicsBody *spherePb = dynamic_cast<SphericalPhysicsBody *>(sphere->getPhysicsBody());
	shared_ptr<SgTransformNode> sphereNode = dynamic_pointer_cast<SgTransformNode>(sphere);

	PlanarPhysicsBody *planePb = dynamic_cast<PlanarPhysicsBody *>(plane->getPhysicsBody());
	shared_ptr<SgTransformNode> planeNode = dynamic_pointer_cast<SgTransformNode>(plane);

	//assert sphere and plane!
	assert(spherePb != NULL && sphereNode != NULL);
	assert(planePb != NULL && planeNode != NULL);

	Cvec3 sphereCenter = getPathAccumRbt(rootNode_, sphereNode).getTranslation();
	
	RigTForm planeRtf = getPathAccumRbt(rootNode_, planeNode);

	
	Cvec3 planeNormal = planeRtf.getRotation() * planePb->getUnitNormal();
	//line is a line perp. to plane passing through sphere center

	Cvec3 intersection = Cvec3();
	bool doesIntersect =
		intersect_line_plane(
			sphereCenter,
			planeNormal,
			planeRtf.getTranslation(),
			planeNormal,
			&intersection
		);
	//constructed to be perp.
	assert(doesIntersect);
	Cvec3 perpVecFromCtrToPlane = intersection - sphereCenter;

	float distFromCtrToPlane = norm(perpVecFromCtrToPlane);

	//if the closest dist. from the center of the sphere to the plane
	//is less than radius, then collision. Otherwise, no.
	if(distFromCtrToPlane <= spherePb->getRadius()) {

		//TODO: check that intersection lies within bounds of finite plane
		//first: find quat from x-axis to the normal that has had the RigTForm's quat applied
		//use this quat to transform the y and z axes
		//get the intersection point relative to planar center
		//apply the inverse quat from the first part
		//check that abs(y) and ans(z) components are less than width/2 and height/2!!
		Quat fromXAxisToNormal;
		if(abs(dot(planeNormal, Cvec3(1, 0, 0))) - 1 < CS175_EPS2) {
			//normal is parallel to x-axis
			//Case 1: opposite
			if(dot(planeNormal, Cvec3(1, 0, 0)) < 0) {
				fromXAxisToNormal = Quat::makeZRotation(2 * M_PI);

			} else {//Case 2:on the axis
				fromXAxisToNormal = Quat::makeZRotation(0);
			}
		} else {
			//then it's valid to do general formula
			//from v1 to v2
			Cvec3 a = cross(Cvec3(1, 0, 0), planeNormal);
			fromXAxisToNormal[0] = a[0];
			fromXAxisToNormal[1] = a[1];
			fromXAxisToNormal[2] = a[2];
			fromXAxisToNormal[3] = sqrt(norm2(planeNormal)) + planeNormal[0];
		}
		Quat fromNormalToXAxis = inv(fromXAxisToNormal);
		Cvec3 intersectionOnXAxis = fromNormalToXAxis * (intersection - planeRtf.getTranslation());
		if(abs(intersectionOnXAxis[1] <= planePb->getWidth()/2 && intersectionOnXAxis[2] <= planePb->getHeight()/2)) {

			//fix sphere position to be firmly outside of plane!
			float overlap = spherePb->getRadius() - distFromCtrToPlane;
			Cvec3 offset = planeNormal * overlap;
			sphereNode->setRbt(sphereNode->getRbt() * RigTForm(offset));

			//intersection within bounds!
			(*intersectionPoint) = intersection;
			return true;
		} else
			return false;
	} else
		return false;
}
Пример #13
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;
}
Пример #14
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();
}
Пример #15
0
/*-----------------------------------------------*/
static void animateRobot(int value)
{
	static float stopwatch = 0;
	float msecsPerFrame = 1/(g_framesPerSecond / 1000);
	static int animationPart = 0;
	static bool isAnimating = true;
	static float stepsPerSecond = 20.0/34.0; // Time Allowed / Steps taken

	//Initial walk to right 5secs (+)x-axis
	static RigTForm start = g_rigidBodies[0].rtf;
	static RigTForm end = RigTForm(Cvec3(5,0,0)) * start;
	static float totalTime = stepsPerSecond * 5 * 1000;
	static float elapsedTime = 0;
	
	//Handles which part of animation is currently running
	if (elapsedTime > totalTime)
	{
		animationPart++;

		//end = g_rigidBodies[0].rtf;
		g_rigidBodies[0].rtf = end;

		//Rotate
		if (animationPart == 1 || animationPart == 3 || animationPart == 5 || animationPart == 7)
		{
			start = end;
			end = RigTForm(start.getTranslation(), Quat::makeYRotation(90) * start.getRotation());
			
			totalTime = stepsPerSecond * 1 * 1000;
		}
		//Walk (-)z 10 paces
		else if (animationPart == 2)
		{
			start = end;
			end = RigTForm(Cvec3(0,0,-10)) * start;
			totalTime = stepsPerSecond * 10 * 1000;
		}
		//Walk (-)x 5 paces
		else if (animationPart == 4)
		{
			start = end;
			end = RigTForm(Cvec3(-5,0,0)) * start;
			totalTime = stepsPerSecond * 5 * 1000;
		}
		//Walk (+)z 10 paces
		else if (animationPart == 6)
		{
			start = end;
			end = RigTForm(Cvec3(0,0,10)) * start;
			totalTime = stepsPerSecond * 10 * 1000;
		}
		else
		{	
			glutPostRedisplay();

			isAnimating = false;

			//Reset values to default
			animationPart = 0;
			start = g_rigidBodies[0].rtf;
			end = RigTForm(Cvec3(5,0,0)) * start;
			totalTime = stepsPerSecond * 5 * 1000;
		}

		elapsedTime = 0;
	}

	if (isAnimating)
	{
		float alpha = elapsedTime / totalTime;
		
		//Handle Translation Interpolation
		Cvec3 startVec = start.getTranslation();
		Cvec3 temp = end.getTranslation() - startVec; 
		g_rigidBodies[0].rtf.setTranslation(startVec + (temp * alpha));

		Quat startQ = start.getRotation(); // Initial rotation
		Quat endQ = end.getRotation();	// Final rotation

		//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);
				//Quat currentQ = Quat::pow(endQ * inv(startQ), alpha); // Calculate this frames rotation Quat //Slerping???
				g_rigidBodies[0].rtf.setRotation(startQ * currentQ); // Apply rotation with respect to starting Position //Double rotates
			}
		}
		else if (g_interpolationType == I_SLERP) //Spherical linear interpolation
		{
			g_rigidBodies[0].rtf.setRotation(Quat::slerp(startQ, endQ, alpha) * startQ);
		}
		else if (g_interpolationType == I_LERP)
		{
			Quat q = normalize(Quat::lerp(startQ, endQ, alpha)); //Normalize lerped quaternion
			g_rigidBodies[0].rtf.setRotation(q);
		}

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

		glutTimerFunc(msecsPerFrame, animateRobot, 0);
	}
	else
	{
		isAnimating =  true;
		//cout << "Stopwatch = " << (stopwatch - msecsPerFrame * 2) / 1000 << "\n"; // Display final time not counting first and last frame
		stopwatch = 0;
	}
}
Пример #16
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();
	}
}
Пример #17
0
static void drawStuff(const ShaderState& curSS, bool picking) {
  // build & send proj. matrix to vshader
  const Matrix4 projmat = makeProjectionMatrix();
  sendProjectionMatrix(curSS, projmat);

  // Choose an eye camera
  // changed to shared_ptr in hw4
  switch(CHOOSEN_FRAME){
    case 0:
      g_currentView = g_skyNode;
      break;
    case 1:
      g_currentView = g_robot1Node;
      break;
    case 2:
      g_currentView = g_robot2Node;
      break;
  }

  const RigTForm eyeRbt = getPathAccumRbt(g_world, g_currentView);
  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]);

  if (!picking) {
    Drawer drawer(invEyeRbt, curSS);
    g_world->accept(drawer);

    // draw a sphere?
    if(!DRAW_SPHERE){return;}    
    if(!WORLD_SKY && !g_currentPickedRbtNode){return;}
    
    RigTForm sphere_center = getPathAccumRbt(g_world, g_currentPickedRbtNode);
    RigTForm eyeCord = invEyeRbt * sphere_center; 
    sphere_center_eyeCord = eyeCord.getTranslation();

    if (!(g_mouseMClickButton || (g_mouseLClickButton && g_mouseRClickButton))){ 
      g_arcballScale = getScreenToEyeScale(sphere_center_eyeCord[2], g_frustFovY, g_windowHeight);
    }
    double arcball_radius = g_arcballScale * g_arcballScreenRadius;

    // draw sphere
    // ----------
    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
    Matrix4 MVM = rigTFormToMatrix(eyeCord) * Matrix4::makeScale(Cvec3(arcball_radius, arcball_radius, arcball_radius));
    Matrix4 NMVM = normalMatrix(MVM);
    sendModelViewNormalMatrix(curSS, MVM, NMVM);
    safe_glUniform3f(curSS.h_uColor, 0, 0, 0);
    g_sphere->draw(curSS);
    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

  }
  else{
    Picker picker(invEyeRbt, curSS);
    g_world->accept(picker);
    glFlush();
    g_currentPickedRbtNode = picker.getRbtNodeAtXY(g_mouseClickX, g_mouseClickY);
    if (g_currentPickedRbtNode == g_groundNode)
      g_currentPickedRbtNode = shared_ptr<SgRbtNode>(); 
  }  

}
Пример #18
0
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);

  // use the skyRbt as the eyeRbt
  const RigTForm eyeRbt = *g_currViewRbt;
  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 RigTForm groundRbt = RigTForm();  // identity
  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 = rigTFormToMatrix(invEyeRbt * g_objectRbt[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 = rigTFormToMatrix(invEyeRbt * g_objectRbt[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
  //============
  if(g_showArcBall){
	  RigTForm arcballEye = inv(*g_currViewRbt);
	  arcballEye = arcballEye * getArcBallRBT();
	  
	  //if not zooming
	  if (!(g_mouseMClickButton || (g_mouseLClickButton && g_mouseRClickButton))){
		  double depth = arcballEye.getTranslation()[2];
		  g_arcBallScale = getScreenToEyeScale(depth, g_frustFovY, g_windowHeight);
	  }
	  double alpha = g_arcBallScale* g_arcBallScreenRadius;
	  //g_objectRbt[2] = RigTForm(g_objectRbt[2].getTranslation(),g_objectRbt[2].getRotation()*alpha);
	  MVM = rigTFormToMatrix( arcballEye) * Matrix4::makeScale(Cvec3(1,1,1)*alpha);
	  NMVM = normalMatrix(MVM);
	  sendModelViewNormalMatrix(curSS, MVM, NMVM);
	  safe_glUniform3f(curSS.h_uColor, g_objectColors[2][0], g_objectColors[2][1], g_objectColors[2][2]);
	  glPolygonMode( GL_FRONT_AND_BACK, GL_LINE);
	  g_arcBall->draw(curSS);
	  glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
  }
}