Пример #1
0
    // Update is called once per frame
    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            if (_state == null)
            {
                _state = new GJKState(ref PolytopeA, ref PolytopeB);
                _state.LastDirection = initDirection;
            }

            _minkowskisumPoints.Clear();
            _minkowskisumPoints = MinkowskiSum.CalcMinkowskiSum(PolytopeA, PolytopeB);

            _gjkSupportPoints.Clear();

            if (!_state.FinishRun)
            {
                GJK.Collided(ref _state);

                for (int i = 0; i < _state.CurrentSimplex.GetSize(); i++)
                {
                    _gjkSupportPoints.Add(_state.CurrentSimplex.PeekAt(i));
                }
            }
            else
            {
                // Physics res
                float c = 0.5f;

                PhysicsSim compA = _state.GetPolytopeA.GetComponent <PhysicsSim>();
                PhysicsSim compB = _state.GetPolytopeB.GetComponent <PhysicsSim>();

                compA.velocity = UIController.initVelocutyA;
                compB.velocity = UIController.initVelocutyB;

                float massTotal = compA.mass + compB.mass;

                // Contacts
                Vector3 lpA = _state.CurrentSimplex.PopBack();
                Vector3 lpB = _state.CurrentSimplex.PopBack();

                Vector3 cpA = _state.epaData.Contact;
                Vector3 cpB = cpA;

                // Inert
                float invVal = 1f / 0.16f;

                Matrix4x4 rotInert = Matrix4x4.identity;
                rotInert.SetRow(0, new Vector4(invVal, 0f, 0f, 0f));
                rotInert.SetRow(1, new Vector4(0f, invVal, 0f, 0f));
                rotInert.SetRow(2, new Vector4(0f, 0f, 0f, invVal));

                float j =
                    (-(1f + c) * Vector3.Dot(compA.velocity - compB.velocity, _state.epaData.Normal)) /
                    ((1f / compA.mass + 1f / compB.mass) +
                     Vector3.Dot(
                         Vector3.Cross(rotInert * Vector3.Cross(cpA, _state.epaData.Normal), cpA) +
                         Vector3.Cross(rotInert * Vector3.Cross(cpB, _state.epaData.Normal), cpB),
                         _state.epaData.Normal
                         ));

                Vector4 wa = rotInert *
                             (
                    Vector3.Cross(
                        cpA,
                        j * _state.epaData.Normal
                        )
                             );

                compA.AngularVelocity.x += wa.x;
                compA.AngularVelocity.y += wa.y;
                compA.AngularVelocity.z += wa.z;

                Vector4 wb = rotInert *
                             (
                    Vector3.Cross(
                        cpB,
                        j * _state.epaData.Normal
                        )
                             );

                compB.AngularVelocity.x -= wb.x;
                compB.AngularVelocity.y -= wb.y;
                compB.AngularVelocity.z -= wb.z;

                compA.velocity = compA.velocity + ((j / compA.mass) * _state.epaData.Normal);

                compB.velocity = compA.velocity - ((j / compB.mass) * _state.epaData.Normal);

                _state = null;
            }
        }
    }
