Beispiel #1
0
        /// <summary>
        /// Implements the + operator.
        /// </summary>
        /// <param name="a">a.</param>
        /// <param name="b">The b.</param>
        /// <returns>The result of the operator.</returns>
        /// <exception cref="ArgumentException">Masses must both be in local coordinate systems in order to be added together.</exception>
        public static Mass operator +(Mass a, Mass b)
        {
            if (a == null)
            {
                return(b);
            }
            if (b == null)
            {
                return(a);
            }
            if (!a.IsLocalCoordinateSystem || !b.IsLocalCoordinateSystem)
            {
                throw new ArgumentException("Masses must both be in local coordinate systems in order to be added together.");
            }

            MassProperties massA = a.GetMass();
            MassProperties massB = b.GetMass();

            MassProperties mass = new MassProperties()
            {
                U1 = massA.U1 + massB.U1,
                U2 = massA.U2 + massB.U2,
                U3 = massA.U3 + massB.U3,
                R1 = massA.R1 + massB.R1,
                R2 = massA.R2 + massB.R2,
                R3 = massA.R3 + massB.R3
            };

            return(new Mass(mass));
        }
            public MaterialGlobalInfos(
                AssemblyDocument document,
                Material material,
                List <ComponentOccurrence> materialOccurrences)
            {
                MassProperties asmMassProperties = document.ComponentDefinition.MassProperties;

                Material = material;

                GlobalInfos = new MaterialInfos(material);

                BreakDownInfos = new Dictionary <ComponentOccurrence, MaterialInfos>();

                string docVolumeUnits = GetDocVolumeUnits(document as Document, false);
                string dbVolumeUnits  = GetDbVolumeUnits(document as Document, false);

                foreach (ComponentOccurrence occurrence in materialOccurrences)
                {
                    MaterialInfos materialInfos = new MaterialInfos(material);

                    //Compute percentage first, so no need to convert in doc units first
                    materialInfos.MassPercentage =
                        occurrence.MassProperties.Mass * 100.0 / asmMassProperties.Mass;

                    materialInfos.DbMass = occurrence.MassProperties.Mass;

                    materialInfos.Volume = document.UnitsOfMeasure.ConvertUnits(
                        occurrence.MassProperties.Volume,
                        dbVolumeUnits,
                        docVolumeUnits);

                    materialInfos.Mass = document.UnitsOfMeasure.ConvertUnits(
                        occurrence.MassProperties.Mass,
                        UnitsTypeEnum.kDatabaseMassUnits,
                        UnitsTypeEnum.kDefaultDisplayMassUnits);

                    BreakDownInfos.Add(occurrence, materialInfos);

                    //Add to global, database value
                    GlobalInfos.DbMass += materialInfos.DbMass;
                    GlobalInfos.Volume += occurrence.MassProperties.Volume;
                    GlobalInfos.Mass   += occurrence.MassProperties.Mass;
                }

                //Compute percentage first, so no need to convert in doc units first
                GlobalInfos.MassPercentage = GlobalInfos.Mass * 100.0 / asmMassProperties.Mass;

                //then convert to doc units
                GlobalInfos.Volume = document.UnitsOfMeasure.ConvertUnits(
                    GlobalInfos.Volume,
                    dbVolumeUnits,
                    docVolumeUnits);

                GlobalInfos.Mass = document.UnitsOfMeasure.ConvertUnits(
                    GlobalInfos.Mass,
                    UnitsTypeEnum.kDatabaseMassUnits,
                    UnitsTypeEnum.kDefaultDisplayMassUnits);
            }
