public static Vector3 GetFixedAngularError(
			SimulationObject objectA,
			SimulationObject objectB,
			Quaternion relativeOrientation)
		{
			Quaternion currentRelativeOrientation = objectB.RotationStatus.Inverse () *
			                                        objectA.RotationStatus;

			Quaternion relativeOrientationError = relativeOrientation.Inverse () *
			                                      currentRelativeOrientation;

			var angularError = new Vector3 (
				relativeOrientationError.b, 
				relativeOrientationError.c, 
				relativeOrientationError.d);

			if (relativeOrientationError.a < 0.0) 
			{
				angularError = new Vector3 (
					-angularError.x,
					-angularError.y,
					-angularError.z);
			}

			return objectA.RotationMatrix * angularError;
		}
		public FixedJointConstraint(
			int indexA,
			int indexB,
			SimulationObject[] simulationObject,
			double restoreCoefficient,
			double springCoefficient)
		{
			IndexA = indexA;
			IndexB = indexB;
			KeyIndex = GetHashCode();
			SpringCoefficient = springCoefficient;
			RestoreCoefficient = restoreCoefficient;

			SimulationObject objectA = simulationObject[IndexA];
			SimulationObject objectB = simulationObject[IndexB];

			StartAnchorPoint = (objectB.Position - objectA.Position) * 0.5;

			Vector3 relativePos = StartAnchorPoint - objectA.StartPosition;
			relativePos = objectA.RotationMatrix * relativePos;

			AnchorPoint = relativePos + objectA.Position;

			StartErrorAxis1 = objectA.RotationMatrix.Transpose() *
									 (AnchorPoint - objectA.Position);

			StartErrorAxis2 = objectB.RotationMatrix.Transpose() *
									 (AnchorPoint - objectB.Position);

			RelativeOrientation = objectB.RotationStatus.Inverse() *
										 objectA.RotationStatus;
		}
		public PistonConstraint(
			int indexA,
			int indexB,
			SimulationObject[] simulationObject,
			Vector3 startAnchorPosition,
			Vector3 pistonAxis,
			double restoreCoefficient,
			double springCoefficient)
		{
			IndexA = indexA;
			IndexB = indexB;
			KeyIndex = GetHashCode();
			RestoreCoefficient = restoreCoefficient;
			SpringCoefficient = springCoefficient;
			StartAnchorPoint = startAnchorPosition;

			PistonAxis = -1.0 * pistonAxis.Normalize ();

			SimulationObject objectA = simulationObject[IndexA];
			SimulationObject objectB = simulationObject[IndexB];

			Vector3 relativePos = objectA.RotationMatrix *
				(startAnchorPosition - objectA.StartPosition);

			AnchorPoint = relativePos + objectA.Position;

			StartErrorAxis1 = objectA.RotationMatrix.Transpose() *
									 (AnchorPoint - objectA.Position);

			StartErrorAxis2 = objectB.RotationMatrix.Transpose() *
									 (AnchorPoint - objectB.Position);

			RelativeOrientation = objectB.RotationStatus.Inverse() *
										 objectA.RotationStatus;
		}
		public Hinge2Constraint(
			int indexA,
			int indexB,
			SimulationObject[] simulationObject,
			Vector3 startAnchorPosition,
			Vector3 hingeAxis,
			Vector3 rotationAxis,
			double restoreCoefficient,
			double springCoefficientHingeAxis,
			double springCoefficient)
		{
			IndexA = indexA;
			IndexB = indexB;
			KeyIndex = GetHashCode();
			RestoreCoefficient = restoreCoefficient;
			SpringCoefficientHingeAxis = springCoefficientHingeAxis;
			SpringCoefficient = springCoefficient;
			StartAnchorPoint = startAnchorPosition;
			HingeAxis = hingeAxis.Normalize ();
			RotationAxis = rotationAxis.Normalize ();

			SimulationObject objectA = simulationObject[IndexA];
			SimulationObject objectB = simulationObject[IndexB];

			Vector3 relativePos = startAnchorPosition - objectA.StartPosition;
			relativePos = objectA.RotationMatrix * relativePos;

			AnchorPoint = relativePos + objectA.Position;

			StartErrorAxis1 = objectA.RotationMatrix.Transpose() *
									 (AnchorPoint - objectA.Position);

			StartErrorAxis2 = objectB.RotationMatrix.Transpose() *
									 (AnchorPoint - objectB.Position);

			Vector3 rHingeAxis = objectA.RotationMatrix * HingeAxis;
			Vector3 rRotationAxis = objectB.RotationMatrix * RotationAxis;

			RelativeOrientation1 = CalculateRelativeOrientation(
				rHingeAxis,
				rRotationAxis,
				objectA.RotationStatus);

			RelativeOrientation2 = CalculateRelativeOrientation(
				rRotationAxis,
				rHingeAxis,
				objectB.RotationStatus);
		}
		public static double GetAngle(
			SimulationObject simulationObjectA,
			SimulationObject simulationObjectB,
			Quaternion relativeRotation,
			Vector3 rotationAxis)
		{
			Quaternion currentRelativeOrientation = simulationObjectA.RotationStatus.Inverse () *
				simulationObjectB.RotationStatus;

			Quaternion relativeOrientation = relativeRotation.Inverse () *
				currentRelativeOrientation;

			var quaternionVectorPart = new Vector3 (
				relativeOrientation.b,
				relativeOrientation.c,
				relativeOrientation.d);

			quaternionVectorPart = simulationObjectA.RotationMatrix * quaternionVectorPart;

			return GetRotationAngle (
				quaternionVectorPart,
				relativeOrientation.a,
				rotationAxis);
		}
        private void UpdateObjectPosition(
            SimulationObject[] simulationObj)
        {
            int index = 0;
            foreach (SimulationObject simObj in simulationObj)
            {
                if (simObj.ObjectType != ObjectType.StaticRigidBody)
                {
                    #region Linear Velocity

                    double linearVelocity = simObj.TempLinearVelocity.Length();

                    simObj.SetPosition(
                        simObj.Position +
                        TimeStep *
                        simObj.TempLinearVelocity);

                    simObj.SetTempLinearVelocity(new Vector3());

                    #endregion

                    #region Angular Velocity

                    double angularVelocity = simObj.TempAngularVelocity.Length();

                    Vector3 versor = simObj.TempAngularVelocity.Normalize();

                    double rotationAngle = angularVelocity * TimeStep;

                    var rotationQuaternion = new Quaternion(versor, rotationAngle);

                    simObj.SetRotationStatus(
                        (rotationQuaternion * simObj.RotationStatus).Normalize());

                    simObj.SetRotationMatrix(simObj.RotationStatus.ConvertToMatrix());

                    simObj.SetInertiaTensor(
                        (simObj.RotationMatrix * simObj.BaseInertiaTensor) *
                        simObj.RotationMatrix.Transpose());

                    simObj.SetTempAngularVelocity(new Vector3());

                    #endregion

                    #region Update AABB

                    if (simObj.ObjectGeometry != null &&
                        (linearVelocity > 0.0 || angularVelocity > 0.0))
                    {
                        simObj.SetAABB();

                        simObj.SetTempLinearVelocity(new Vector3());
                        simObj.SetTempAngularVelocity(new Vector3());
                    }

                    #endregion
                }
                simulationObjects[index] = simObj;
                index++;
            }
        }
		/// <summary>
		/// Integrates the objects position.
		/// </summary>
		private void IntegrateObjectsPosition(
			SimulationObject[] simulationObj)
		{
			int index = 0;
			foreach (SimulationObject simObj in simulationObj) 
			{
				if (simObj.ObjectType != ObjectType.StaticRigidBody) 
				{
					#region Linear Velocity
                    
                    	simObj.SetPosition (
						simObj.Position + 
						TimeStep * 
						simObj.LinearVelocity);

                    simObj.SetLinearVelocity(simObj.LinearVelocity +
                        (simObj.ForceValue * simObj.InverseMass) +
                        (TimeStep * SimulationEngineParameters.ExternalForce));

                    simObj.SetForce(new Vector3());

                    double linearVelocity = simObj.LinearVelocity.Length();

                    #endregion

                    #region Angular Velocity

                    double angularVelocity = simObj.AngularVelocity.Length();

                    Vector3 versor = simObj.AngularVelocity.Normalize ();

					double rotationAngle = angularVelocity * TimeStep;

                    var rotationQuaternion = new Quaternion(versor, rotationAngle);

                    	simObj.SetRotationStatus ((rotationQuaternion * simObj.RotationStatus).Normalize());

					simObj.SetRotationMatrix (simObj.RotationStatus.ConvertToMatrix ());

					simObj.SetInertiaTensor (
						(simObj.RotationMatrix * simObj.BaseInertiaTensor) *
						simObj.RotationMatrix.Transpose ());

                    simObj.SetAngularVelocity(simObj.AngularVelocity +
                                              simObj.InertiaTensor *
                                              simObj.TorqueValue);

                    angularVelocity = simObj.AngularVelocity.Length();
                    simObj.SetTorque(new Vector3());

                    #endregion

                    #region Sleeping Object

                    if (SimulationEngineParameters.SleepingObject)
                        ObjectSleep(simObj);

                    #endregion

                    #region Update AABB

                    if (simObj.ObjectGeometry != null &&
						(linearVelocity > 0.0 || angularVelocity > 0.0))
                    {
                       simObj.SetAABB();
                    }

                    #endregion

                }
				simulationObjects [index] = simObj;
				index++;
			}
		}