Пример #2
0
        /// <summary>
        /// Constructs a new demo.
        /// </summary>
        /// <param name="game">Game owning this demo.</param>
        public FancyShapesDemo(DemosGame game)
            : base(game)
        {
            var points = new List <Vector3>();


            //Setup a random distribution in a cube and compute a convex hull.
            var random = new Random(0);

            for (int k = 0; k < 40; k++)
            {
                points.Add(new Vector3(3 * (Fix64)random.NextDouble(), 5 * (Fix64)random.NextDouble(), 3 * (Fix64)random.NextDouble()));
            }
            var convexHull = new ConvexHull(new Vector3(0, 7, 0), points, 10);

            Space.Add(convexHull);

            points.Clear();


            //Create another random distribution, but this time with more points.
            points.Clear();
            for (int k = 0; k < 400; k++)
            {
                points.Add(new Vector3(1 * (Fix64)random.NextDouble(), 3 * (Fix64)random.NextDouble(), 1 * (Fix64)random.NextDouble()));
            }


            convexHull = new ConvexHull(new Vector3(4, 7, 0), points, 10);
            Space.Add(convexHull);



            //Minkowski Sums are fancy 'combinations' of objects, where the result is the sum of the individual points making up shapes.
            //Think of it as sweeping one shape around and through another; a sphere and a box would produce a rounded-edge box.
            var minkowskiSum = new MinkowskiSum(new Vector3(4, -3, 0),
                                                new OrientedConvexShapeEntry(new BoxShape(2, 2, 2)),
                                                new OrientedConvexShapeEntry(new ConeShape(2, 2)), 10);

            Space.Add(minkowskiSum);

            minkowskiSum = new MinkowskiSum(new Vector3(0, 3, 0),
                                            new OrientedConvexShapeEntry(Quaternion.CreateFromYawPitchRoll(1, 2, 3), new ConeShape(1, 1)),
                                            new OrientedConvexShapeEntry(new TriangleShape(Vector3.Zero, Vector3.Right, Vector3.Forward)), 1);
            Space.Add(minkowskiSum);

            //Note how this minkowski sum is composed of a cylinder, and another minkowski sum shape.
            minkowskiSum = new MinkowskiSum(new Vector3(-4, 10, 0),
                                            new OrientedConvexShapeEntry(new CylinderShape(1, 2)),
                                            new OrientedConvexShapeEntry(new MinkowskiSumShape(
                                                                             new OrientedConvexShapeEntry(new TriangleShape(new Vector3(1, 1, 1), new Vector3(-2, 0, 0), new Vector3(0, -1, 0))),
                                                                             new OrientedConvexShapeEntry(new BoxShape(.3m, 1, .3m)))), 10);
            Space.Add(minkowskiSum);

            //Minkowski sums can also be used on more than two shapes at once.  The two-shape constructor is just a convenience wrapper.


            //Wrapped objects use an implicit convex hull around a set of shapes.

            //Oblique cone:
            var cone = new List <ConvexShapeEntry>
            {
                new ConvexShapeEntry(new CylinderShape(0, 1)),
                new ConvexShapeEntry(new RigidTransform(new Vector3(1, 2, 0)), new SphereShape(0))
            };

            Space.Add(new WrappedBody(new Vector3(-5, 0, 0), cone, 10));



            //Rather odd shape:
            var oddShape = new List <ConvexShapeEntry>();
            var bottom   = new ConvexShapeEntry(new Vector3(-2, 2, 0), new SphereShape(2));
            var middle   = new ConvexShapeEntry(
                new RigidTransform(
                    new Vector3(-2, 3, 0),
                    Quaternion.CreateFromAxisAngle(Vector3.Right, MathHelper.Pi / 6)),
                new CylinderShape(0, 3));
            var top = new ConvexShapeEntry(new Vector3(-2, 4, 0), new SphereShape(1));

            oddShape.Add(bottom);
            oddShape.Add(middle);
            oddShape.Add(top);
            Space.Add(new WrappedBody(new Vector3(-3, 4, 0), oddShape, 10));

            //Transformable shapes can be any other kind of convex primitive transformed by any affine transformation.
            Matrix3x3 transform;

            transform     = Matrix3x3.Identity;
            transform.M23 = .5m;
            transform.M13 = .5m;
            var transformable = new TransformableEntity(new Vector3(0, 0, 4), new BoxShape(1, 1, 1), transform, 10);

            Space.Add(transformable);


            Space.Add(new Box(new Vector3(0, -10, 0), 70, 5, 70));

            game.Camera.Position = new Vector3(0, 0, 30);
        }