Beispiel #3
0
        public Entity CreateBody(RenderMesh displayMesh, float3 position, quaternion orientation,
                                 BlobAssetReference <Unity.Physics.Collider> collider,
                                 float3 linearVelocity, float3 angularVelocity, float mass, bool isDynamic)
        {
            ComponentType[] componentTypes = new ComponentType[isDynamic ? 9 : 6];

            componentTypes[0] = typeof(RenderMesh);
            componentTypes[1] = typeof(TranslationProxy);
            componentTypes[2] = typeof(RotationProxy);
            componentTypes[3] = typeof(PhysicsCollider);
            componentTypes[4] = typeof(Translation);
            componentTypes[5] = typeof(Rotation);
            if (isDynamic)
            {
                componentTypes[6] = typeof(PhysicsVelocity);
                componentTypes[7] = typeof(PhysicsMass);
                componentTypes[8] = typeof(PhysicsDamping);
            }
            EntityManager entityManager = EntityManager;

            Entity entity = entityManager.CreateEntity(componentTypes);

            entityManager.SetName(entity, "randomSphere");
            entityManager.SetSharedComponentData(entity, displayMesh);

            entityManager.AddComponentData(entity, new LocalToWorld {
            });
            entityManager.SetComponentData(entity, new Translation {
                Value = position
            });
            entityManager.SetComponentData(entity, new Rotation {
                Value = orientation
            });
            entityManager.SetComponentData(entity, new PhysicsCollider {
                Value = collider
            });
            if (isDynamic)
            {
                MassProperties massProperties = collider.Value.MassProperties;
                entityManager.SetComponentData(entity, PhysicsMass.CreateDynamic(
                                                   massProperties, mass));
                float3 angularVelocityLocal = math.mul(
                    math.inverse(massProperties.MassDistribution.Transform.rot),
                    angularVelocity);
                entityManager.SetComponentData(entity, new PhysicsVelocity()
                {
                    Linear  = linearVelocity,
                    Angular = angularVelocityLocal
                });
                entityManager.SetComponentData(entity, new PhysicsDamping()
                {
                    Linear  = 0.01f,
                    Angular = 0.05f
                });
            }

            return(entity);
        }
Beispiel #4
0
        private PhysicalProperties ExportPhysicalProperties(MassProperties massProperties)
        {
            var physicalProperties = new PhysicalProperties();

            physicalProperties.Mass         = massProperties.Mass;                      // kg -> kg
            physicalProperties.Area         = massProperties.Area / Math.Pow(100, 2);   // cm^2 -> m^2
            physicalProperties.Volume       = massProperties.Volume / Math.Pow(100, 3); // cm^3 -> m^3
            physicalProperties.CenterOfMass = GetVector3DConvertUnits(massProperties.CenterOfMass);
            return(physicalProperties);
        }
Beispiel #5
0
        public RigidBodyModel(MassProperties mass, CompiledPart[] parts,
                              Material[] materials)
        {
            _mass      = mass;
            _parts     = parts;
            _materials = materials;

            if (_parts.Length != _materials.Length)
            {
                throw new ArgumentException("The count of supplied mesh parts and materials do not match.");
            }
        }
        public void TestBoxColliderMassProperties()
        {
            float3     center       = float3.zero;
            quaternion orientation  = quaternion.identity;
            float3     size         = new float3(1.0f, 250.0f, 2.0f);
            float      convexRadius = 0.25f;
            var        boxCollider  = BoxCollider.Create(center, orientation, size, convexRadius);

            float3 expectedInertiaTensor = 1.0f / 12.0f * new float3(
                size.y * size.y + size.z * size.z,
                size.x * size.x + size.z * size.z,
                size.y * size.y + size.x * size.x);

            MassProperties massProperties = boxCollider.Value.MassProperties;
            float3         inertiaTensor  = massProperties.MassDistribution.InertiaTensor;

            Debug.Log($"Expected Inertia Tensor: {expectedInertiaTensor}, was: {inertiaTensor}");
            TestUtils.AreEqual(expectedInertiaTensor, inertiaTensor, 1e-3f);
        }