Esempio n. 8
0
		public static Vector3 GetEuler(Quaternion q)
		{
			
			double test = q.b * q.c + q.d * q.a;
			double heading, attitude, bank;

			// singularity at north pole
			if (test > 0.499999) 
			{ 
				heading = 2.0 * Math.Atan2 (q.b, q.a);
				attitude = Math.PI / 2.0;
				bank = 0.0;
				return new Vector3 (bank, heading, attitude);
			}

			// singularity at south pole
			if (test < -0.499999) { 
				heading = -2.0 * Math.Atan2 (q.b, q.a);
				attitude = -Math.PI / 2.0;
				bank = 0.0;
				return new Vector3 (bank, heading, attitude);
			}

			double sqx = q.b * q.b;
			double sqy = q.c * q.c;
			double sqz = q.d * q.d;

			// y-axis
			heading = Math.Atan2 (2.0 * q.c * q.a - 2.0 * q.b * q.d, 
				1.0 - 2.0 * sqy - 2.0 * sqz);

			// z-axis
			attitude = Math.Asin (2.0 * test); 

			// x-axis
			bank = Math.Atan2 (2.0 * q.b * q.a - 2.0 * q.c * q.d, 
				1.0 - 2.0 * sqx - 2.0 * sqz); 
			
			return new Vector3 (bank, heading, attitude);
		}
