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"); //} }
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)); } } } }