Exemplo n.º 1
0
void SpaceShip::setAcc(float yacc, float pacc, float roll)
{
	m_accquat = anglesToQuat(SimpleAngles(yacc, pacc, 0));

	// Create the Quaternion from upvector and upvector with roll
	glm::quat rollquat = RotationBetweenVectors(
		SimpleVec3d(0, 1, 0),
		SimpleVec3d(SimpleAngles(PI/2, PI/2 - roll, 0))
	);

	// Apply rotation Quaternion (rollquat) to look Quaternion
	m_accquat *= rollquat;
}
void NGLScene::paintGL()
{

    if(testangle==89)
        vary=-1;

    if(testangle==-89)
        vary=1;

//This bit has been  MOVED TO TIMER EVENT for more 'slow-motion' control
//    testangle+=vary;
    std::cout<<testangle<<std::endl;

    ngl::Vec3 v1(-5+15*sin((testangle)*(M_PI/180))-2,-5+15*sin((testangle)*(M_PI/180)),  4*sin((testangle)*(M_PI/180))-2);
    ngl::Vec3 v2(-4,0.01,-5+15*sin((testangle)*(M_PI/180)));//transform the triangle vao to 2,2,0

      ngl::Vec3 v2NonNormalized=v2;
      ngl::Vec3 v1NonNormalized=v1;


  // clear the screen and depth buffer
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  // Rotation based on the mouse position for our global transform

  // Rotation based on the mouse position for our global
  // transform
  ngl::Mat4 rotX;
  ngl::Mat4 rotY;
  // create the rotation matrices
  rotX.rotateX(m_spinXFace);
  rotY.rotateY(m_spinYFace);
  // multiply the rotations
  m_mouseGlobalTX=rotY*rotX;
  // add the translations
  m_mouseGlobalTX.m_m[3][0] = m_modelPos.m_x;
  m_mouseGlobalTX.m_m[3][1] = m_modelPos.m_y;
  m_mouseGlobalTX.m_m[3][2] = m_modelPos.m_z;


  ngl::ShaderLib *shader=ngl::ShaderLib::instance();
  (*shader)["Phong"]->use();
  ngl::Material m(ngl::STDMAT::PEWTER);
  // load our material values to the shader into the structure material (see Vertex shader)
  m.loadToShader("material");

  ngl::Mat4 MV;
  ngl::Mat4 MVP;
  ngl::Mat3 normalMatrix;
  ngl::Mat4 M;


  //*********
  m_transform.reset();
  //draw box
  {
      m_transform.setPosition(v1NonNormalized);
      M=m_transform.getMatrix()*m_mouseGlobalTX;
      MV=  M*m_cam->getViewMatrix();
      MVP= M*m_cam->getVPMatrix();
      normalMatrix=MV;
      normalMatrix.inverse();
      shader->setShaderParamFromMat4("MV",MV);
      shader->setShaderParamFromMat4("MVP",MVP);
      shader->setShaderParamFromMat3("normalMatrix",normalMatrix);
      shader->setShaderParamFromMat4("M",M);


      //ngl::VAOPrimitives::instance()->draw("cube");
      m_vao2->bind();
      m_vao2->draw();
      m_vao2->unbind();

  }


    v1.normalize();
    v2.normalize();
    float angle = /*atan2(v1.m_y,v1.m_x) - atan2(v2.m_y,v2.m_x);//*/acos(v1.dot(v2));

    ngl::Vec3 rotationAxis = v1.cross(v2);
    rotationAxis.normalize();

//    ngl::Quaternion q ;
//    q.fromAxisAngle(rotationAxis,angle);

    ngl::Mat4 s,rotateMat,translateMat;
    s=1;

    //Use either RotationBetweenVectors or matrixFromAxisAngle
    rotateMat=RotationBetweenVectors(v2,v1).toMat4();
    //rotateMat=matrixFromAxisAngle(rotationAxis,angle);//q.toMat4();


    //calculate euler angles from axis-angle
//    double heading,attitude,bank;
//    toEuler(rotationAxis.m_x, rotationAxis.m_y, rotationAxis.m_z, angle, heading, attitude, bank);

//    m_transform.reset();
//    std::cout<<bank*(180/M_PI)<<","<<heading*(180/M_PI)<<","<<attitude*(180/M_PI)<<","<<std::endl;
//    m_transform.setRotation(bank*(180/M_PI),heading*(180/M_PI),attitude*(180/M_PI));
//    r= m_transform.getMatrix();

    m_transform.reset();
    m_transform.setPosition(v2NonNormalized);
    translateMat= m_transform.getMatrix();

    ngl::Mat4 modelmatrix=s*rotateMat*translateMat;

  m_transform.reset();
  //draw triangle
  {
      //    load our material values to the shader into the structure material (see Vertex shader)
      m.set(ngl::STDMAT::BRONZE);
      m.loadToShader("material");

      M=/*m_transform.getMatrix()*/  modelmatrix*m_mouseGlobalTX;
      MV=  M*m_cam->getViewMatrix();
      MVP= M*m_cam->getVPMatrix();
      normalMatrix=MV;
      normalMatrix.inverse();
      shader->setShaderParamFromMat4("MV",MV);
      shader->setShaderParamFromMat4("MVP",MVP);
      shader->setShaderParamFromMat3("normalMatrix",normalMatrix);
      shader->setShaderParamFromMat4("M",M);


//      ngl::VAOPrimitives::instance()->draw("cube");
      m_vao->bind();
      m_vao->draw();
      m_vao->unbind();

   }



//    //draw the tip-cube of the triangle
//  {
//    m.set(ngl::GOLD);
//    // load our material values to the shader into the structure material (see Vertex shader)
//    m.loadToShader("material");

//    translateMat=1;

//  //  rotateMat=1;
//  //  scaleMat=1;

//  //not working
//  //  ngl::Vec3 v=v1.cross(v2);
//  //  float c=v1.dot(v2);
//  //  float h=1-c/v.dot(v);
//  //  rotateMat=ngl::Mat4(c*h*v.m_x*v.m_x,                 h*v.m_x*v.m_y-v.m_z,           h*v.m_x*v.m_z+v.m_y, 1,
//  //                      h*v.m_x*v.m_y+v.m_z,             c+h*v.m_y*v.m_y,               h*v.m_y*v.m_z-v.m_x, 1,
//  //                      h*v.m_x*v.m_z-v.m_y,       h*v.m_y*v.m_z+v.m_x,                c+h*v.m_z*v.m_z,      1,
//  //                      0 ,                            0 ,                                     0,            1);
//  //  rotateMat.transpose();
//  //not working



//  //     ngl::Mat4 trs=m_transform.getMatrix();
//  //     rotateMat=matrixFromAxisAngle(rotationAxis,angle);
//  //     translateMat.translate(-v2NonNormalized.m_x,-(v2NonNormalized.m_y),-v2NonNormalized.m_z);

//    //Based on [R] = [T].inverse * [R0] * [T] //http://www.euclideanspace.com/maths/geometry/affine/aroundPoint/
//    /*
//      translate the arbitrary point to the origin (subtract P which is translate by -Px,-Py,-Pz)
//      rotate about the origin (can use 3×3 matrix R0)
//      then translate back. (add P which is translate by +Px,+Py,+Pz)
//    */
//       translateMat.inverse();//step 1.. translate pointToRotate to origin

//       //(rotation matrix) - same as the triangle's "rotateMat" //step 2 rotate..

//       translateMat2.translate(v2NonNormalized.m_x,(v2NonNormalized.m_y),v2NonNormalized.m_z);//step3 ..translate pointToRotate back to its original position in 3d space

//       std::cout<<translateMat2.m_30<<","<<translateMat2.m_31<<","<<translateMat2.m_32<<std::endl;



//  //     std::cout<<"mat Matrix():\n"<<"  "<<rotateMat.m_00<<"  "<< rotateMat.m_01<<"  "<<rotateMat.m_02 <<"  "<<rotateMat.m_03<<"  "<<
//  //                                    rotateMat.m_10<<"  "<< rotateMat.m_11<<"  "<<rotateMat.m_12 <<"  "<<rotateMat.m_13<<"  "<< rotateMat.m_20<<"  "<< rotateMat.m_21<<"  "<<rotateMat.m_22 <<"  "<<rotateMat.m_23<<"  "<< rotateMat.m_30<<"  "<<
//  //                                    rotateMat.m_31<<"  "<<rotateMat.m_32 <<"  "<<rotateMat.m_33<<"  "<<std::endl;

//  //     std::cout<<angle<<std::endl;

//       //place one one sphere-primitive in the tip of the triangle, but we translate first and then rotate (this effectively shows the "trajectory of the triangle rotation")

//       /*
//        * In order to calculate the rotation about any arbitrary point we need to calculate its new rotation and translation.
//        * In other words rotation about a point is an 'proper' isometry transformation' which means that it has a linear
//        *  and a rotational component.
//        * [resulting transform] = [+Px,+Py,+Pz] * [rotation] * [-Px,-Py,-Pz]
//        */


//        M=  translateMat*rotateMat*translateMat2 /**scaleMat*/; //in ngl multiplication happens from left to right

//        M= M*m_mouseGlobalTX;
//        MV=  M*m_cam->getViewMatrix();
//        MVP= M*m_cam->getVPMatrix();
//        normalMatrix=MV;
//        normalMatrix.inverse();
//        shader->setShaderParamFromMat4("MV",MV);
//        shader->setShaderParamFromMat4("MVP",MVP);
//        shader->setShaderParamFromMat3("normalMatrix",normalMatrix);
//        shader->setShaderParamFromMat4("M",M);

////        ngl::VAOPrimitives::instance()->createSphere("mysphere",0.1,10);

//        ngl::VAOPrimitives::instance()->draw("cube");

//  }















//  //*********NOW********* STEP 2
//  //Calculate rotation vector from 2nd to 1st triangle
//  //then

//  m.set(ngl::BRONZE);
//  // load our material values to the shader into the structure material (see Vertex shader)
//  m.loadToShader("material");

//  //... rotate and draw the 2nd triangle as well
//  m_transform.reset();
//  {

////------------------------------------------------------------------------------------------------------------------------------------
////------------------------------------------------------------------------------------------------------------------------------------
///**************
////not working
////     eulerAngles.m_x = atan2( rotationAxis.m_y, rotationAxis.m_z );
////     if (rotationAxis.m_z >= 0) {
////        eulerAngles.m_y = -atan2( rotationAxis.m_x * cos(eulerAngles.m_x), rotationAxis.m_z );
////     }else{
////        eulerAngles.m_y = atan2( rotationAxis.m_x * cos(eulerAngles.m_x), -rotationAxis.m_z );
////     }

////     eulerAngles.m_z = atan2( cos(eulerAngles.m_x), sin(eulerAngles.m_x) * sin(eulerAngles.m_y) );


//     //
////     eulerAngles.m_x= 0;
////     eulerAngles.m_y = atan2((v1-v2).m_x, (v1-v2).m_z);
////     float padj = sqrt(pow((v1-v2).m_x, 2) + pow((v1-v2).m_z, 2));
////     eulerAngles.m_y = atan2(padj, (v1-v2).m_y) ;

//  **************/
//     //convert axis anle to euler angles
////     toEuler(rotationAxis.m_x, rotationAxis.m_y, rotationAxis.m_z, angle);
////     m_transform.setRotation(eulerAngles.m_x*(180/M_PI),eulerAngles.m_y*(180/M_PI),eulerAngles.m_z*(180/M_PI));
//       ngl::Mat4 trs=m_transform.getMatrix();
////------------------------------------------------------------------------------------------------------------------------------------
////------------------------------------------------------------------------------------------------------------------------------------



//    //The following work with ngl::Transformation too, as well as with individual matrices
//    //       m_transform.reset();
//    //       if(testangle<360)
//    //           testangle++;
//    //       else
//    //       {
//    //           testangle=0;
//    //       }

//    //       m_transform.setRotation(testangle,0,0);

//    //Rotate based where v1 is (make v2NonNormalized(triangle) to point towards v1-cube)
//     rotateMat=matrixFromAxisAngle(rotationAxis,angle);//m_transform.getMatrix();
//     translateMat.translate(v2NonNormalized.m_x,v2NonNormalized.m_y,v2NonNormalized.m_z);


////     std::cout<<"mat Matrix():\n"<<"  "<<rotateMat.m_00<<"  "<< rotateMat.m_01<<"  "<<rotateMat.m_02 <<"  "<<rotateMat.m_03<<"  "<<
////                                    rotateMat.m_10<<"  "<< rotateMat.m_11<<"  "<<rotateMat.m_12 <<"  "<<rotateMat.m_13<<"  "<< rotateMat.m_20<<"  "<< rotateMat.m_21<<"  "<<rotateMat.m_22 <<"  "<<rotateMat.m_23<<"  "<< rotateMat.m_30<<"  "<<
////                                    rotateMat.m_31<<"  "<<rotateMat.m_32 <<"  "<<rotateMat.m_33<<"  "<<std::endl;
////     std::cout<<angle<<std::endl;




////not quite working
//        float norm_u_norm_v = sqrt(v2NonNormalized.lengthSquared() * v1NonNormalized.lengthSquared());
//        ngl::Vec3 w = v2.cross(v1);
//        ngl::Quaternion q = ngl::Quaternion(norm_u_norm_v + v2NonNormalized.dot(v1NonNormalized), w.m_x, w.m_y, w.m_z);
//        q.normalise();
//        rotateMat=q.toMat4();

////not quite working either
//     rotateMat=ngl::lookAt(v2NonNormalized,v1NonNormalized,ngl::Vec3(0,1,0));



//      M=rotateMat*translateMat;//left to right multiplication in ngl (first rotate then translate)

//      M=/*m_transform.getMatrix()*/ M/* trs*/*m_mouseGlobalTX;
//      MV=  M*m_cam->getViewMatrix();
//      MVP= M*m_cam->getVPMatrix();
//      normalMatrix=MV;
//      normalMatrix.inverse();
//      shader->setShaderParamFromMat4("MV",MV);
//      shader->setShaderParamFromMat4("MVP",MVP);
//      shader->setShaderParamFromMat3("normalMatrix",normalMatrix);
//      shader->setShaderParamFromMat4("M",M);


//      m_vao->bind();
//      m_vao->draw();//draw triangle now
//      m_vao->unbind();
//  }


//  //*********NOW********* STEP 3

//  //draw the tip-cube of the triangle
//{
//  m.set(ngl::GOLD);
//  // load our material values to the shader into the structure material (see Vertex shader)
//  m.loadToShader("material");

//  translateMat=1;

////  rotateMat=1;
////  scaleMat=1;

////not working
////  ngl::Vec3 v=v1.cross(v2);
////  float c=v1.dot(v2);
////  float h=1-c/v.dot(v);
////  rotateMat=ngl::Mat4(c*h*v.m_x*v.m_x,                 h*v.m_x*v.m_y-v.m_z,           h*v.m_x*v.m_z+v.m_y, 1,
////                      h*v.m_x*v.m_y+v.m_z,             c+h*v.m_y*v.m_y,               h*v.m_y*v.m_z-v.m_x, 1,
////                      h*v.m_x*v.m_z-v.m_y,       h*v.m_y*v.m_z+v.m_x,                c+h*v.m_z*v.m_z,      1,
////                      0 ,                            0 ,                                     0,            1);
////  rotateMat.transpose();
////not working



////     ngl::Mat4 trs=m_transform.getMatrix();
////     rotateMat=matrixFromAxisAngle(rotationAxis,angle);
////     translateMat.translate(-v2NonNormalized.m_x,-(v2NonNormalized.m_y),-v2NonNormalized.m_z);

//  //Based on [R] = [T].inverse * [R0] * [T] //http://www.euclideanspace.com/maths/geometry/affine/aroundPoint/
//  /*
//    translate the arbitrary point to the origin (subtract P which is translate by -Px,-Py,-Pz)
//    rotate about the origin (can use 3×3 matrix R0)
//    then translate back. (add P which is translate by +Px,+Py,+Pz)
//  */
//     translateMat.inverse();//step 1.. translate pointToRotate to origin

//     //(rotation matrix) - same as the triangle's "rotateMat" //step 2 rotate..

//     translateMat2.translate(v2NonNormalized.m_x,(v2NonNormalized.m_y),v2NonNormalized.m_z);//step3 ..translate pointToRotate back to its original position in 3d space

//     std::cout<<translateMat2.m_30<<","<<translateMat2.m_31<<","<<translateMat2.m_32<<std::endl;



////     std::cout<<"mat Matrix():\n"<<"  "<<rotateMat.m_00<<"  "<< rotateMat.m_01<<"  "<<rotateMat.m_02 <<"  "<<rotateMat.m_03<<"  "<<
////                                    rotateMat.m_10<<"  "<< rotateMat.m_11<<"  "<<rotateMat.m_12 <<"  "<<rotateMat.m_13<<"  "<< rotateMat.m_20<<"  "<< rotateMat.m_21<<"  "<<rotateMat.m_22 <<"  "<<rotateMat.m_23<<"  "<< rotateMat.m_30<<"  "<<
////                                    rotateMat.m_31<<"  "<<rotateMat.m_32 <<"  "<<rotateMat.m_33<<"  "<<std::endl;

////     std::cout<<angle<<std::endl;

//     //place one one sphere-primitive in the tip of the triangle, but we translate first and then rotate (this effectively shows the "trajectory of the triangle rotation")

//     /*
//      * In order to calculate the rotation about any arbitrary point we need to calculate its new rotation and translation.
//      * In other words rotation about a point is an 'proper' isometry transformation' which means that it has a linear
//      *  and a rotational component.
//      * [resulting transform] = [+Px,+Py,+Pz] * [rotation] * [-Px,-Py,-Pz]
//      */


//      M=  translateMat*rotateMat*translateMat2 /**scaleMat*/; //in ngl multiplication happens from left to right

//      M= M*m_mouseGlobalTX;
//      MV=  M*m_cam->getViewMatrix();
//      MVP= M*m_cam->getVPMatrix();
//      normalMatrix=MV;
//      normalMatrix.inverse();
//      shader->setShaderParamFromMat4("MV",MV);
//      shader->setShaderParamFromMat4("MVP",MVP);
//      shader->setShaderParamFromMat3("normalMatrix",normalMatrix);
//      shader->setShaderParamFromMat4("M",M);

//      ngl::VAOPrimitives::instance()->createSphere("mysphere",0.1,10);

//      ngl::VAOPrimitives::instance()->draw("cube");

//}



}
Exemplo n.º 3
0
void SpaceShip::processKeys(bool keystate[255], bool keystate_special[255], float dtime)
{
	float yacc = 0;
	float pacc = 0;
	float racc = 0;

	// Special Keys:
	if (keystate_special[GLUT_KEY_DOWN])
		pacc += SPACESHIP_ROTACC;

	if (keystate_special[GLUT_KEY_UP])
		pacc -= SPACESHIP_ROTACC;

	if (keystate_special[GLUT_KEY_LEFT])
		yacc -= SPACESHIP_ROTACC;

	if (keystate_special[GLUT_KEY_RIGHT])
		yacc += SPACESHIP_ROTACC;

	if (keystate[(uint8_t)'x'])
		racc += SPACESHIP_ROTACC;

	if (keystate[(uint8_t)'y'])
		racc -= SPACESHIP_ROTACC;

	if (keystate_special[GLUT_KEY_PAGE_UP])
	{
		// Forward
		m_engine_acc = quatToVector(m_quat)
			* config->getDouble("spaceship_acceleration", 100.0) * USC; // 100km/s^2
		if (!m_engine_running) // powering on
		{
			m_audio.stop();
			m_audio.addFile("spaceship_start.ogg");
			m_audio.setLoop(AL_FALSE);
			m_audio.play();
		}
		m_time_since_acc = 0;
		m_engine_running = true;
	}
	else
	{
		if (m_engine_running) // powering down
		{
			m_audio.stop();
			m_audio.addFile("spaceship_stop.ogg");
			m_audio.setLoop(AL_FALSE);
			m_audio.play();
		}
		m_engine_acc = SimpleVec3d();
		m_engine_running = false;
	}

	if (keystate_special[GLUT_KEY_PAGE_DOWN])
	{
		// Make the spaceship rotate into the opposite direction of the velocity
		glm::quat targetquat = RotationBetweenVectors(SimpleVec3d(0, 0, 1), m_velocity);
		m_quat = glm::normalize(m_quat);
		targetquat = glm::normalize(targetquat);

		if (game->getGameSpeed() > 15.0)
		{
			m_quat = targetquat;
			m_velquat = glm::quat();
		}
		else
		{
			m_quat = glm::slerp(m_quat, targetquat,
				(float)(dtime / SPACESHIP_ALIGN_TIME));
			m_velquat = glm::slerp(glm::quat(), m_velquat,
				(float)(1.0 / SPACESHIP_ROTBREAK_TIME));
		}
	}

	setAcc(yacc, pacc, racc);

	if (keystate[(uint8_t)'c']) // break rotation, stop if gamespeed > 15
	{
		if (game->getGameSpeed() > 15.0)
			m_velquat = glm::quat();
		else
			m_accquat = glm::slerp(glm::quat(), conjugateQuat(m_velquat),
				(float)(1.0 / SPACESHIP_ROTBREAK_TIME));
	}

	if (keystate[(uint8_t)'b'])
	{
		if (m_navigator->getActive())
		{
			// Align to Navigation target
			glm::quat targetquat = m_navigator->getTargetQuat();
			if (game->getGameSpeed() > 15.0)
			{
				m_quat = targetquat;
				m_velquat = glm::quat();
			}
			else
			{
				m_quat = glm::slerp(m_quat, targetquat,
					(float)(dtime / SPACESHIP_ALIGN_TIME));
				m_velquat = glm::slerp(glm::quat(), m_velquat,
					(float)(1.0 / SPACESHIP_ROTBREAK_TIME));
			}
		}
	}
}