void ToricInterpolator::interpolateVector( const double & t, Vector3 & pOutVecA, Vector3 & pOutVecB ) { { pOutVecA = Quaternion(Vector3::WorldUp(), m_infoA.viewAngleChange * t) * m_infoA.startVector; pOutVecA = Quaternion(pOutVecA ^ Vector3::WorldUp(), m_infoA.viewHeightChange * t) * pOutVecA; } { pOutVecB = Quaternion(Vector3::WorldUp(), m_infoB.viewAngleChange * t) * m_infoB.startVector; pOutVecB = Quaternion(pOutVecB ^ Vector3::WorldUp(), m_infoB.viewHeightChange * t) * pOutVecB; } Vector3 vecAB = m_wposB-m_wposA; double AB = vecAB.norm(); double alpha = m_alpha[0] * (1-t) + m_alpha[1] * t; double PiMinusAlpha = PI-alpha; double transform = PI / PiMinusAlpha; double dA; { double dA1 = m_infoA.distance[0] * (1-t) + m_infoA.distance[1] * t; double beta = pOutVecA.angle(vecAB)(); beta = clamp(beta, 0.0, PiMinusAlpha); double dA2 = Constraints::ComputeDistanceToA(AB, alpha, beta*2); double wA2 = EaseInOut( sin( beta * transform ) ); dA = (dA1 + dA2 * wA2) / (1 + wA2); } double dB; { double dB1 = m_infoB.distance[0] * (1-t) + m_infoB.distance[1] * t; double beta = pOutVecB.angle(-vecAB)(); beta = clamp(beta, 0.0, PiMinusAlpha); double dB2 = Constraints::ComputeDistanceToA(AB, alpha, beta*2); double wB2 = EaseInOut( sin( beta * transform ) ); dB = (dB1 + dB2 * wB2) / (1 + wB2); } pOutVecA *= dA; pOutVecB *= dB; }
void Vector3::interpolateDirection(const Vector3 &u,const Vector3 &v,double t) { // TODO : heavy computation Vector3 axis=p3d::cross(u,v); Quaternion q; if (axis.length()<0.00001) q.setIdentity(); else { double angle=u.angle(v,u.cross(v)); angle*=t; q=Quaternion::fromAngleAxis(toDegree(angle),axis); } double ilength=(1.0-t)*u.length()+t*v.length(); Vector3 uu=u; uu.normalize(); *this=(q*uu)*ilength; }
void Window::mouseMotion(int x, int y) { Matrix4 xyTrans, zTrans; Matrix4 scale, rotate; Vector3 axis; Vector3 currentPoint; Vector3 point; float rotateAngle = 0.0; currentPoint = trackBallMapping(Window::width, Window::height, mouseX, mouseY); if (leftClick) { //Exaggerate elevation if (mouseX < 100) { //If mouse moves up, increase scale if (currentPoint[1] > lastPoint[1]) Globals::elevationScale += ELEVATION_SCALE; //If mouse moves down, decrease scale else if (currentPoint[1] < lastPoint[1]) { if (Globals::elevationScale >= 0.0) Globals::elevationScale -= ELEVATION_SCALE; if (Globals::elevationScale < 0) Globals::elevationScale = 0; } //Update positions Globals::recalcNorms = true; lastPoint = currentPoint; mouseX = x; mouseY = y; } else if (mouseX > width - 100) { //If mouse moves up, increase scale if (currentPoint[1] > lastPoint[1]) Globals::currWater += WATER_SCALE; //If mouse moves down, decrease scale else if (currentPoint[1] < lastPoint[1]) { if (Globals::currWater >= 0) Globals::currWater -= WATER_SCALE; if (Globals::currWater < 0) Globals::currWater = 0; } //Update positions lastPoint = currentPoint; mouseX = x; mouseY = y; } else { axis = lastPoint.cross(currentPoint); rotateAngle = lastPoint.angle(currentPoint); rotate = rotate.makeRotateArbitrary(axis, rotateAngle); bleh = rotate * bleh; lastPoint = currentPoint; mouseX = x; mouseY = y; } } else if (rightClick) { //Exaggerate elevation if (mouseX < 100) { //If mouse moves up, increase scale if (currentPoint[1] > lastPoint[1]) Globals::elevationScale += ELEVATION_SCALE; //If mouse moves down, decrease scale else if (currentPoint[1] < lastPoint[1]) { if (Globals::elevationScale >= 0.0) Globals::elevationScale -= ELEVATION_SCALE; if (Globals::elevationScale < 0) Globals::elevationScale = 0; } //Update positions Globals::recalcNorms = true; lastPoint = currentPoint; mouseX = x; mouseY = y; } else if (mouseX > width - 100) { //If mouse moves up, increase scale if (currentPoint[1] > lastPoint[1]) Globals::currWater += WATER_SCALE; //If mouse moves down, decrease scale else if (currentPoint[1] < lastPoint[1]) { if (Globals::currWater >= 0.0) Globals::currWater -= WATER_SCALE; } //Update positions lastPoint = currentPoint; mouseX = x; mouseY = y; } else { //Translate along z axis if (zoom) { point = lastPoint - currentPoint; point = point.scale(9.0); zTrans.makeTranslate(0, 0, point[1]); meh = zTrans * meh; lastPoint = currentPoint; mouseX = x; mouseY = y; } //Translate along x / y axis else { point = currentPoint - lastPoint; point = point.scale(50.0); xyTrans.makeTranslate(point[0], point[1], 0); meh = xyTrans * meh; lastPoint = currentPoint; mouseX = x; mouseY = y; } } } }
bool Asteroid::update() { toWorld = translation * toWorld; float x = toWorld.m[3][0]; float y = toWorld.m[3][1]; float z = toWorld.m[3][2]; if (x < -251 || x > 251 || y < -251 || y > 251 || z < -251 || z > 251) { return false; } SolarSystem * solar = &Globals::solarSystem; for (list<SolarPlanet*>::iterator it = solar->planets.begin(); it != solar->planets.end(); it++) { Matrix4 newToWorld; Vector3 newPoint; Vector3 newDiff; SolarPlanet* planet = (*it); Vector3 pos = planet->position; Vector3 asteroid_pos = toWorld.getTranslate().toVector3(); Vector3 diff = asteroid_pos - pos; float mag = diff.magnitude(); if(!collided){ if (mag < planet->radius) { planet->changeColor(); collided = true; unsigned long range = 268435455; float genSeed = ((float)rand() / (float)RAND_MAX) * range; gShape = new GShape((unsigned long)genSeed); Vector4 dir = toWorld.getTranslate() - pos.toVector4(0); Vector3 newDir = dir.toVector3(); Vector3 face = Vector3(0, 0, 1); float angle = face.angle(newDir); Vector3 axis = face.cross(newDir).normalize(); Matrix4 rot; rot = rot.makeRotateArbitrary(axis, angle); toWorld.m[3][0] = pos[0]; toWorld.m[3][1] = pos[1]; toWorld.m[3][2] = pos[2]; toWorld = toWorld * rot; toWorld.m[3][0] = asteroid_pos[0]; toWorld.m[3][1] = asteroid_pos[1]; toWorld.m[3][2] = asteroid_pos[2]; translation.identity(); float xT = dir[0] / (planet->radius * 2); float yT = dir[1] / (planet->radius * 2); float zT = dir[2] / (planet->radius * 2); /*xT = xT / 200; yT = yT / 200; zT = zT / 200;*/ translation = translation.makeTranslate(xT, yT, zT); justReverted = true; break; } //return false; } else { Vector3 basePos = gShape->baseToWorld.getTranslate().toVector3(); Vector3 leftPos = gShape->leftToWorld.getTranslate().toVector3(); Vector3 rightPos = gShape->rightToWorld.getTranslate().toVector3(); float baseRadius = gShape->A_size * 1.7; float leftRadius = gShape->B_size * 1.7; float rightRadius = gShape->C_size * 1.7; diff = basePos - pos; if (diff.magnitude() <= baseRadius + planet->radius) { newToWorld = toWorld * translation; newPoint = newToWorld.getTranslate().toVector3(); newDiff = newPoint - pos; if (newDiff.magnitude() > diff.magnitude()) { break; } else { if (!justReverted) { genColorz(gShape->baseBoundSphereColor); translation.m[3][0] = -translation.m[3][0]; translation.m[3][1] = -translation.m[3][1]; translation.m[3][2] = -translation.m[3][2]; justReverted = true; } break; } } diff = leftPos - pos; if (diff.magnitude() <= leftRadius + planet->radius) { newToWorld = toWorld * translation; newPoint = newToWorld.getTranslate().toVector3(); newDiff = newPoint - pos; if (newDiff.magnitude() > diff.magnitude()) { break; } else { if (!justReverted) { genColorz(gShape->leftBoundSphereColor); translation.m[3][0] = -translation.m[3][0]; translation.m[3][1] = -translation.m[3][1]; translation.m[3][2] = -translation.m[3][2]; justReverted = true; } break; } } diff = rightPos - pos; if (diff.magnitude() <= rightRadius + planet->radius) { newToWorld = toWorld * translation * translation* translation * translation; newPoint = newToWorld.getTranslate().toVector3(); newDiff = newPoint - pos; if (newDiff.magnitude() > diff.magnitude()) { break; } else { if (!justReverted) { genColorz(gShape->rightBoundSphereColor); translation.m[3][0] = -translation.m[3][0]; translation.m[3][1] = -translation.m[3][1]; translation.m[3][2] = -translation.m[3][2]; justReverted = true; } break; } } justReverted = false; } } return true; //cout << "Asteroid New Pos" << endl; //cout << toWorld.m[3][0] << " " << toWorld.m[3][1] << " " << toWorld.m[3][2]<< endl; // }