private void SavePhysicsObjectFile(ref Project project)
        {
            if (project != null && project.CollisionPrimitiveInfos != null)
            {
                if (project.CollisionPrimitiveInfos.Count > 0)
                {
                    DialogResult dialogResult = DialogResult.None;
                    bool save = false;

                    try
                    {
                        SaveFileDialog saveFileDialog = new SaveFileDialog();
                        saveFileDialog.Filter = "JigLibSDX Physics Object (*.jlpo)|*.jlpo";

                        dialogResult = saveFileDialog.ShowDialog(this);

                        switch (dialogResult)
                        {
                            case DialogResult.OK:
                                save = true;
                                break;

                            default:
                                save = false;
                                break;
                        }

                        if (save)
                        {
                            JLC.CollisionSkin skin = new JLC.CollisionSkin();

                            JLG.Box box;
                            JLG.Sphere sphere;
                            JLG.Capsule capsule;

                            JLG.Primitive primitive;

                            Quaternion orientation;
                            Vector3 scale;
                            Vector3 translation;

                            Vector3 position;

                            for (int i = 0; i < project.CollisionPrimitiveInfos.Count; i++)
                            {
                                switch ((JLG.PrimitiveType)project.CollisionPrimitiveInfos[i].Primitive.Type)
                                {
                                    case JLG.PrimitiveType.Box:
                                        box = (JLG.Box)project.CollisionPrimitiveInfos[i].Primitive.Clone();

                                        box.Orientation.Decompose(out scale, out orientation, out translation);
                                        box.Position += Vector3.TransformCoordinate(box.SideLengths * -0.5f, Matrix.RotationQuaternion(orientation));

                                        skin.AddPrimitive(box, project.CollisionPrimitiveInfos[i].MaterialProperties);
                                        break;

                                    case JLG.PrimitiveType.Sphere:
                                        skin.AddPrimitive(project.CollisionPrimitiveInfos[i].Primitive.Clone(), project.CollisionPrimitiveInfos[i].MaterialProperties);
                                        break;

                                    case JLG.PrimitiveType.Capsule:
                                        capsule = (JLG.Capsule)project.CollisionPrimitiveInfos[i].Primitive.Clone();

                                        capsule.Orientation.Decompose(out scale, out orientation, out translation);
                                        capsule.Position += Vector3.TransformCoordinate(new Vector3(0f, 0f, capsule.Length * -0.5f), Matrix.RotationQuaternion(orientation));

                                        skin.AddPrimitive(capsule, project.CollisionPrimitiveInfos[i].MaterialProperties);
                                        break;
                                }
                            }

                            JLU.PhysicsObjectFile.Save(saveFileDialog.FileName, true, skin, project.PrimitiveProperties, null);
                        }

                    }
                    catch (Exception e)
                    {
                        MessageBox.Show(this, "An error occured:\n" + e.Message, "Error", MessageBoxButtons.OK);
                    }
                }
                else
                {
                    MessageBox.Show(this, "You need at least one primitive.", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
            }
            else
            {
                MessageBox.Show(this, "Create a new project first.", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }
        public void CalculateMassProperties()
        {
            CollisionSkin skin = new CollisionSkin();

            #region Mass Variables
            Vector3 centerOfMass;
            float mass;
            Matrix inertiaTensor;
            Matrix inertiaTensorCoM;
            #endregion

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

            skin.GetMassProperties(PrimitiveProperties, out mass, out centerOfMass, out inertiaTensor, out inertiaTensorCoM);
            skin.RemoveAllPrimitives();

            _massProperties.Mass = mass;
            _massProperties.CenterOfMass = centerOfMass;
            _massProperties.InertiaTensor = inertiaTensor;
            _massProperties.InertiaTensorCoM = inertiaTensorCoM;
        }
        /// <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;
            }
        }
        private void Initialize(Primitive primitive, MaterialProperties materialProperties, PrimitiveProperties primitiveProperties, bool enableBody)
        {
            float mass;
            Vector3 centerOfMass;
            Matrix inertiaTensor;
            Matrix inertiaTensorCoM;

            // Set variables ...
            _primitive = primitive;
            _primitiveProperties = primitiveProperties;
            _materialProperties = materialProperties;

            // Create and link Body and CollisionSkin.
            _body = new Body();
            _skin = new CollisionSkin(_body);
            _body.CollisionSkin = _skin;

            // Add primitive to CollisionSkin.
            _skin.AddPrimitive(primitive, materialProperties);

            // Set body properties.
            _skin.GetMassProperties(primitiveProperties, out mass, out centerOfMass, out inertiaTensor, out inertiaTensorCoM);

            _body.BodyInertia = inertiaTensorCoM;
            _body.Mass = mass;

            // Sync CollisionSkin and Body.
            _body.MoveTo(Vector3.Zero, Matrix.Identity);
            _skin.ApplyLocalTransform(new Transform(-centerOfMass, Matrix.Identity));

            // Enable Body.
            if (enableBody)
            {
                _body.EnableBody();
            }
            else
            {
                _body.DisableBody();
            }
        }