Beispiel #7
0
        public double[] FindCenterOfMassOffset(ComponentOccurrence oDoc)
        {
            // Store temporary variables and names
            MassProperties oMassProps = oDoc.MassProperties;

            double[] c = new double[3];

            c[0] = oMassProps.CenterOfMass.X;
            c[1] = oMassProps.CenterOfMass.Y;
            c[2] = oMassProps.CenterOfMass.Z;

            UnitsOfMeasure oUOM = _invApp.ActiveDocument.UnitsOfMeasure;

            for (int k = 0; k < 3; k++)
            {
                c[k] = oUOM.ConvertUnits(c[k], "cm", "m");
            }

            return(c);
        }
        public void TestBoxColliderMassProperties()
        {
            var geometry = new BoxGeometry
            {
                Center      = float3.zero,
                Orientation = quaternion.identity,
                Size        = new float3(1.0f, 250.0f, 2.0f),
                BevelRadius = 0.25f
            };

            var boxCollider = BoxCollider.Create(geometry);

            float3 expectedInertiaTensor = 1.0f / 12.0f * new float3(
                geometry.Size.y * geometry.Size.y + geometry.Size.z * geometry.Size.z,
                geometry.Size.x * geometry.Size.x + geometry.Size.z * geometry.Size.z,
                geometry.Size.y * geometry.Size.y + geometry.Size.x * geometry.Size.x);

            MassProperties massProperties = boxCollider.Value.MassProperties;
            float3         inertiaTensor  = massProperties.MassDistribution.InertiaTensor;

            TestUtils.AreEqual(expectedInertiaTensor, inertiaTensor, 1e-3f);
        }
Beispiel #9
0
        public ScaledSphere(Game game, float radius, Vector3 color)
        {
            _model        = game.Content.Load <Model>("models/sphere");
            _diffuseColor = color;

            _meshTransform = Matrix.CreateScale(radius / 0.25f);

            this.MassProperties = MassProperties.FromSphere(1f, Vector3.Zero, radius);

            this.Skin.Add(new SpherePart(new Sphere(Vector3.Zero, radius)), new Material(0f, 0.5f));

            foreach (var mesh in _model.Meshes)
            {
                foreach (BasicEffect effect in mesh.Effects)
                {
                    effect.EnableDefaultLighting();
                    effect.AmbientLightColor      = Vector3.One * 0.75f;
                    effect.SpecularColor          = Vector3.One;
                    effect.PreferPerPixelLighting = true;
                }
            }
        }
Beispiel #10
0
            public Inertial(MassProperties massProperties)
            {
                mass.value = Math.Round(massProperties.Mass, 4);
                // Get mass properties for each link.
                double[] iXYZ = new double[6];
                massProperties.XYZMomentsOfInertia(out iXYZ[0], out iXYZ[3], out iXYZ[5], out iXYZ[1], out iXYZ[4], out iXYZ[2]); // Ixx, Iyy, Izz, Ixy, Iyz, Ixz -> Ixx, Ixy, Ixz, Iyy, Iyz, Izz

                iXYZ = iXYZ.Select(x => Math.Round(Math.Round(x) * 0.0001, 7)).ToArray();

                inertiaVector.ixx = iXYZ[0];
                inertiaVector.ixy = iXYZ[1];
                inertiaVector.ixz = iXYZ[2];
                inertiaVector.iyy = iXYZ[3];
                inertiaVector.iyz = iXYZ[4];
                inertiaVector.izz = iXYZ[5];
                InertiaMatrix     = new double[, ] {
                    { iXYZ[0], iXYZ[1], iXYZ[2] },
                    { iXYZ[1], iXYZ[3], iXYZ[4] },
                    { iXYZ[2], iXYZ[4], iXYZ[5] }
                };

                Origin     = new Origin();
                Origin.XYZ = new double[] { massProperties.CenterOfMass.X * 0.01, massProperties.CenterOfMass.Y * 0.01, massProperties.CenterOfMass.Z * 0.01 };
            }