Esempio n. 9
0
		public static Quaternion IntegrateQuaternion(
			Quaternion q, 
			Vector3 v, 
			double delta)
		{
			Vector3 theta = v * (delta * 0.5);

			double ra = 0.0;
			double rb = theta.x;
			double rc = theta.y;
			double rd = theta.z;

			return Normalize (new Quaternion(ra,rb,rc,rd) * q);
		}
        public SimulationObject(
            ObjectType type,
            ObjectGeometry[] geometry,
            double[] mass,
            Vector3[] startCompositePosition,
            Vector3 position,
            Quaternion rotationStatus)
        {
            ObjectType = type;
            ObjectGeometry = geometry;
            PartialMass = new double[geometry.Length];

            Array.Copy(mass, PartialMass, geometry.Length);
            for (int i = 0; i < geometry.Length; i++)
                Mass += mass[i];
            
            if (ObjectType == ObjectType.StaticRigidBody)
            {
                Mass = 0.0;
                InverseMass = 0.0;
            }
            else if (Mass > 0.0)
                InverseMass = 1.0 / Mass;

            RotationStatus = rotationStatus;

            StartCompositePositionObjects = startCompositePosition;
            
            SetObjectProperties();

            Position = position;

            SetAABB();

            SleepingFrameCount = 0;
        }
		double GetAngle1(
			Vector3 axis1,
			Vector3 axis2,
			Vector3 startAxis,
			Quaternion rotationStatus,
			Quaternion startRelativeRotation)
		{
			Matrix3x3 rotationMatrix = Matrix3x3.GetRotationMatrix(axis1, axis2);
			Quaternion rotationQ = Quaternion.GetQuaternion(rotationMatrix);

			Quaternion mult1 = Quaternion.Multiply1(rotationStatus, rotationQ);
			Quaternion mult2 = Quaternion.Multiply2(mult1, startRelativeRotation);

			var quaternionVectorPart = new Vector3(
				mult2.b,
				mult2.c,
				mult2.d);

			return JacobianCommon.GetRotationAngle(quaternionVectorPart, mult2.a, startAxis);
		}
Esempio n. 12
0
		public static Quaternion Inverse(Quaternion q) 
		{
			double d = 1.0 / (q.a * q.a + q.b * q.b + q.c * q.c + q.d * q.d);
			return new Quaternion (q.a * d, -q.b * d, -q.c * d, -q.d * d);
		}
