public static MassProperties CreateProperties(float mass, Vector3 centerOfMass, Matrix inertiaTensor, Matrix inertiaTensorCoM)
        {
            MassProperties newProps = new MassProperties();
            newProps.Mass = mass;
            newProps.CenterOfMass = centerOfMass;
            newProps.InertiaTensor = inertiaTensor;
            newProps.InertiaTensorCoM = inertiaTensorCoM;

            return newProps;
        }
        /// <summary>
        /// Creates a part.
        /// </summary>
        /// <param name="primitiveProperties">Properties of the body's shape.</param>
        /// <param name="massProperties">Properties of the body's mass.</param>
        /// <param name="withMainController">Adds a main BasicController for this part.</param>
        public Part(JLG.PrimitiveProperties primitiveProperties, MassProperties massProperties, bool withMainController)
            : base()
        {
            _primitiveProperties = primitiveProperties;
            _massProperties = massProperties;

            if (withMainController)
            {
                // Create Main Controller
                _mainController = new BasicController(this);

                if (PhysicsSystem.CurrentPhysicsSystem != null)
                {
                    PhysicsSystem.CurrentPhysicsSystem.AddController(_mainController);
                }
            }

            _relatedControllers = new Hashtable();
        }
        /// <summary>
        /// Saves all needed information to recreate an physics world object.
        /// </summary>
        /// <param name="filePath"></param>
        /// <param name="overwrite"></param>
        /// <param name="skin"></param>
        /// <param name="primitiveProperties"></param>
        /// <param name="massProperties">"Null" will cause re-calculation of the mass properties. If you are saving loaded data: Re-calc might cause data loss!</param>
        /// <returns></returns>
        public static bool Save(string filePath, bool overwrite, CollisionSkin skin, PrimitiveProperties primitiveProperties, MassProperties? massProperties)
        {
            if (!File.Exists(filePath) || (File.Exists(filePath) && overwrite))
            {
                PhysicsObjectData data = new PhysicsObjectData();
                data.SetPrimitiveProperties(primitiveProperties);

                for (int i = 0; i < skin.NumPrimitives; i++)
                {
                    data.Add(skin.GetPrimitiveLocal(i), skin.GetMaterialID(i), skin.GetMaterialProperties(i));
                }

                if (massProperties.HasValue)
                {
                    data.MassProperties = massProperties.Value;
                }
                else
                {
                    data.CalculateMassProperties();
                }

                XmlSerializer xmlSerializer = new XmlSerializer(typeof(PhysicsObjectData));
                TextWriter textWriter = new StreamWriter(filePath);

                xmlSerializer.Serialize(textWriter, data);
                textWriter.Close();

                return true;
            }
            else
            {
                MessageBox.Show("Can't write to file \"" + filePath + "\".", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return false;
            }
        }
        /// <summary>
        /// Loads a physics world object.
        /// </summary>
        /// <param name="filePath"></param>
        /// <param name="skin"></param>
        /// <param name="body"></param>
        /// <param name="massProperties"></param>
        /// <returns></returns>
        public static bool Load(string filePath, out CollisionSkin skin, out Body body, out PrimitiveProperties primitiveProperties, out MassProperties massProperties)
        {
            skin = null;
            body = null;
            primitiveProperties = new PrimitiveProperties(PrimitiveProperties.MassDistributionEnum.Solid, PrimitiveProperties.MassTypeEnum.Mass, 0.001f);
            massProperties = MassProperties.Zero;

            if (File.Exists(filePath))
            {
                XmlSerializer xmlSerializer = new XmlSerializer(typeof(PhysicsObjectData));
                TextReader textReader = new StreamReader(filePath);

                PhysicsObjectData data = (PhysicsObjectData)xmlSerializer.Deserialize(textReader);
                textReader.Close();

                if (data != null && data.MaterialPrimitivePairs != null && data.MaterialPrimitivePairs.Count > 0)
                {
                    body = new JigLibSDX.Physics.Body();
                    skin = new JigLibSDX.Collision.CollisionSkin(body);
                    body.CollisionSkin = skin;

                    primitiveProperties = data.PrimitiveProperties;

                    for (int i = 0; i < data.MaterialPrimitivePairs.Count; i++)
                    {
                        if (data.MaterialPrimitivePairs[i].MaterialID == (int)MaterialTable.MaterialID.UserDefined)
                        {
                            skin.AddPrimitive(data.MaterialPrimitivePairs[i].Primitive, data.MaterialPrimitivePairs[i].MaterialID);
                        }
                        else
                        {
                            skin.AddPrimitive(data.MaterialPrimitivePairs[i].Primitive, data.MaterialPrimitivePairs[i].MaterialProperties);
                        }
                    }

                    massProperties = data.MassProperties;

                    body.BodyInertia = massProperties.InertiaTensorCoM;
                    body.Mass = massProperties.Mass;

                    body.MoveTo(Vector3.Zero, Matrix.Identity);
                    skin.ApplyLocalTransform(new Transform(-massProperties.CenterOfMass, Matrix.Identity));

                    body.EnableBody();
                }

                return true;
            }
            else
            {
                MessageBox.Show("File \"" + filePath + "\" not found.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return false;
            }
        }