Beispiel #11
0
        public ScaledCapsule(Game game, float length, float radius, Vector3 color)
        {
            _model         = game.Content.Load <Model>("models/capsule");
            _meshTransform = _model.Meshes[0].ParentBone.Transform *
                             Matrix.CreateScale(new Vector3(radius / 0.25f, radius / 0.25f, length + (radius * 2)));
            _diffuseColor = color;

            Vector3 dummy, p1 = new Vector3(0f, 0f, length / 2f), p2 = new Vector3(0f, 0f, -length / 2f);

            this.MassProperties = MassProperties.FromCapsule(1f, p1, p2, radius, out dummy);

            this.Skin.Add(new CapsulePart(new Capsule(p1, p2, radius)), new Material(0f, 0.5f));

            foreach (var mesh in _model.Meshes)
            {
                foreach (BasicEffect effect in mesh.Effects)
                {
                    effect.EnableDefaultLighting();
                    effect.AmbientLightColor      = Vector3.One * 0.75f;
                    effect.SpecularColor          = Vector3.One;
                    effect.PreferPerPixelLighting = true;
                }
            }
        }
Beispiel #12
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Mass"/> class.
 /// </summary>
 /// <param name="mass">The mass.</param>
 /// <param name="isLocalCoordinateSystem">if set to <c>true</c> [is local coordinate system].</param>
 internal Mass(MassProperties mass, bool isLocalCoordinateSystem = true)
 {
     _mass = mass;
     IsLocalCoordinateSystem = isLocalCoordinateSystem;
 }