Esempio n. 13
0
		public static Quaternion Multiply2(Quaternion q1, Quaternion q2)
		{
			double a = (q1.a * q2.a + q1.b * q2.b + q1.c * q2.c + q1.d * q2.d);
			double b = (-q1.a * q2.b + q1.b * q2.a - q1.c * q2.d + q1.d * q2.c);
			double c = (-q1.a * q2.c + q1.c * q2.a - q1.d * q2.b + q1.b * q2.d);
			double d = (-q1.a * q2.d + q1.d * q2.a - q1.b * q2.c + q1.c * q2.b);

			return new Quaternion (a, b, c, d);
		}
Esempio n. 14
0
		/// <summary>
		/// Gets the vector.
		/// </summary>
		/// <returns>The vector.</returns>
		/// <param name="q1">Q1.</param>
		/// <param name="q2">Q2.</param>
		public static Vector3 GetVector(Quaternion q1, Quaternion q2)
		{
			double x = (q1.a * q2.b + q1.b * q2.a + q1.c * q2.d - q1.d * q2.c);
			double y = (q1.a * q2.c - q1.b * q2.d + q1.c * q2.a + q1.d * q2.b);
			double z = (q1.a * q2.d + q1.b * q2.c - q1.c * q2.b + q1.d * q2.a);

			return new Vector3 (x, y, z);
		}
		public void SetRotationStatus(Quaternion inputRotationStatus)
		{
			RotationStatus = inputRotationStatus;
		}
		double GetAngle2(
			Vector3 axis1,
			Vector3 axis2,
			Vector3 startAxis,
			Quaternion rotationStatus,
			Quaternion startRelativeRotation)
		{
			return -GetAngle1(axis2, axis1, startAxis, rotationStatus, startRelativeRotation);
		}
Esempio n. 17
0
		public static Matrix3x3 ConvertToMatrix(Quaternion q)
		{
			double xx = 2.0 * q.b * q.b;
			double yy = 2.0 * q.c * q.c;
			double zz = 2.0 * q.d * q.d;
			double s = q.a;

			double r1x = 1.0 - yy - zz;
			double r1y = 2.0 * (q.b * q.c - s * q.d);
			double r1z = 2.0 * (q.b * q.d + s * q.c);

			double r2x = 2.0 * (q.b * q.c + s * q.d);
			double r2y = 1.0 - xx - zz;
			double r2z = 2.0 * (q.c * q.d - s * q.b);

			double r3x = 2.0 * (q.b * q.d - s * q.c);
			double r3y = 2.0 * (q.c * q.d + s * q.b);
			double r3z = 1.0 - xx - yy;

			return new Matrix3x3 (
				r1x, r1y, r1z,
				r2x, r2y, r2z,
				r3x, r3y, r3z);

		}
		Quaternion CalculateRelativeOrientation(
			Vector3 axis1,
			Vector3 axis2,
			Quaternion bodyRotationStatus)
		{
			Matrix3x3 rotationMatrix = Matrix3x3.GetRotationMatrix(axis1, axis2);
			Quaternion rotationQ = Quaternion.GetQuaternion(rotationMatrix);

			return Quaternion.Multiply1(bodyRotationStatus, rotationQ);
		}
Esempio n. 19
0
		public static double Length(Quaternion q)
		{
			return Math.Sqrt (
				q.a * q.a +
				q.b * q.b +
				q.c * q.c +
				q.d * q.d);
		}
Esempio n. 20
0
		public static Quaternion Normalize(Quaternion q)
		{
			double l = Length (q);

			if (l > 0.0) {
				
				double inv = 1.0 / l;
				double ra = q.a * inv;
				double rb = q.b * inv;
				double rc = q.c * inv;
				double rd = q.d * inv;

				return new Quaternion (ra, rb, rc, rd);
			}

			return q;
		}
        //TODO Refactoring costruttori(inserire possibilità di creeare oggetti con centro di massa e inertia tensor prestabiliti)
		public SimulationObject(
			ObjectType type,
			ObjectGeometry geometry,
			double mass,
			Vector3 position,
			Quaternion rotationStatus)
		{
			ObjectType = type;
            ObjectGeometry = new ObjectGeometry[1] { geometry };
            PartialMass = new double[1] { mass };
            Mass = mass;

			if (ObjectType == ObjectType.StaticRigidBody)
			{
				Mass = 0.0;
				InverseMass = 0.0;
			}
			else if (Mass > 0.0)
				InverseMass = 1.0 / Mass;

            StartCompositePositionObjects = new Vector3[1];

			RotationStatus = rotationStatus;

            Position = position;

            SetObjectProperties();
            
            SetAABB();

            SleepingFrameCount = 0;
        }