Exemple #1
0
        public void GetMassProperties(float density, out float mass, out Vector3 centerOfMass, out Matrix inertiaTensor)
        {
            inertiaTensor = Matrix.Identity;

            // if polygon trace model
            if (_type == TraceModelType.Polygon)
            {
                idTraceModel traceModel = VolumeFromPolygon(1.0f);
                traceModel.GetMassProperties(density, out mass, out centerOfMass, out inertiaTensor);
            }
            else
            {
                VolumeIntegrals integrals = GetVolumeIntegrals();

                // if no volume
                if (integrals.T0 == 0.0f)
                {
                    mass          = 1.0f;
                    centerOfMass  = Vector3.Zero;
                    inertiaTensor = Matrix.Identity;
                }
                else
                {
                    // mass of model
                    mass = density * integrals.T0;

                    // center of mass
                    centerOfMass = integrals.T1 / integrals.T0;

                    // compute inertia tensor
                    inertiaTensor.M11 = density * (integrals.T2.Y + integrals.T2.Z);
                    inertiaTensor.M22 = density * (integrals.T2.Z + integrals.T2.X);
                    inertiaTensor.M33 = density * (integrals.T2.X + integrals.T2.Y);
                    inertiaTensor.M12 = inertiaTensor.M21 = -density * integrals.TP.X;
                    inertiaTensor.M23 = inertiaTensor.M32 = -density * integrals.TP.Y;
                    inertiaTensor.M31 = inertiaTensor.M13 = -density * integrals.TP.Z;

                    // translate inertia tensor to center of mass
                    inertiaTensor.M11 -= mass * (centerOfMass.Y * centerOfMass.Y + centerOfMass.Z * centerOfMass.Z);
                    inertiaTensor.M22 -= mass * (centerOfMass.Z * centerOfMass.Z + centerOfMass.X * centerOfMass.X);
                    inertiaTensor.M33 -= mass * (centerOfMass.X * centerOfMass.X + centerOfMass.Y * centerOfMass.Y);
                    inertiaTensor.M12  = inertiaTensor.M21 += mass * centerOfMass.X * centerOfMass.Y;
                    inertiaTensor.M23  = inertiaTensor.M32 += mass * centerOfMass.Y * centerOfMass.Z;
                    inertiaTensor.M31  = inertiaTensor.M13 += mass * centerOfMass.Z * centerOfMass.X;
                }
            }
        }
		private VolumeIntegrals GetVolumeIntegrals()
		{
			VolumeIntegrals integrals = new VolumeIntegrals();
			int polyCount = _polygons.Length;

			for(int i = 0; i < polyCount; i++)
			{
				TraceModelPolygon poly = _polygons[i];

				float nx = idMath.Abs(poly.Normal.X);
				float ny = idMath.Abs(poly.Normal.Y);
				float nz = idMath.Abs(poly.Normal.Z);
				int c = 0;

				if((nx > ny) && (nx > nz))
				{
					c = 0;
				}
				else
				{
					c = (ny > nz) ? 1 : 2;
				}

				int a = (c + 1) % 3;
				int b = (a + 1) % 3;

				PolygonIntegrals pi = GetPolygonIntegrals(i, a, b, c);

				integrals.T0 += poly.Normal.X * ((a == 0) ? pi.Fa : ((b == 0) ? pi.Fb : pi.Fc));

				if(a == 0)
				{
					integrals.T1.X += poly.Normal.X * pi.Faa;
					integrals.T2.X += poly.Normal.X * pi.Faaa;
					integrals.TP.X += poly.Normal.X * pi.Faab;
				}
				else if(a == 1)
				{
					integrals.T1.Y += poly.Normal.Y * pi.Faa;
					integrals.T2.Y += poly.Normal.Y * pi.Faaa;
					integrals.TP.Y += poly.Normal.Y * pi.Faab;
				}
				else if(a == 2)
				{
					integrals.T1.Z += poly.Normal.Z * pi.Faa;
					integrals.T2.Z += poly.Normal.Z * pi.Faaa;
					integrals.TP.Z += poly.Normal.Z * pi.Faab;
				}

				if(b == 0)
				{
					integrals.T1.X += poly.Normal.X * pi.Fbb;
					integrals.T2.X += poly.Normal.X * pi.Fbbb;
					integrals.TP.X += poly.Normal.X * pi.Fbbc;
				}
				else if(b == 1)
				{
					integrals.T1.Y += poly.Normal.Y * pi.Fbb;
					integrals.T2.Y += poly.Normal.Y * pi.Fbbb;
					integrals.TP.Y += poly.Normal.Y * pi.Fbbc;
				}
				else if(b == 2)
				{
					integrals.T1.Z += poly.Normal.Z * pi.Fbb;
					integrals.T2.Z += poly.Normal.Z * pi.Fbbb;
					integrals.TP.Z += poly.Normal.Z * pi.Fbbc;
				}

				if(c == 0)
				{
					integrals.T1.X += poly.Normal.X * pi.Fcc;
					integrals.T2.X += poly.Normal.X * pi.Fccc;
					integrals.TP.X += poly.Normal.X * pi.Fcca;
				}
				else if(c == 1)
				{
					integrals.T1.Y += poly.Normal.Y * pi.Fcc;
					integrals.T2.Y += poly.Normal.Y * pi.Fccc;
					integrals.TP.Y += poly.Normal.Y * pi.Fcca;
				}
				else if(c == 2)
				{
					integrals.T1.Z += poly.Normal.Z * pi.Fcc;
					integrals.T2.Z += poly.Normal.Z * pi.Fccc;
					integrals.TP.Z += poly.Normal.Z * pi.Fcca;
				}
			}

			integrals.T1 *= 0.5f;
			integrals.T2 *= (1.0f / 3.0f);
			integrals.TP *= 0.5f;

			return integrals;
		}
