Пример #1
0
	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;
	}
Пример #2
0
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;
}
Пример #3
0
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;
			}
		}
	}
}
Пример #4
0
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;
	//
}