void ModelBall::draw(QGLPainter *painter) { if (parent() && !visible()) { return; } painter->projectionMatrix().push(); painter->modelViewMatrix().push(); painter->modelViewMatrix() = transMat(); painter->modelViewMatrix().scale(scale()); foreach(QGLSceneNode *node, _nodes) { node->draw(painter); }
DenseMatrix DenseMatrix::Transpose(void) const { DenseMatrix transMat(mColNum, mRowNum, 0); for (int rid = 0; rid < mRowNum; rid++) { int rBaseIndex = rid * mColNum; for (int cid = 0; cid < mColNum; cid++) { transMat.at(cid, rid) = mValues.at(rBaseIndex + cid); } } return transMat; }
QMatrix4x4 P3P::getRegister(vector< Point3f > ObjPoints, vector< Point3f > estimatedPoints) { field< vec > objPts(3); field< vec > estPts(3); for (size_t i=0; i<3; ++i) { objPts(i).set_size(3); objPts(i)(0) = ObjPoints[i].x; objPts(i)(1) = ObjPoints[i].y; objPts(i)(2) = ObjPoints[i].z; } for (size_t i=0; i<3; ++i) { estPts(i).set_size(3); estPts(i)(0) = estimatedPoints[i].x; estPts(i)(1) = estimatedPoints[i].y; estPts(i)(2) = estimatedPoints[i].z; } estPts.print("P3P with LM Result:"); Reg3D A(objPts,estPts); mat44 homTransform = A.getTransformation(); QMatrix4x4 transMat(homTransform.at(0,0), homTransform.at(0,1), homTransform.at(0,2), homTransform.at(0,3), homTransform.at(1,0), homTransform.at(1,1), homTransform.at(1,2), homTransform.at(1,3), homTransform.at(2,0), homTransform.at(2,1), homTransform.at(2,2), homTransform.at(2,3), homTransform.at(3,0), homTransform.at(3,1), homTransform.at(3,2), homTransform.at(3,3)); return transMat; }
glm::mat4 Camera::CalcLookAtMatrix() { glm::vec3 lookDir = glm::normalize(camTarget - camPos); glm::vec3 upDir = glm::normalize(glm::vec3(upVector)); glm::vec3 rightDir = glm::normalize(glm::cross(lookDir, upDir)); glm::vec3 perpUpDir = glm::cross(rightDir, lookDir); glm::mat4 rotMat(1.0f); rotMat[0] = glm::vec4(rightDir, 0.0f); rotMat[1] = glm::vec4(perpUpDir, 0.0f); rotMat[2] = glm::vec4(-lookDir, 0.0f); rotMat = glm::transpose(rotMat); glm::mat4 transMat(1.0f); transMat[3] = glm::vec4(-camPos, 1.0f); return rotMat * transMat; }
glm::mat4 GraphicsSubsystem::calcLookAtMatrix(const glm::vec3 &cameraPt, const glm::vec3 &lookPt, const glm::vec3 &upPt) { glm::vec3 lookDir = glm::normalize(lookPt - cameraPt); glm::vec3 upDir = glm::normalize(upPt); glm::vec3 rightDir = glm::normalize(glm::cross(lookDir, upDir)); glm::vec3 perpUpDir = glm::cross(rightDir, lookDir); glm::mat4 rotMat(1.0f); rotMat[0] = glm::vec4(rightDir, 0.0f); rotMat[1] = glm::vec4(perpUpDir, 0.0f); rotMat[2] = glm::vec4(-lookDir, 0.0f); rotMat = glm::transpose(rotMat); glm::mat4 transMat(1.0f); transMat[3] = glm::vec4(-cameraPt, 1.0f); return rotMat * transMat; }
int draw(Scene& myScene) { unsigned char* img; img = (unsigned char*)tga_create(myScene.width, myScene.height, TGA_TRUECOLOR_24); int img_index = 0; for(int m = 0; m<myScene.height*myScene.width*3; m++) img[m]=0; for(int y = 0; y < myScene.height; y++) for(int x = 0; x < myScene.width; x++) { Ray viewRay; viewRay.o.x = x; viewRay.o.y = y; viewRay.o.z = -1000.0; viewRay.d.x = 0.0; viewRay.d.y = 0.0; viewRay.d.z = 1.0; viewRay.reflected = 0; float red = 0, green = 0, blue = 0; float coef = 1.0; int level = 0; int repeatFlag = 0; int lastfrontSphere = -1; int frontSphere = -1; int lastfrontTriangle = -1; int frontTriangle = -1; do{ Point inter; Point frontInter; float t_inter; Matrix iMat; Ray newviewRay; int triangleisFront, sphereisFront; int flag; if(repeatFlag==0) { int ret_val_trngl = 0; flag = 1; float t = 2000.0; frontSphere = -1; frontTriangle = -1; sphereisFront = 0; triangleisFront = 0; for(int i = 0; i<myScene.spheres.size(); i++) { if(myScene.spheres[i].transformed==0) { if(raySphere(viewRay, myScene.spheres[i], t)) { frontSphere = i; t_inter = t; } } else if(myScene.spheres[i].transformed==1) { if(lastfrontSphere!=i) { if(viewRay.reflected == 0) { Matrix temp_iMat = invMat(myScene.spheres[i].mat); Ray temp_newviewRay; temp_newviewRay.o = transformPoint(temp_iMat, viewRay.o); temp_newviewRay.o = subPoint(temp_newviewRay.o, myScene.spheres[i].tlate);// we have to sub since it is a inverse transform temp_newviewRay.d = transformPoint(temp_iMat, viewRay.d); ///////////////*doubt*why???//// if(raySphere(temp_newviewRay, myScene.spheres[i], t)) { frontSphere = i; iMat = temp_iMat; t_inter = t; newviewRay = temp_newviewRay; newviewRay.reflected = 0; } } else { Matrix temp_iMat = invMat(myScene.spheres[i].mat); if(raySphere(viewRay, myScene.spheres[i], t)) { frontSphere = i; iMat = temp_iMat; t_inter = t; newviewRay = viewRay; newviewRay.reflected = 0; } } } } } viewRay.reflected = 0; for(int i = 0; i<myScene.triangles.size(); i++) { ret_val_trngl = rayTriangle(viewRay, myScene.triangles[i], inter); if((ret_val_trngl==1)&&(lastfrontTriangle!=i)) { frontTriangle = i; frontInter = inter; } } if(frontSphere==-1) if(frontTriangle==-1) { flag = 0; triangleisFront = 0; sphereisFront = 0; break; } else { triangleisFront = 1; sphereisFront = 0; } if(frontSphere!=-1) if(frontTriangle==-1) { triangleisFront = 0; sphereisFront = 1; } else { triangleisFront = 1; sphereisFront = 1; } } repeatFlag = 0; if((sphereisFront==1)&&(triangleisFront==0)) { if(myScene.spheres[frontSphere].transformed==0) { Point tempo = multPoint(t_inter, viewRay.d); Point newStart = addPoint(viewRay.o, tempo); Point n = subPoint(newStart, myScene.spheres[frontSphere].c); float temp = multPoint(n, n); if (temp == 0.0f) break; temp = 1.0f / sqrtf(temp); n = multPoint(temp, n); //normal Material currentMat = myScene.materials[myScene.spheres[frontSphere].materialId]; for (int j = 0; j < myScene.lights.size(); j++) { Light light = myScene.lights[j]; Point dist = subPoint(light.pos, newStart); if (multPoint(n, dist) <= 0.0f) continue; float t = sqrtf(multPoint(dist, dist)); if ( t <= 0.0f ) continue; Ray lightRay; lightRay.o = newStart; lightRay.d = multPoint((1/t), dist); bool inShadow = false; for (int k = 0; k < myScene.spheres.size(); k++) { if (raySphere(lightRay, myScene.spheres[k], t)) { inShadow = true; break; } } if (!inShadow) { // lambert float lambert = multPoint(n, lightRay.d) * coef; red += lambert * light.col.r * currentMat.r; green += lambert * light.col.g * currentMat.g; blue += lambert * light.col.b * currentMat.b; } } coef *= currentMat.reflection; float reflet = 2.0f * multPoint(viewRay.d, n); viewRay.o = newStart; Point temp_2 = multPoint(reflet, n); viewRay.d = subPoint(viewRay.d, temp_2); viewRay.reflected = 0; level++; } else if (myScene.spheres[frontSphere].transformed==1) { Point tempo = multPoint(t_inter, newviewRay.d); Point newStart = addPoint(newviewRay.o, tempo); //intersection point in sphere space Point newStart_2 = transformPoint(myScene.spheres[frontSphere].mat, newStart);//intersection point in ellipsoid space newStart_2 = addPoint(newStart_2, myScene.spheres[frontSphere].tlate); Point n = subPoint(newStart, myScene.spheres[frontSphere].c); float temp = multPoint(n, n); if (temp == 0.0f) break; temp = 1.0f / sqrtf(temp); n = multPoint(temp, n); //convert normal to new worldspace Matrix iMat_2 = transMat(iMat); Point n_orig = n; n = transformPoint(iMat_2, n); Material currentMat = myScene.materials[myScene.spheres[frontSphere].materialId]; for (int j = 0; j < myScene.lights.size(); j++) { Light light = myScene.lights[j]; Point dist = subPoint(light.pos, newStart_2); if (multPoint(n, dist) <= 0.0f) continue; float t2 = sqrtf(multPoint(dist, dist)); if ( t2 <= 0.0f ) continue; Ray lightRay; lightRay.o = newStart_2; lightRay.d = multPoint((1/t2), dist); lightRay.reflected = 0; Point dist_temp = subPoint(light.pos, newStart); float t_temp = sqrtf(multPoint(dist_temp, dist_temp)); bool inShadow = false; Ray newlightRay; for (int k = 0; k < myScene.spheres.size(); k++) { newlightRay.o = newStart; newlightRay.d = transformPoint(iMat, lightRay.d); newlightRay.reflected = 0; if((k!=frontSphere) && (k!=lastfrontSphere)) if (raySphere(newlightRay, myScene.spheres[k], t_temp)) { inShadow = true; break; } } if (!inShadow) { // lambert float lambert = multPoint(n, lightRay.d) * coef; red += lambert * light.col.r * currentMat.r; green += lambert * light.col.g * currentMat.g; blue += lambert * light.col.b * currentMat.b; } } lastfrontSphere = frontSphere; coef *= currentMat.reflection; float reflet = 2.0f * multPoint(newviewRay.d, n_orig); viewRay.o = newStart_2; Point temp_2 = multPoint(reflet, n_orig); viewRay.d = subPoint(newviewRay.d, temp_2); viewRay.reflected = 1; level++; } } else if((sphereisFront==0)&&(triangleisFront==1)) { Point u_n = subPoint(myScene.triangles[frontTriangle].v1, frontInter); Point v_n = subPoint(myScene.triangles[frontTriangle].v2, frontInter); Point n = crossProduct(v_n, u_n); //pay attention here float temp = multPoint(n, n); if (temp == 0.0f) flag = 0; temp = 1.0f / sqrtf(temp); n = multPoint(temp, n); //normal Material currentMat = myScene.materials[myScene.triangles[frontTriangle].materialId]; for (int j = 0; j < myScene.lights.size(); j++) { Light light = myScene.lights[j]; Point dist = subPoint(light.pos, frontInter); if (multPoint(n, dist) <= 0.0f) continue; float t = sqrtf(multPoint(dist, dist)); if ( t <= 0.0f ) continue; Ray lightRay; lightRay.o = frontInter; lightRay.d = multPoint((1/t), dist); Point temp_inter; for (int k = 0; k < myScene.triangles.size(); k++) { if((k!=frontTriangle) && (k!=lastfrontTriangle)) if ((rayTriangle(lightRay, myScene.triangles[k], temp_inter)==1)) { flag = 0; break; } } if(flag == 1) { float lambert = multPoint(n, lightRay.d) * coef; red += lambert * light.col.r * currentMat.r; green += lambert * light.col.g * currentMat.g; blue += lambert * light.col.b * currentMat.b; } lastfrontTriangle = frontTriangle; //important } coef *= currentMat.reflection; float reflet = 2.0f * multPoint(viewRay.d, n); viewRay.o = frontInter; Point temp_2 = multPoint(reflet, n); viewRay.d = subPoint(viewRay.d, temp_2); viewRay.reflected = 1; level++; } else if((sphereisFront==1)&&(triangleisFront==1)) { Point tempo = multPoint(t_inter, viewRay.d); Point newStart = addPoint(viewRay.o, tempo); if(newStart.z <= frontInter.z) triangleisFront=0; else sphereisFront = 0; repeatFlag = 1; } }while((coef>0.0f)&&(level<10)); img[img_index] = (unsigned char)(min(red*255.0f, 255.0f)); img[img_index+1] = (unsigned char)(min(green*255.0f, 255.0f)); img[img_index+2] = (unsigned char)(min(blue*255.0f, 255.0f)); img_index = img_index+3; } int ret_value = tga_write_rle( "output3.tga", myScene.width, myScene.height, img, TGA_TRUECOLOR_24); return 1; }
void NewXZRotExperimentHCI::update(const std::vector<MinVR::EventRef> &events){ //later to be pass into closestTouchPair function glm::dvec3 pos1; glm::dvec3 pos2; double minDistance = DBL_MAX; MinVR::TimeStamp timestamp; //boolean flags bool xzTrans = false; glm::dmat4 xzTransMat = dmat4(0.0); bool yTrans = false; glm::dmat4 yTransMat = dmat4(0.0); bool yRotScale = false; numTouchForHand1 = 0; numTouchForHand2 = 0; //only update the map and other variables first for(int p = 0; p < events.size(); p++) { timestamp = events[p]->getTimestamp(); std::string name = events[p]->getName(); int id = events[p]->getId(); if (boost::algorithm::starts_with(name, "TUIO_Cursor_up")) { //delete the cursor down associated with this up event std::map<int, TouchDataRef>::iterator it = registeredTouchData.find(id); if (it != registeredTouchData.end()) { // if id is found registeredTouchData.erase(it); //erase value associate with that it //std::cout << "UP" <<std::endl; } else { std::cout<<"ERROR: Received touch up for a cursor not in the registered touch data!"<<std::endl; std::cout << events[p]->toString() << std::endl; for (auto iter = registeredTouchData.begin(); iter != registeredTouchData.end(); iter++) { std::cout << "\t" << iter->second->toString() << std::endl; } } } else if (boost::algorithm::starts_with(name, "TUIO_Cursor_down")) { // always add a new one on DOWN glm::dvec3 roomCoord = convertScreenToRoomCoordinates(events[p]->get2DData()); TouchDataRef datum(new TouchData(events[p], roomCoord)); registeredTouchData.insert(std::pair<int, TouchDataRef>(id, datum)); //std::cout << "DOWN " << glm::to_string(events[p]->get2DData()) <<std::endl; } else if (boost::algorithm::starts_with(name, "TUIO_CursorMove")) { //update the map with the move event // if the corresponding id was down, make it a move event std::map<int, TouchDataRef>::iterator it = registeredTouchData.find(id); //std::cout << "Move " << events[p]->getId() <<std::endl; if (it != registeredTouchData.end()) { // if id is found glm::dvec2 screenCoord (events[p]->get4DData()); glm::dvec3 roomCoord = convertScreenToRoomCoordinates(glm::dvec2(events[p]->get4DData())); // update map it->second->setCurrentEvent(events[p]); it->second->setCurrRoomPos(roomCoord); } } // end of TUIO events // Update hand positions if (name == "Hand_Tracker1") { //std::cout << "Inside hand tracking 1 event (xz) " << std::endl; //only enter one time to init prevHandPos1 if (prevHandPos1.y == -1.0) { glm::dvec3 currHandPos1 (events[p]->getCoordinateFrameData()[3]); prevHandPos1 = currHandPos1; initRoomPos = true; } else { //std::cout << "updating hand 1 curr and prev position " << std::endl; prevHandPos1 = currHandPos1; currHandPos1 = glm::dvec3(events[p]->getCoordinateFrameData()[3]); } } //std::cout<<"currHandPos1: "<<glm::to_string(currHandPos1)<<std::endl; //std::cout<<"prevHandPos1: "<<glm::to_string(prevHandPos1)<<std::endl; if(name == "Hand_Tracker2") { //std::cout << "Inside hand tracking 2 event (xz) " << std::endl; if (prevHandPos2.y == -1.0) { glm::dvec3 currHandPos2 (events[p]->getCoordinateFrameData()[3]); prevHandPos2 = currHandPos2; } else { //std::cout << "updating hand 2 curr and prev position " << std::endl; prevHandPos2 = currHandPos2; currHandPos2 = glm::dvec3(events[p]->getCoordinateFrameData()[3]); } } } // end of data-updating for loop // give feedback object the touch data so //it can draw touch positions feedback->registeredTouchData = registeredTouchData; // At this point, the touch data should be updated, and hand positions std::map<int, TouchDataRef>::iterator iter; for (iter = registeredTouchData.begin(); iter != registeredTouchData.end(); iter++) { glm::dvec3 currRoomPos (iter->second->getCurrRoomPos()); bool belongsToHand1 = (glm::length(currHandPos1 - currRoomPos) < glm::length(currHandPos2 - currRoomPos)); if (belongsToHand1) { numTouchForHand1++; if(iter->second->getBelongTo() == -1){ iter->second->setBelongTo(1); } } else { // belongs to hand 2 numTouchForHand2++; if(iter->second->getBelongTo() == -1){ iter->second->setBelongTo(2); } } } // end touch enumeration //from TUIO move //std::cout << "Touch size: " << registeredTouchData.size() << std::endl; //find closest pair of TouchPoints if (registeredTouchData.size() > 1) { closestTouchPair(registeredTouchData , pos1, pos2, minDistance); //std::cout << "Min distance: " << minDistance << std::endl; } if (minDistance < 0.06 && currHandPos1 != prevHandPos1) { xzRotFlag = true; //std::cout << "Inside XZRot Mode" << std::endl; } if (xzRotFlag && liftedFingers) { // might have to be xzRotFlag and not any other flag feedback->displayText = "rotating"; if(initRoomPos){ // pos1 and pos2 are where you put your fingers down. We're finding the centroid //to calculate the box boundary for xzRotMode initRoomTouchCentre = 0.5*(pos1 + pos2); initRoomPos = false; } // try to change around center of origin glm::dvec3 centOfRot (glm::dvec3((glm::column(cFrameMgr->getVirtualToRoomSpaceFrame(), 3)))); //calculate the current handToTouch vector if(registeredTouchData.size() > 1 && !centerRotMode) { roomTouchCentre = 0.5*(pos1 + pos2); } //std::cout << "Touch Center: " << glm::to_string(roomTouchCentre) << std::endl; //Should not be equal in XZRotMode but just in case. //for choosing the hand that rotates /*std::cout<<"currHandPos1: "<<glm::to_string(currHandPos1)<<std::endl;*/ if (numTouchForHand1 >= numTouchForHand2) { //std::cout << "Using right hand: " << std::endl; if (roomTouchCentre - currHandPos1 != glm::dvec3(0.0)) {//zero guard currHandToTouch = roomTouchCentre - currHandPos1; } if (roomTouchCentre - prevHandPos1 != glm::dvec3(0.0)) {//zero guard prevHandToTouch = roomTouchCentre - prevHandPos1; } } else { //std::cout << "Using Left hand: " << std::endl; if (roomTouchCentre - currHandPos2 != glm::dvec3(0.0)) { //zero guard currHandToTouch = roomTouchCentre - currHandPos2; } if (roomTouchCentre - prevHandPos2 != glm::dvec3(0.0)) { //zero guard prevHandToTouch = roomTouchCentre - prevHandPos2; } } //set up the 2 vertices for a square boundry for the gesture glm::dvec3 upRight = glm::dvec3(initRoomTouchCentre.x+0.2, 0.0, initRoomTouchCentre.z+0.2); glm::dvec3 lowLeft = glm::dvec3(initRoomTouchCentre.x-0.2, 0.0, initRoomTouchCentre.z-0.2); //this if-else block for setting xzRotFlag, //also for grabbing xzCentOfRot if(registeredTouchData.size() == 0) { //if no touch on screen then automatically exit the xzrot mode xzRotFlag = false; initRoomPos = true; liftedFingers = true; feedback->displayText = ""; feedback->centOfRot.x = DBL_MAX; //std::cout<<"no touchyyy so I quit"<<std::endl; } else { //if there are touch(s) then check if the touch is in bound of the rectangle bool setxzRotFlag = true; std::map<int, TouchDataRef>::iterator iter; int countFingers = 0; for (iter = registeredTouchData.begin(); iter != registeredTouchData.end(); iter++) { // not exactly sure why roomPos. > upRight.z , I think it should be <. but that doesn't work if(!(iter->second->getCurrRoomPos().x > upRight.x || iter->second->getCurrRoomPos().z > upRight.z ||iter->second->getCurrRoomPos().x < lowLeft.x ||iter->second->getCurrRoomPos().z < lowLeft.z)){ //you are in the box //std::cout << "fingers in bound so STILL IN XZRot Mode" << std::endl; setxzRotFlag = false; countFingers += 1; } //else{ // touch point not in box, assume as center of rotation // centOfRot = iter->second->getCurrRoomPos(); // centerRotMode = true; // //std::cout << "Cent of Rot set" << std::endl; // feedback->centOfRot = centOfRot; //} // only tries to change the xzRotFlag at the end of the data in the map if(iter == std::prev(registeredTouchData.end(),1) && setxzRotFlag) { xzRotFlag = false; initRoomPos = true; feedback->displayText = ""; feedback->centOfRot.x = DBL_MAX; //std::cout << "all fingers went out of bound so Out of XZRot Mode" << std::endl; // found bug where person just drags their fingers across the table, and it reinitiates xzRotMode liftedFingers = false; } } // end for loop over registeredTouchData if(countFingers == registeredTouchData.size()){//all fingers in bound centerRotMode = false; feedback->centOfRot.x = DBL_MAX; } } // end if/else block //std::cout<<"currHandToTouch: "<<glm::to_string(currHandToTouch)<<std::endl; //std::cout<<"prevHandToTouch: "<<glm::to_string(prevHandToTouch)<<std::endl; //std::cout<<"dot product of them: "<< glm::to_string(glm::dot(glm::normalize(currHandToTouch), glm::normalize(prevHandToTouch))) << std::endl; //std::cout<<"what we clamping: "<<glm::clamp(glm::dot(currHandToTouch, prevHandToTouch),-1.0,1.0)<<std::endl; double alpha = glm::acos(glm::clamp(glm::dot(glm::normalize(currHandToTouch), glm::normalize(prevHandToTouch)),-1.0,1.0)); // from 0 to pi //std::cout<<"alpha: " << alpha << std::endl; // get cross prod glm::dvec3 cross = glm::normalize(glm::cross(currHandToTouch, prevHandToTouch)); //std::cout<<"cross: "<<glm::to_string(cross)<<std::endl; glm::dvec3 projCross = glm::normalize(glm::dvec3(cross.x, 0.0, cross.z)); // projection //std::cout<<"projcross: "<<glm::to_string(projCross)<<std::endl; // project cross prod onto the screen, get a length double lengthOfProjection = glm::dot(cross, projCross); //std::cout<<"lengthOfProjection: "<<glm::to_string(lengthOfProjection)<<std::endl; // projected cross prod //glm::dvec3 projectedCrossProd = lengthOfProjection * normProjCross; //std::cout<<"lengthOfProjection: "<<lengthOfProjection<<std::endl; //std::cout<<"alpha in degree before times lengthofprojection: "<<glm::degrees(alpha)<<std::endl; alpha = alpha * lengthOfProjection; //std::cout<<"alpha in degree after: "<<glm::degrees(alpha)<<std::endl; //std::cout<<"normProjCross: "<<glm::to_string(normProjCross)<<std::endl; glm::dmat4 XZRotMat = glm::rotate(glm::dmat4(1.0), glm::degrees(alpha) /* * 2.0 */, glm::normalize(projCross)); // have translations when we have a touch point not in the bounding box // translate to origin glm::dmat4 transMat(glm::translate(glm::dmat4(1.0), -1.0*centOfRot)); //translate back glm::dmat4 transBack(glm::translate(glm::dmat4(1.0), centOfRot)); //put it into the matrix stack //std::cout<<"XZRotMat: "<<glm::to_string(XZRotMat) <<std::endl; cFrameMgr->setRoomToVirtualSpaceFrame(cFrameMgr->getRoomToVirtualSpaceFrame() * transBack * XZRotMat * transMat); } // end xzRot Gesture if(registeredTouchData.size() == 0) { feedback->displayText = ""; liftedFingers = true; } //this is bret's commented out line //updateHandPos(events); }
void NewAnchoredExperimentHCI::yRotationAndScale(TouchDataRef centOfRotData, TouchDataRef roomCoordData) { // have to do calculations, switching between both touch points // translate to origin glm::dmat4 transMat(glm::translate(glm::dmat4(1.0), -1.0*centOfRotData->getCurrRoomPos())); glm::dmat4 rotMat = glm::dmat4(1.0); glm::dmat4 scaleMat = glm::dmat4(1.0); // movement of touch point is above threshold if(glm::abs(glm::length(roomCoordData->getPrevRoomPos()) - glm::length(roomCoordData->getCurrRoomPos())) > THRESH) { //std::cout<<"using the filtered pos in rotate and scale"<<std::endl; // rotate //// 0 vector guard glm::dvec3 prevDiffBetweenTwoPoints; if (glm::length(roomCoordData->getPrevRoomPos() - centOfRotData->getCurrRoomPos()) > 0.0) { prevDiffBetweenTwoPoints = glm::normalize(roomCoordData->getPrevRoomPos() - centOfRotData->getCurrRoomPos()); // "it" is the current thing through the for loop below } //// 0 vector guard glm::dvec3 currDiffBetweenTwoPoints; if (glm::length(roomCoordData->getCurrRoomPos() - centOfRotData->getCurrRoomPos()) > 0.0) { currDiffBetweenTwoPoints = glm::normalize(roomCoordData->getCurrRoomPos() - centOfRotData->getCurrRoomPos()); } // both distances are normalized glm::dvec3 crossProd = glm::cross(prevDiffBetweenTwoPoints,currDiffBetweenTwoPoints); double theta = glm::acos(glm::dot(prevDiffBetweenTwoPoints,currDiffBetweenTwoPoints)); if(crossProd.y < 0){ theta = -theta; } //std::cout << "Rotation Angle Theta: " << theta << std::endl; // glm::rotate takes degrees! Madness. rotMat = glm::rotate(glm::dmat4(1.0) , glm::degrees(-theta), glm::dvec3(0.0, 1.0, 0.0)); // scale double prevDistanceDiff = glm::length(roomCoordData->getPrevRoomPos() - centOfRotData->getCurrRoomPos()); double currDistanceDiff = glm::length(roomCoordData->getCurrRoomPos() - centOfRotData->getCurrRoomPos()); //std::cout << prevDistanceDiff/currDistanceDiff << std::endl; // might move this into a more general function // to test for crazy input /*if (glm::dvec3(prevDistanceDiff/currDistanceDiff)) { }*/ glm::dvec3 scaleBy = glm::dvec3(prevDistanceDiff/currDistanceDiff); scaleMat = glm::scale( glm::dmat4(1.0), scaleBy); } // translate back glm::dmat4 transBack(glm::translate(glm::dmat4(1.0), centOfRotData->getCurrRoomPos())); // combine transforms glm::dmat4 yRotScaleMat = cFrameMgr->getRoomToVirtualSpaceFrame() * transBack * scaleMat *rotMat * transMat; cFrameMgr->setRoomToVirtualSpaceFrame(yRotScaleMat); }