Example #1
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();
}
Example #2
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 );
  }
}
Example #3
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;
}
Example #4
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;
}