Beispiel #13
0
        public void CreateScene(int sceneNumber)
        {
            _physics.Clear();
            _markers.Clear();

            Room room = new Room(this);

            _physics.Add(room);
            _physics.Gravity = new Vector3(0f, 0f, -9.8f);

            Model cubeModel     = this.Content.Load <Model>("models/small_cube");
            Model obeliskModel  = this.Content.Load <Model>("models/obelisk");
            Model sphereModel   = this.Content.Load <Model>("models/sphere");
            Model capsuleModel  = this.Content.Load <Model>("models/capsule");
            Model torusModel    = this.Content.Load <Model>("models/torus");
            Model slabModel     = this.Content.Load <Model>("models/slab");
            Model triangleModel = this.Content.Load <Model>("models/triangle");

            switch (sceneNumber)
            {
            case 1:
            {
                for (int i = 0; i < 12; i++)
                {
                    var cube = new SolidThing(this, cubeModel);
                    cube.SetWorld(new Vector3(0f, 0f, 0.25f + 0.51f * i));
                    _physics.Add(cube);
                }
            }
            break;

            case 2:
            {
                for (int i = 0; i < 7; i++)
                {
                    for (int j = 0; j < 7 - i; j++)
                    {
                        var cube = new SolidThing(this, cubeModel);
                        cube.SetWorld(new Vector3(0f, 0.501f * j + 0.25f * i, 0.5f + 0.55f * i));
                        _physics.Add(cube);
                    }
                }
            }
            break;

            case 3:
            {
                for (int i = 0; i < 6; i++)
                {
                    for (int j = 0; j < 6 - i; j++)
                    {
                        var cube = new SolidThing(this, cubeModel);
                        cube.SetWorld(new Vector3(0f, 2.2f * j + 1f * i - 4.1f, 0.75f * i + 0.25f));
                        _physics.Add(cube);
                    }
                }
                for (int i = 0; i < 6; i++)
                {
                    for (int j = 0; j < 5 - i; j++)
                    {
                        var plank = new SolidThing(this, obeliskModel);
                        plank.SetWorld(new Vector3(0f, 2.2f * j + 1f * i + 1f - 4f, 0.75f * i + 0.65f),
                                       Quaternion.CreateFromAxisAngle(Vector3.UnitZ, MathHelper.ToRadians(90f)));
                        _physics.Add(plank);
                    }
                }
            }
            break;

            case 4:
            {
                int size = 9;
#if WINDOWS
#else
                size = 4;
#endif
                for (int i = 0; i < size; i++)
                {
                    for (int j = 0; j < size - i; j++)
                    {
                        for (int k = 0; k < size - i; k++)
                        {
                            var sphere = new SolidThing(this, sphereModel);
                            sphere.SetWorld(new Vector3(
                                                0.501f * j + 0.25f * i,
                                                0.501f * k + 0.25f * i,
                                                0.501f * i + 0.5f
                                                ), Quaternion.Identity);
                            _physics.Add(sphere);
                        }
                    }
                }
            }
            break;

            case 5:
            {
                var plank = new SolidThing(this, obeliskModel);
                plank.SetWorld(new Vector3(0.0f, 0.0f, 4.0f),
                               Quaternion.CreateFromAxisAngle(Vector3.UnitY, MathHelper.ToRadians(15f)));
                MassProperties immovableMassProperties = new MassProperties(float.PositiveInfinity, Matrix.Identity);
                plank.MassProperties = immovableMassProperties;
                _physics.Add(plank);

                var sphere = new SolidThing(this, sphereModel);
                sphere.SetWorld(new Vector3(-4.9f, 0.0f, 9.0f), Quaternion.Identity);
                _physics.Add(sphere);


//                        int size = 9;
//#if WINDOWS
//#else
//                        size = 4;
//#endif
//                        var models = new Model[] { cubeModel, sphereModel };
//                        for (int i = 0; i < size; i++)
//                        {
//                            for (int j = 0; j < size - i; j++)
//                            {
//                                for (int k = 0; k < size - i; k++)
//                                {
//                                    var sphere = new SolidThing(this, i % 2 == 0 ? sphereModel : cubeModel);
//                                    sphere.SetWorld(new Vector3(
//                                        0.501f * j + 0.25f * i,
//                                        0.501f * k + 0.25f * i,
//                                        0.501f * i + 0.5f
//                                        ), Quaternion.Identity);
//                                    _physics.Add(sphere);
//                                }
//                            }
//                        }
            }
            break;

            case 6:
            {
                int size = 9;
#if WINDOWS
#else
                size = 4;
#endif
                var models = new Model[] { cubeModel, sphereModel, capsuleModel };
                for (int i = 0; i < size; i++)
                {
                    for (int j = 0; j < size - i; j++)
                    {
                        for (int k = 0; k < size - i; k++)
                        {
                            var sphere = new SolidThing(this, models[_rand.Next(3)]);
                            sphere.SetWorld(new Vector3(
                                                0.501f * j + 0.25f * i,
                                                0.501f * k + 0.25f * i,
                                                1f * i + 0.5f));
                            _physics.Add(sphere);
                        }
                    }
                }
            }
            break;

            case 7:
            {
                var o = new SolidThing(this, torusModel);
                o.SetWorld(new Vector3(0f, 0f, 0.5f), Quaternion.CreateFromAxisAngle(Vector3.UnitY, -MathHelper.PiOver2));
                _physics.Add(o);

                o = new SolidThing(this, torusModel);
                o.SetWorld(new Vector3(0f, 0f, 4f), Quaternion.CreateFromAxisAngle(Vector3.UnitY, -MathHelper.PiOver4));
                _physics.Add(o);

                o = new SolidThing(this, slabModel);
                o.SetWorld(new Vector3(-4f, 4f, 2f));
                _physics.Add(o);

                o = new SolidThing(this, this.Content.Load <Model>("models/cone"));
                o.SetWorld(new Vector3(-4f, -4f, 1f), Quaternion.CreateFromAxisAngle(Vector3.UnitZ, MathHelper.PiOver2));
                _physics.Add(o);

                o = new SolidThing(this, cubeModel);
                o.SetWorld(new Vector3(-4f, 6.1f, 3f));
                _physics.Add(o);
            }
            break;

            case 8:
            {
                RigidBody oLast = null;
                for (int i = 0; i < 10; i++)
                {
                    var o = new SolidThing(this, capsuleModel);
                    o.SetWorld(new Vector3(0f, 0f, 9.5f - i));
                    _physics.Add(o);
                    if (i == 0)
                    {
                        var j = new PointConstraint(o, room, new Vector3(0f, 0f, 10f));
                        j.IsCollisionEnabled = false;
                        _physics.Add(j);
                    }
                    else
                    {
                        var j = new PointConstraint(oLast, o, new Vector3(0f, 0f, 10f - (float)i));
                        j.IsCollisionEnabled = false;
                        _physics.Add(j);
                    }
                    oLast = o;
                }

                var a = new SolidThing(this, cubeModel);
                a.SetWorld(new Vector3(1f, 0f, 0.25f));
                _physics.Add(a);
                var b = new SolidThing(this, cubeModel);
                b.SetWorld(new Vector3(1f, 0f, 0.75f));
                _physics.Add(b);
                var j2 = new RevoluteJoint(b, a, new Vector3(1.25f, 0f, 0.5f), Vector3.UnitY,
                                           0f, MathHelper.PiOver2);
                j2.IsCollisionEnabled = false;
                _physics.Add(j2);

                a = new SolidThing(this, cubeModel);
                a.SetWorld(new Vector3(1f, 1f, 0.25f));
                _physics.Add(a);
                b = new SolidThing(this, cubeModel);
                b.SetWorld(new Vector3(1f, 1f, 0.75f));
                _physics.Add(b);
                var j4 = new GenericConstraint(b, a, new Frame(new Vector3(1f, 1f, 0.5f)),
                                               Axes.All, Vector3.Zero, new Vector3(0f, 0f, 0.5f),
                                               Axes.All, Vector3.Zero, Vector3.Zero);
                j4.IsCollisionEnabled = false;
                _physics.Add(j4);

                a = new SolidThing(this, cubeModel);
                a.SetWorld(new Vector3(1f, 2f, 0.25f));
                _physics.Add(a);
                b = new SolidThing(this, cubeModel);
                b.SetWorld(new Vector3(1f, 2f, 0.75f));
                _physics.Add(b);
                var j5 = new GenericConstraint(b, a, new Frame(new Vector3(1f, 2f, 0.5f)),
                                               Axes.All, new Vector3(-0.125f, -0.125f, 0f), new Vector3(0.125f, 0.125f, 0f),
                                               Axes.All, Vector3.Zero, Vector3.Zero);
                j5.IsCollisionEnabled = false;
                _physics.Add(j5);

                a = new SolidThing(this, sphereModel);
                a.SetWorld(new Vector3(2f, 0f, 2f));
                _physics.Add(a);
                b = new SolidThing(this, sphereModel);
                b.SetWorld(new Vector3(2f, 0f, 1f));
                _physics.Add(b);
                var g1 = new SpringForce(a, b, Vector3.Zero, Vector3.Zero, 1f, 5f, 0.05f);
                _physics.Add(g1);
                var j3 = new WorldPointConstraint(a, new Vector3(2f, 0f, 2f));
                _physics.Add(j3);
            }
            break;

            case 9:
            {
                var a = new SolidThing(this, sphereModel);
                a.Skin.Remove(a.Skin[0]);
                a.Skin.Add(new SpherePart(new Sphere(Vector3.Zero, 0.25f)), new Material(0f, 0.5f));
                a.SetWorld(7.0f, new Vector3(0f, 0f, 5f), Quaternion.Identity);
                a.MassProperties = MassProperties.Immovable;
                _physics.Add(a);

                _physics.Add(new SingularityForce(new Vector3(0f, 0f, 5f), 1E12f));

                _physics.Gravity = Vector3.Zero;

                var b = new SolidThing(this, cubeModel);
                b.SetWorld(new Vector3(0f, 0f, 8f),
                           Quaternion.CreateFromAxisAngle(Vector3.UnitX, MathHelper.PiOver4 / 2.0f) *
                           Quaternion.CreateFromAxisAngle(Vector3.UnitY, MathHelper.PiOver4)
                           );
                _physics.Add(b);
            }
            break;

            default:
                break;
            }
        }
        public override ModelContent Process(NodeContent input, ContentProcessorContext context)
        {
            var attributes = input.Children.ToDictionary(n => n.Name, n => n.OpaqueData);

            var nodesToRemove = (from node in input.Children
                                 where node.OpaqueData.GetAttribute(TYPE_ATTR_NAME, MeshType.Both) == MeshType.Physical
                                 select node).ToArray();

            ModelContent model        = base.Process(input, context);
            var          parts        = new List <CompiledPart>();
            var          materials    = new List <Material>();
            var          mass         = new MassProperties();
            var          centerOfMass = Vector3.Zero;

            foreach (var mesh in model.Meshes)
            {
                MeshType      type = MeshType.Both;
                PhysicalShape shape = PhysicalShape.Mesh;
                float         elasticity = _defaultElasticity, roughness = _defaultRoughness, density = _defaultDensity;

                if (attributes.ContainsKey(mesh.Name))
                {
                    type = attributes[mesh.Name].GetAttribute(TYPE_ATTR_NAME, MeshType.Both);
                    if (type == MeshType.Visual)
                    {
                        continue;
                    }
                    elasticity = attributes[mesh.Name].GetAttribute(ELASTICITY_ATTR_NAME, _defaultElasticity);
                    roughness  = attributes[mesh.Name].GetAttribute(ROUGHNESS_ATTR_NAME, _defaultRoughness);
                    density    = attributes[mesh.Name].GetAttribute(DENSITY_ATTR_NAME, _defaultDensity);
                    shape      = attributes[mesh.Name].GetAttribute(SHAPE_ATTR_NAME, _defaultShape);
                }

                var          meshCenterOfMass = Vector3.Zero;
                var          meshMass         = MassProperties.Immovable;
                CompiledPart meshPart         = null;

                if (mesh.MeshParts.Count < 1)
                {
                    continue;
                }

                int[]     indices  = mesh.MeshParts[0].IndexBuffer.Skip(mesh.MeshParts[0].StartIndex).Take(mesh.MeshParts[0].PrimitiveCount * 3).ToArray();
                Vector3[] vertices = MeshToVertexArray(context.TargetPlatform, mesh);

                if (_windingOrder == WindingOrder.Clockwise)
                {
                    ReverseWindingOrder(indices);
                }

                switch (shape)
                {
                case PhysicalShape.Mesh:
                {
                    meshPart         = new CompiledMesh(vertices, indices);
                    meshMass         = MassProperties.Immovable;
                    meshCenterOfMass = GetMeshTranslation(mesh);
                }
                break;

                case PhysicalShape.Polyhedron:
                {
                    var hull = new ConvexHull3D(vertices);
                    meshPart = hull.ToPolyhedron();
                    meshMass = MassProperties.FromTriMesh(density, vertices, indices, out meshCenterOfMass);
                }
                break;

                case PhysicalShape.Sphere:
                {
                    Sphere s;
                    Sphere.Fit(vertices, out s);
                    meshPart         = new CompiledSphere(s.Center, s.Radius);
                    meshMass         = MassProperties.FromSphere(density, s.Center, s.Radius);
                    meshCenterOfMass = s.Center;
                }
                break;

                case PhysicalShape.Capsule:
                {
                    Capsule c;
                    Capsule.Fit(vertices, out c);
                    meshPart = new CompiledCapsule(c.P1, c.P2, c.Radius);
                    meshMass = MassProperties.FromCapsule(density, c.P1, c.P2, c.Radius, out meshCenterOfMass);
                }
                break;
                }
                parts.Add(meshPart);
                materials.Add(new Material(elasticity, roughness));
                Vector3.Multiply(ref meshCenterOfMass, meshMass.Mass, out meshCenterOfMass);
                Vector3.Add(ref centerOfMass, ref meshCenterOfMass, out centerOfMass);
                mass.Mass           += meshMass.Mass;
                meshMass.Inertia.M44 = 0f;
                Matrix.Add(ref mass.Inertia, ref meshMass.Inertia, out mass.Inertia);
            }

            // compute mass properties
            Vector3.Divide(ref centerOfMass, mass.Mass, out centerOfMass);
            mass.Inertia.M44 = 1f;
            MassProperties.TranslateInertiaTensor(ref mass.Inertia, -mass.Mass, centerOfMass, out mass.Inertia);
            if (centerOfMass.Length() >= Constants.Epsilon)
            {
                var transform = Matrix.CreateTranslation(-centerOfMass.X, -centerOfMass.Y, -centerOfMass.Z);
                foreach (var p in parts)
                {
                    p.Transform(ref transform);
                }

                transform            = model.Root.Transform;
                transform.M41       -= centerOfMass.X;
                transform.M42       -= centerOfMass.Y;
                transform.M43       -= centerOfMass.Z;
                model.Root.Transform = transform;
            }

            mass = new MassProperties(mass.Mass, mass.Inertia);
            var rbm = new RigidBodyModel(mass, parts.ToArray(), materials.ToArray());

            // remove non-visual nodes
            if (nodesToRemove.Length > 0)
            {
                foreach (var node in nodesToRemove)
                {
                    input.Children.Remove(node);
                }
                model = base.Process(input, context);
            }

            model.Tag = rbm;
            return(model);
        }