Exemple #3
0
        private VolumeIntegrals GetVolumeIntegrals()
        {
            VolumeIntegrals integrals = new VolumeIntegrals();
            int             polyCount = _polygons.Length;

            for (int i = 0; i < polyCount; i++)
            {
                TraceModelPolygon poly = _polygons[i];

                float nx = idMath.Abs(poly.Normal.X);
                float ny = idMath.Abs(poly.Normal.Y);
                float nz = idMath.Abs(poly.Normal.Z);
                int   c  = 0;

                if ((nx > ny) && (nx > nz))
                {
                    c = 0;
                }
                else
                {
                    c = (ny > nz) ? 1 : 2;
                }

                int a = (c + 1) % 3;
                int b = (a + 1) % 3;

                PolygonIntegrals pi = GetPolygonIntegrals(i, a, b, c);

                integrals.T0 += poly.Normal.X * ((a == 0) ? pi.Fa : ((b == 0) ? pi.Fb : pi.Fc));

                if (a == 0)
                {
                    integrals.T1.X += poly.Normal.X * pi.Faa;
                    integrals.T2.X += poly.Normal.X * pi.Faaa;
                    integrals.TP.X += poly.Normal.X * pi.Faab;
                }
                else if (a == 1)
                {
                    integrals.T1.Y += poly.Normal.Y * pi.Faa;
                    integrals.T2.Y += poly.Normal.Y * pi.Faaa;
                    integrals.TP.Y += poly.Normal.Y * pi.Faab;
                }
                else if (a == 2)
                {
                    integrals.T1.Z += poly.Normal.Z * pi.Faa;
                    integrals.T2.Z += poly.Normal.Z * pi.Faaa;
                    integrals.TP.Z += poly.Normal.Z * pi.Faab;
                }

                if (b == 0)
                {
                    integrals.T1.X += poly.Normal.X * pi.Fbb;
                    integrals.T2.X += poly.Normal.X * pi.Fbbb;
                    integrals.TP.X += poly.Normal.X * pi.Fbbc;
                }
                else if (b == 1)
                {
                    integrals.T1.Y += poly.Normal.Y * pi.Fbb;
                    integrals.T2.Y += poly.Normal.Y * pi.Fbbb;
                    integrals.TP.Y += poly.Normal.Y * pi.Fbbc;
                }
                else if (b == 2)
                {
                    integrals.T1.Z += poly.Normal.Z * pi.Fbb;
                    integrals.T2.Z += poly.Normal.Z * pi.Fbbb;
                    integrals.TP.Z += poly.Normal.Z * pi.Fbbc;
                }

                if (c == 0)
                {
                    integrals.T1.X += poly.Normal.X * pi.Fcc;
                    integrals.T2.X += poly.Normal.X * pi.Fccc;
                    integrals.TP.X += poly.Normal.X * pi.Fcca;
                }
                else if (c == 1)
                {
                    integrals.T1.Y += poly.Normal.Y * pi.Fcc;
                    integrals.T2.Y += poly.Normal.Y * pi.Fccc;
                    integrals.TP.Y += poly.Normal.Y * pi.Fcca;
                }
                else if (c == 2)
                {
                    integrals.T1.Z += poly.Normal.Z * pi.Fcc;
                    integrals.T2.Z += poly.Normal.Z * pi.Fccc;
                    integrals.TP.Z += poly.Normal.Z * pi.Fcca;
                }
            }

            integrals.T1 *= 0.5f;
            integrals.T2 *= (1.0f / 3.0f);
            integrals.TP *= 0.5f;

            return(integrals);
        }