Пример #3
0
        /// <summary>
        /// Constructs a new demo.
        /// </summary>
        /// <param name="game">Game owning this demo.</param>
        public FancyShapesDemo(DemosGame game)
            : base(game)
        {
            var points = new List<Vector3>();

            //Setup a random distribution in a cube and compute a convex hull.
            var random = new Random(0);
            for (int k = 0; k < 40; k++)
            {
                points.Add(new Vector3(3 * (float)random.NextDouble(), 5 * (float)random.NextDouble(), 3 * (float)random.NextDouble()));
            }
            var convexHull = new ConvexHull(new Vector3(0, 7, 0), points, 10);

            Space.Add(convexHull);

            points.Clear();

            //Create another random distribution, but this time with more points.
            points.Clear();
            for (int k = 0; k < 400; k++)
            {
                points.Add(new Vector3(1 * (float)random.NextDouble(), 3 * (float)random.NextDouble(), 1 * (float)random.NextDouble()));
            }

            convexHull = new ConvexHull(new Vector3(4, 7, 0), points, 10);
            Space.Add(convexHull);

            //Minkowski Sums are fancy 'combinations' of objects, where the result is the sum of the individual points making up shapes.
            //Think of it as sweeping one shape around and through another; a sphere and a box would produce a rounded-edge box.
            var minkowskiSum = new MinkowskiSum(new Vector3(4, -3, 0),
                    new OrientedConvexShapeEntry(new BoxShape(2, 2, 2)),
                    new OrientedConvexShapeEntry(new ConeShape(2, 2)), 10);
            Space.Add(minkowskiSum);

            minkowskiSum = new MinkowskiSum(new Vector3(0, 3, 0),
                    new OrientedConvexShapeEntry(Quaternion.CreateFromYawPitchRoll(1, 2, 3), new ConeShape(1, 1)),
                    new OrientedConvexShapeEntry(new TriangleShape(Vector3.Zero, Vector3.Right, Vector3.Forward)), 1);
            Space.Add(minkowskiSum);

            //Note how this minkowski sum is composed of a cylinder, and another minkowski sum shape.
            minkowskiSum = new MinkowskiSum(new Vector3(-4, 10, 0),
                    new OrientedConvexShapeEntry(new CylinderShape(1, 2)),
                    new OrientedConvexShapeEntry(new MinkowskiSumShape(
                        new OrientedConvexShapeEntry(new TriangleShape(new Vector3(1, 1, 1), new Vector3(-2, 0, 0), new Vector3(0, -1, 0))),
                        new OrientedConvexShapeEntry(new BoxShape(.3f, 1, .3f)))), 10);
            Space.Add(minkowskiSum);

            //Minkowski sums can also be used on more than two shapes at once.  The two-shape constructor is just a convenience wrapper.

            //Wrapped objects use an implicit convex hull around a set of shapes.

            //Oblique cone:
            var cone = new List<ConvexShapeEntry>
            {
                new ConvexShapeEntry(new CylinderShape(0, 1)),
                new ConvexShapeEntry(new RigidTransform(new Vector3(1f, 2, 0)), new SphereShape(0))
            };
            Space.Add(new WrappedBody(new Vector3(-5, 0, 0), cone, 10));

            //Rather odd shape:
            var oddShape = new List<ConvexShapeEntry>();
            var bottom = new ConvexShapeEntry(new Vector3(-2, 2, 0), new SphereShape(2));
            var middle = new ConvexShapeEntry(
                new RigidTransform(
                    new Vector3(-2, 3, 0),
                    Quaternion.CreateFromAxisAngle(Vector3.Right, (float)Math.PI / 6)),
                    new CylinderShape(0, 3));
            var top = new ConvexShapeEntry(new Vector3(-2, 4, 0), new SphereShape(1f));
            oddShape.Add(bottom);
            oddShape.Add(middle);
            oddShape.Add(top);
            Space.Add(new WrappedBody(new Vector3(-3, 4, 0), oddShape, 10));

            //Transformable shapes can be any other kind of convex primitive transformed by any affine transformation.
            Matrix3x3 transform;
            transform = Matrix3x3.Identity;
            transform.M23 = .5f;
            transform.M13 = .5f;
            var transformable = new TransformableEntity(new Vector3(0, 0, 4), new BoxShape(1, 1, 1), transform, 10);
            Space.Add(transformable);

            Space.Add(new Box(new Vector3(0, -10, 0), 70, 5, 70));

            game.Camera.Position = new Vector3(0, 0, 30);
        }