Beispiel #15
0
 private JObject PhysicalPropertiesToJSON(MassProperties massProperties)
 {
     return(JObject.Parse(synFormatter.Format(ExportPhysicalProperties(massProperties))));
 }
Beispiel #16
0
        static void Main(string[] args)
        {
            // Initialize mass properties
            MassProperties massProp        = new MassProperties(1, 1);
            Guid           structureMassId = Guid.NewGuid();

            massProp.SetMass(structureMassId, 4280);                           // kg, structure weight without fuel
            SimpleGravity gravity = new SimpleGravity(new Vector2D(0, -1.62)); // m/s^2

            // Initialize lander
            Vector2D    initalPosition     = new Vector2D(0, 3000);
            Vector2D    initialVelocity    = new Vector2D(0, -20);
            double      initialOrientation = Util.DegToRad(45);
            RigidBody2D lander             = new RigidBody2D(massProp, initalPosition, initialVelocity, initialOrientation, 0);

            lander.Gravity = gravity;

            // Initialize fuel tanks
            FuelTank rcsTank  = new FuelTank(massProp, 633);
            FuelTank mainTank = new FuelTank(massProp, 10334);

            // Initialize engines
            Vector2D engineMountPoint = new Vector2D(0, -4); // m
            double   orientation      = Util.DegToRad(-90);
            double   maxThrust        = 45040;               // N
            double   fuelUsage        = 13;                  // kg/s, guess
            Thruster mainEngine       = new Thruster(massProp, lander, mainTank, engineMountPoint, orientation, maxThrust, fuelUsage, true);

            // Thrusters
            List <Vector2D> rcsMountPoints = new List <Vector2D>()
            {
                new Vector2D(-5, 0), new Vector2D(-5, 0), new Vector2D(5, 0), new Vector2D(5, 0)
            };
            List <double> rcsOrientations = new List <double>()
            {
                90, -90, 90, -90
            };
            List <Thruster> rcsThrusters = new List <Thruster>();
            double          rcsMaxThrust = 1760;
            double          rcsFuelUsage = 15; // kg/s

            for (int i = 0; i < 4; i++)
            {
                rcsThrusters.Add(new Thruster(massProp, lander, rcsTank, rcsMountPoints[i], rcsOrientations[i], rcsMaxThrust, rcsFuelUsage, false));
            }

            // Flight control
            LanderFlightControl flightControl = new LanderFlightControl(lander, mainEngine, rcsThrusters);

            // logging
            Logger log = new Logger(5);

            log.MainEngine = mainEngine;
            log.RigidBody  = lander;

            // Initialize scheduler
            EqualScheduler scheduler = new EqualScheduler(40); //hz

            scheduler.Add(flightControl, 0);
            scheduler.Add(mainEngine, 10);

            for (int i = 0; i < 4; i++)
            {
                scheduler.Add(rcsThrusters[i], 20 + i);
            }

            scheduler.Add(lander, 40);
            scheduler.Add(log, 50);

            // run sim
            scheduler.Run(TimeSpan.FromSeconds(125));
            log.WriteCSV("simdata_" + DateTime.Now.ToString("yyyyMMddTHHmmss") + ".csv");
        }