protected override void OnTransformChanged()
        {
            if (rigidBody != null && !updatePropertiesWithoutUpdatingBody)
            {
                var bodyTransform = Transform.Value;

                if (rigidBodyCreatedTransformScale != bodyTransform.Scale)
                {
                    RecreateBody();
                }
                else
                {
                    //update transform
                    rigidBody.Position = Physics2DUtility.Convert(bodyTransform.Position.ToVector2());
                    rigidBody.Rotation = -(float)MathEx.DegreeToRadian(bodyTransform.Rotation.ToAngles().Yaw);

                    //update constraints
                    if (rigidBody.JointList != null)
                    {
                        foreach (var c in GetLinkedCreatedConstraints())
                        {
                            c.RecreateConstraint();
                        }
                    }
                }
            }

            base.OnTransformChanged();
        }
Esempio n. 2
0
        public override void UpdateDataFromPhysicsEngine()
        {
            if (ConstraintRigid != null)
            {
                Transform rigidBodyTransform;

                {
                    var rigidBody = ConstraintRigid.BodyA;

                    var position = Physics2DUtility.Convert(rigidBody.Position);
                    var rotation = -rigidBody.Rotation;

                    var oldT = Transform.Value;

                    Matrix3F.FromRotateByZ(rotation, out var mat3);
                    var rot2 = mat3.ToQuaternion();
                    //var rot2 = new Angles( 0, 0, MathEx.RadianToDegree( rot ) );

                    rigidBodyTransform = new Transform(new Vector3(position.X, position.Y, oldT.Position.Z), rot2);
                }

                {
                    var transformA = rigidBodyTransform.ToMatrix4() * ConstraintAFrame;
                    transformA.Decompose(out Vector3 translation, out Matrix3 rotation, out Vector3 scale);
                    var oldT = Transform.Value;
                    var newT = new Transform(translation, rotation.ToQuaternion(), oldT.Scale);

                    SetTransformWithoutUpdatingConstraint(newT);
                }
            }
        }
        protected override void OnCheckSelectionByRay(CheckSelectionByRayContext context)
        {
            base.OnCheckSelectionByRay(context);

            if (rigidBody != null)
            {
                context.thisObjectWasChecked = true;

                var worldData = GetPhysicsWorldData(false);
                if (worldData != null)
                {
                    if (context.viewport.CameraSettings.Projection == ProjectionType.Orthographic)
                    {
                        var point = Physics2DUtility.Convert(context.ray.Origin.ToVector2());
                        foreach (var fixture in rigidBody.FixtureList)
                        {
                            if (fixture.TestPoint(ref point))
                            {
                                context.thisObjectResultRayScale = 0;
                                break;
                            }
                        }
                    }
                    else
                    {
                        var bounds = SpaceBounds.CalculatedBoundingBox;
                        if (bounds.Intersects(ref context.ray, out double scale))
                        {
                            context.thisObjectResultRayScale = scale;
                        }
                    }
                }
            }
        }
        public override void UpdateDataFromPhysicsEngine()
        {
            if (MotionType.Value == MotionTypeEnum.Dynamic && rigidBody != null)
            {
                var position = Physics2DUtility.Convert(rigidBody.Position);
                var rotation = -rigidBody.Rotation;

                var oldT = Transform.Value;

                Matrix3F.FromRotateByZ(rotation, out var mat3);
                var rot2 = mat3.ToQuaternion();
                //var rot2 = new Angles( 0, 0, MathEx.RadianToDegree( rot ) );

                var newT = new Transform(new Vector3(position.X, position.Y, oldT.Position.Z), rot2, oldT.Scale);

                try
                {
                    updatePropertiesWithoutUpdatingBody = true;
                    Transform       = newT;
                    LinearVelocity  = Physics2DUtility.Convert(rigidBody.LinearVelocity);
                    AngularVelocity = MathEx.RadianToDegree(rigidBody.AngularVelocity);
                }
                finally
                {
                    updatePropertiesWithoutUpdatingBody = false;
                }
            }
        }
Esempio n. 5
0
        protected internal override IList <Fixture> CreateShape(Body body, Transform shapeTransform, List <Vector2> rigidBodyLocalPoints)
        {
            var convex = GenerateConvex();

            var points = new Vector2[convex.Length];

            for (int n = 0; n < points.Length; n++)
            {
                points[n] = (shapeTransform * new Vector3(convex[n], 0)).ToVector2();
            }

            var r = Rectangle.Cleared;

            foreach (var p in points)
            {
                r.Add(p);
            }
            rigidBodyLocalPoints.Add(r.LeftTop);
            rigidBodyLocalPoints.Add(r.RightTop);
            rigidBodyLocalPoints.Add(r.LeftBottom);
            rigidBodyLocalPoints.Add(r.RightBottom);

            var vertices = new Vertices(points.Length);

            foreach (var p in points)
            {
                vertices.Add(Physics2DUtility.Convert(p));
            }

            return(new Fixture[] { body.CreatePolygon(vertices, 0) });
        }
Esempio n. 6
0
        protected override Joint OnCreateConstraint(Component_PhysicalBody2D creationBodyA, Component_PhysicalBody2D creationBodyB)
        {
            var anchor1 = Physics2DUtility.Convert(TransformV.Position.ToVector2());
            var anchor2 = Physics2DUtility.Convert((TransformV * new Vector3(1, 0, 0)).ToVector2());

            return(new DistanceJoint(creationBodyA.Physics2DBody, creationBodyB.Physics2DBody, anchor1, anchor2, true));
        }
        protected override Joint OnCreateConstraint(Component_PhysicalBody2D creationBodyA, Component_PhysicalBody2D creationBodyB)
        {
            var anchor = Physics2DUtility.Convert(TransformV.Position.ToVector2());

            var angle = -MathEx.DegreeToRadian(TransformV.Rotation.ToAngles().Yaw);
            var axis  = Physics2DUtility.Convert(new Vector2(Math.Cos(angle), Math.Sin(angle)));

            return(new PrismaticJoint(creationBodyA.Physics2DBody, creationBodyB.Physics2DBody, anchor, anchor, axis, true));
        }
        public Physics2DUtility.Physics2DWorldDataImpl GetPhysicsWorldData(bool canInit)
        {
            var scene = ParentScene;

            if (scene != null)
            {
                return(Physics2DUtility.GetWorldData(scene, canInit));
            }
            return(null);
        }
Esempio n. 9
0
        /////////////////////////////////////////

        protected internal override IList <Fixture> CreateShape(Body body, Transform shapeTransform, List <Vector2> rigidBodyLocalPoints)
        {
            if (shapeTransform.IsPositionZero && shapeTransform.IsRotationIdentity)
            {
                var radius = Dimensions.Value * shapeTransform.Scale.ToVector2() * 0.5;

                rigidBodyLocalPoints.Add(new Vector2(-radius.X, -radius.Y));
                rigidBodyLocalPoints.Add(new Vector2(radius.X, -radius.Y));
                rigidBodyLocalPoints.Add(new Vector2(-radius.X, radius.Y));
                rigidBodyLocalPoints.Add(new Vector2(radius.X, radius.Y));

                if (Math.Abs(radius.X - radius.Y) < 0.0001 && UseSmoothCircleWhenPossible)
                {
                    return new Fixture[] { body.CreateCircle((float)radius.X, 0, new Microsoft.Xna.Framework.Vector2(0, 0)) }
                }
                ;
                else
                {
                    return new Fixture[] { body.CreateEllipse((float)radius.X, (float)radius.Y, Edges, 0) }
                };
            }
            else
            {
                var radius = Dimensions.Value * 0.5;
                int edges  = Edges.Value;

                var points = new Vector2[edges];
                for (int n = 0; n < edges; n++)
                {
                    float angle = (float)n / (float)edges * MathEx.PI * 2;
                    points[n] = (shapeTransform * new Vector3(MathEx.Cos(angle) * radius.X, MathEx.Sin(angle) * radius.Y, 0)).ToVector2();
                }

                var r = Rectangle.Cleared;
                foreach (var p in points)
                {
                    r.Add(p);
                }
                rigidBodyLocalPoints.Add(r.LeftTop);
                rigidBodyLocalPoints.Add(r.RightTop);
                rigidBodyLocalPoints.Add(r.LeftBottom);
                rigidBodyLocalPoints.Add(r.RightBottom);

                var vertices = new Vertices(points.Length);
                foreach (var p in points)
                {
                    vertices.Add(Physics2DUtility.Convert(p));
                }

                return(new Fixture[] { body.CreatePolygon(vertices, 0) });
            }
        }
Esempio n. 10
0
        public static void Physics2DRayTest(this Component_Scene scene, Physics2DRayTestItem[] items)
        {
            var worldData = Physics2DUtility.GetWorldData(scene, false);

            if (worldData != null)
            {
                //!!!!threading

                foreach (var item in items)
                {
                    var result = new List <Physics2DRayTestItem.ResultItem>();

                    var point1 = Physics2DUtility.Convert(item.Ray.Origin);
                    var point2 = Physics2DUtility.Convert(item.Ray.GetEndPoint());

                    worldData.world.RayCast((f, p, n, fr) =>
                    {
                        if (ShouldCollide(f, item))
                        {
                            var shape = f.Tag as Component_CollisionShape2D;
                            if (shape != null)
                            {
                                var resultItem           = new Physics2DRayTestItem.ResultItem();
                                resultItem.Body          = shape.ParentRigidBody;
                                resultItem.Shape         = shape;
                                resultItem.Position      = Physics2DUtility.Convert(p);
                                resultItem.Normal        = Physics2DUtility.Convert(n);
                                resultItem.DistanceScale = fr;

                                result.Add(resultItem);

                                if (item.Mode == Physics2DRayTestItem.ModeEnum.One)
                                {
                                    return(0);
                                }
                            }
                        }

                        return(1);
                    }, point1, point2);

                    RayTest_PostProcess(item, result);
                }
            }
            else
            {
                foreach (var item in items)
                {
                    item.Result = Array.Empty <Physics2DRayTestItem.ResultItem>();
                }
            }
        }
        /////////////////////////////////////////

        protected internal override IList <Fixture> CreateShape(Body body, Transform shapeTransform, List <Vector2> rigidBodyLocalPoints)
        {
            if (shapeTransform.IsPositionZero && shapeTransform.IsRotationIdentity)
            {
                var size     = Dimensions.Value * shapeTransform.Scale.ToVector2();
                var sizeHalf = size * 0.5;

                rigidBodyLocalPoints.Add(new Vector2(-sizeHalf.X, -sizeHalf.Y));
                rigidBodyLocalPoints.Add(new Vector2(sizeHalf.X, -sizeHalf.Y));
                rigidBodyLocalPoints.Add(new Vector2(-sizeHalf.X, sizeHalf.Y));
                rigidBodyLocalPoints.Add(new Vector2(sizeHalf.X, sizeHalf.Y));

                return(new Fixture[] { body.CreateRectangle((float)size.X, (float)size.Y, 0, new Microsoft.Xna.Framework.Vector2(0, 0)) });
            }
            else
            {
                var halfDimensions = Dimensions.Value * 0.5;

                var points = new Vector2[4];
                points[0] = (shapeTransform * new Vector3(-halfDimensions.X, -halfDimensions.Y, 0)).ToVector2();
                points[1] = (shapeTransform * new Vector3(halfDimensions.X, -halfDimensions.Y, 0)).ToVector2();
                points[2] = (shapeTransform * new Vector3(halfDimensions.X, halfDimensions.Y, 0)).ToVector2();
                points[3] = (shapeTransform * new Vector3(-halfDimensions.X, halfDimensions.Y, 0)).ToVector2();

                foreach (var p in points)
                {
                    rigidBodyLocalPoints.Add(p);
                }

                var vertices = new Vertices(points.Length);
                foreach (var p in points)
                {
                    vertices.Add(Physics2DUtility.Convert(p));
                }

                return(new Fixture[] { body.CreatePolygon(vertices, 0) });
            }
        }
Esempio n. 12
0
        /////////////////////////////////////////

        public static void Physics2DContactTest(this Component_Scene scene, Physics2DContactTestItem[] items)
        {
            var worldData = Physics2DUtility.GetWorldData(scene, false);

            if (worldData != null)
            {
                foreach (var item in items)
                {
                    var aabb     = new AABB(Physics2DUtility.Convert(item.Bounds.Minimum), Physics2DUtility.Convert(item.Bounds.Maximum));
                    var fixtures = worldData.world.QueryAABB(ref aabb);

                    var result = new List <Physics2DContactTestItem.ResultItem>(fixtures.Count);

                    bool Contains(Component_PhysicalBody2D body, Component_CollisionShape2D shape)
                    {
                        for (int n = 0; n < result.Count; n++)
                        {
                            if (result[n].Body == body && result[n].Shape == shape)
                            {
                                return(true);
                            }
                        }
                        return(false);
                    }

                    PolygonShape polygonShape = null;
                    if (item.Convex != null)
                    {
                        var vertices = new Vertices(item.Convex.Length);
                        foreach (var p in item.Convex)
                        {
                            vertices.Add(Physics2DUtility.Convert(p));
                        }
                        polygonShape = new PolygonShape(vertices, 0);
                    }

                    foreach (var fixture in fixtures)
                    {
                        if (ShouldCollide(fixture, item))
                        {
                            bool skip = false;

                            if (polygonShape != null)
                            {
                                fixture.Body.GetTransform(out var bodyTransform);

                                var identity = tainicom.Aether.Physics2D.Common.Transform.Identity;
                                if (!Collision.TestOverlap(polygonShape, 0, fixture.Shape, 0, ref identity, ref bodyTransform))
                                {
                                    skip = true;
                                }
                            }

                            if (!skip)
                            {
                                var shape = fixture.Tag as Component_CollisionShape2D;
                                if (shape != null)
                                {
                                    var body = shape.ParentRigidBody;
                                    if (!Contains(body, shape))
                                    {
                                        var resultItem = new Physics2DContactTestItem.ResultItem();
                                        resultItem.Body  = body;
                                        resultItem.Shape = shape;
                                        result.Add(resultItem);

                                        if (item.Mode == Physics2DContactTestItem.ModeEnum.One)
                                        {
                                            break;
                                        }
                                    }
                                }
                            }
                        }
                    }

                    item.Result = result.ToArray();
                }
            }
            else
            {
                foreach (var item in items)
                {
                    item.Result = Array.Empty <Physics2DContactTestItem.ResultItem>();
                }
            }
        }
 /// <summary>
 /// Apply an impulse at a point. This immediately modifies the velocity.
 /// This wakes up the body.
 /// </summary>
 /// <param name="impulse">The world impulse vector, usually in N-seconds or kg-m/s.</param>
 public void ApplyLinearImpulse(Vector2 impulse)
 {
     rigidBody?.ApplyLinearImpulse(Physics2DUtility.Convert(impulse));
 }
        protected internal override IList <Fixture> CreateShape(Body body, Transform shapeTransform, List <Vector2> rigidBodyLocalPoints)
        {
            var epsilon = 0.0001f;

            //clear data
            processedVertices = null;
            processedIndices  = null;
            processedTrianglesToSourceIndex = null;

            //get source geometry
            if (!GetSourceData(out var sourceVertices, out var sourceIndices))
            {
                return(null);
            }

            //check valid data
            if (CheckValidData)
            {
                if (!MathAlgorithms.CheckValidVertexIndexBuffer(sourceVertices.Length, sourceIndices, false))
                {
                    Log.Info("Component_CollisionShape2D_Mesh: CreateShape: Invalid source data.");
                    return(null);
                }
            }

            //process geometry
            if (MergeEqualVerticesRemoveInvalidTriangles)
            {
                MathAlgorithms.MergeEqualVerticesRemoveInvalidTriangles(sourceVertices, sourceIndices, epsilon, epsilon, out processedVertices, out processedIndices, out processedTrianglesToSourceIndex);
            }
            else
            {
                processedVertices = sourceVertices;
                processedIndices  = sourceIndices;
            }

            if (ShapeType.Value == ShapeTypeEnum.Auto && ParentRigidBody.MotionType.Value == Component_RigidBody2D.MotionTypeEnum.Dynamic && MathAlgorithms.IsMeshConvex(processedVertices, processedIndices, epsilon) || ShapeType.Value == ShapeTypeEnum.Convex)
            {
                //convex

                var    points = new List <Vector2>(processedVertices.Length);
                Bounds bounds = Bounds.Cleared;
                foreach (var p in processedVertices)
                {
                    var p2 = shapeTransform * new Vector3(p.ToVector2(), 0);
                    points.Add(p2.ToVector2());
                    bounds.Add(p2);
                    //points.Add( ( shapeTransform * new Vector3( p.ToVector2(), 0 ) ).ToVector2() );
                }

                var fixtures = new List <Fixture>();
                {
                    var currentList = new Vertices(points.Count);

                    for (int vertex = 0; vertex < points.Count; vertex++)
                    {
                        currentList.Add(Physics2DUtility.Convert(points[vertex]));

                        if (currentList.Count == Settings.MaxPolygonVertices)
                        {
                            fixtures.Add(body.CreatePolygon(currentList, 0));

                            currentList = new Vertices();
                            currentList.Add(Physics2DUtility.Convert(points[0]));
                            currentList.Add(Physics2DUtility.Convert(points[vertex]));
                        }
                    }

                    if (currentList.Count >= 3)
                    {
                        fixtures.Add(body.CreatePolygon(currentList, 0));
                    }
                }

                //rigidBodyLocalPoints
                {
                    var r = bounds.ToRectangle();
                    rigidBodyLocalPoints.Add(r.LeftTop);
                    rigidBodyLocalPoints.Add(r.RightTop);
                    rigidBodyLocalPoints.Add(r.RightBottom);
                    rigidBodyLocalPoints.Add(r.LeftBottom);
                }

                if (fixtures.Count != 0)
                {
                    return(fixtures.ToArray());
                }

                //var points = new List<Vector2>();
                //foreach( var p in processedVertices )
                //	points.Add( ( shapeTransform * new Vector3( p.ToVector2(), 0 ) ).ToVector2() );

                //var vertices = new Vertices( points.Count );
                //foreach( var p in points )
                //	vertices.Add( Physics2DUtility.Convert( p ) );

                //if( vertices.Count > 1 )
                //	return new Fixture[] { body.CreatePolygon( vertices, 0 ) };
            }
            else
            {
                //chain shapes

                var       fixtures = new List <Fixture>();
                Rectangle bounds   = Rectangle.Cleared;


                //!!!!

                ESet <(Vector2, Vector2)> wasAdded = new ESet <(Vector2, Vector2)>();

                void Add(Vector2 p1, Vector2 p2)
                {
                    if (p1 != p2 && !wasAdded.Contains((p1, p2)) && !wasAdded.Contains((p2, p1)))
                    {
                        wasAdded.Add((p1, p2));

                        fixtures.Add(body.CreateEdge(Physics2DUtility.Convert(p1), Physics2DUtility.Convert(p2)));

                        bounds.Add(p1);
                        bounds.Add(p2);
                    }
                }

                for (int nTriangle = 0; nTriangle < processedIndices.Length / 3; nTriangle++)
                {
                    var v0 = shapeTransform * processedVertices[processedIndices[nTriangle * 3 + 0]];
                    var v1 = shapeTransform * processedVertices[processedIndices[nTriangle * 3 + 1]];
                    var v2 = shapeTransform * processedVertices[processedIndices[nTriangle * 3 + 2]];

                    Add(v0.ToVector2(), v1.ToVector2());
                    Add(v1.ToVector2(), v2.ToVector2());
                    Add(v2.ToVector2(), v0.ToVector2());
                }



                //rectangle

                //for( int nTriangle = 0; nTriangle < processedIndices.Length / 3; nTriangle++ )
                //{
                //	//!!!!slowly shapeTransform *
                //	var v0 = shapeTransform * processedVertices[ processedIndices[ nTriangle * 3 + 0 ] ];
                //	var v1 = shapeTransform * processedVertices[ processedIndices[ nTriangle * 3 + 1 ] ];
                //	var v2 = shapeTransform * processedVertices[ processedIndices[ nTriangle * 3 + 2 ] ];
                //	bounds.Add( v0 );
                //	bounds.Add( v1 );
                //	bounds.Add( v2 );
                //}

                //var vertices = new Vertices();
                //var r = bounds.ToRectangle();
                //vertices.Add( Physics2DUtility.Convert( r.LeftTop ) );
                //vertices.Add( Physics2DUtility.Convert( r.RightTop ) );
                //vertices.Add( Physics2DUtility.Convert( r.RightBottom ) );
                //vertices.Add( Physics2DUtility.Convert( r.LeftBottom ) );



                //local points for space bounds calculation
                rigidBodyLocalPoints.Add(bounds.LeftTop);
                rigidBodyLocalPoints.Add(bounds.RightTop);
                rigidBodyLocalPoints.Add(bounds.RightBottom);
                rigidBodyLocalPoints.Add(bounds.LeftBottom);

                return(fixtures.ToArray());

                //return new Fixture[] { body.CreateLoopShape( vertices ) };
            }

            return(null);
        }
        public override void Render(ViewportRenderingContext context, out int verticesRendered)
        {
            verticesRendered = 0;

            var context2 = context.objectInSpaceRenderingContext;

            //var scene = ParentScene;
            //bool show = ( scene.GetDisplayDevelopmentDataInThisApplication() && scene.DisplayPhysicalObjects ) ||
            //	context2.selectedObjects.Contains( this ) || context2.canSelectObjects.Contains( this ) || context2.dragDropCreateObject == this;
            if (/*show && */ rigidBody != null && context.Owner.Simple3DRenderer != null)
            {
                var viewport = context.Owner;
                var renderer = viewport.Simple3DRenderer;

                //if( context2.displayPhysicalObjectsCounter < context2.displayPhysicalObjectsMax )
                //{
                //	context2.displayPhysicalObjectsCounter++;

                //draw body
                {
                    ColorValue color;
                    if (MotionType.Value == MotionTypeEnum.Static)
                    {
                        color = ProjectSettings.Get.SceneShowPhysicsStaticColor;
                    }
                    else if (rigidBody.Awake)
                    {
                        color = ProjectSettings.Get.SceneShowPhysicsDynamicActiveColor;
                    }
                    else
                    {
                        color = ProjectSettings.Get.SceneShowPhysicsDynamicInactiveColor;
                    }
                    viewport.Simple3DRenderer.SetColor(color, color * ProjectSettings.Get.HiddenByOtherObjectsColorMultiplier);

                    Transform tr;
                    {
                        tr = Transform.Value;
                        var newRotation = new Angles(0, 0, tr.Rotation.ToAngles().Yaw).ToQuaternion();
                        tr = tr.UpdateRotation(newRotation);
                    }

                    foreach (var shape in GetComponents <Component_CollisionShape2D>(false, true, true))
                    {
                        shape.Render(viewport, tr, false, ref verticesRendered);
                    }

                    ////center of mass
                    //if( MotionType.Value == MotionTypeEnum.Dynamic )
                    //{
                    //	var center = rigidBody.LocalCenter;//CenterOfMassPosition;
                    //	double radius = SpaceBounds.CalculatedBoundingSphere.Radius / 16;

                    //	var item = GetCenterOfMassGeometry( (float)radius );
                    //	var transform = Matrix4.FromTranslate( Physics2DUtility.Convert( center ) );
                    //	context.Owner.Simple3DRenderer.AddTriangles( item.positions, item.indices, ref transform, false, true );
                    //	//context.viewport.Simple3DRenderer.AddSphere( BulletPhysicsUtility.Convert( center ), radius, 16, true );

                    //	//Vector3 center = Vector3.Zero;
                    //	//double radius = 1.0;
                    //	//rigidBody.CollisionShape.GetBoundingSphere( out center, out radius );
                    //	//center = rigidBody.CenterOfMassPosition;
                    //	//radius /= 16.0;
                    //	//context.viewport.DebugGeometry.AddSphere( BulletUtils.Convert( center ), radius );

                    //	verticesRendered += item.positions.Length;
                    //}
                }

                //draw selection
                if (context2.selectedObjects.Contains(this) || context2.canSelectObjects.Contains(this))
                {
                    ColorValue color;
                    if (context2.selectedObjects.Contains(this))
                    {
                        color = ProjectSettings.Get.SelectedColor;
                    }
                    else if (context2.canSelectObjects.Contains(this))
                    {
                        color = ProjectSettings.Get.CanSelectColor;
                    }
                    else
                    {
                        color = ProjectSettings.Get.SceneShowPhysicsDynamicActiveColor;
                    }

                    color.Alpha *= .5f;
                    viewport.Simple3DRenderer.SetColor(color, color * ProjectSettings.Get.HiddenByOtherObjectsColorMultiplier);

                    foreach (var shape in GetComponents <Component_CollisionShape2D>(false, true, true))
                    {
                        shape.Render(viewport, Transform, true, ref verticesRendered);
                    }

                    //context.viewport.DebugGeometry.AddBounds( SpaceBounds.CalculatedBoundingBox );
                }

                //display collision contacts
                if (ContactsDisplay && rigidBody.ContactList != null)
                {
                    var size3 = SpaceBounds.CalculatedBoundingBox.GetSize();
                    var scale = (float)Math.Min(size3.X, size3.Y) / 30;
                    //var scale = (float)Math.Max( size3.X, Math.Max( size3.Y, size3.Z ) ) / 40;

                    var edge = rigidBody.ContactList;
                    while (edge != null)
                    {
                        var contact = edge.Contact;

                        int pointCount = contact.Manifold.PointCount;
                        if (pointCount > 0)
                        {
                            if (pointCount > 2)
                            {
                                pointCount = 2;
                            }

                            renderer.SetColor(new ColorValue(1, 0, 0));

                            contact.GetWorldManifold(out _, out var points);

                            for (int n = 0; n < pointCount; n++)
                            {
                                var point = Physics2DUtility.Convert(points[n]);

                                var pos    = new Vector3(point, TransformV.Position.Z);
                                var bounds = new Bounds(
                                    pos - new Vector3(scale, scale, scale),
                                    pos + new Vector3(scale, scale, scale));

                                renderer.AddBounds(bounds, true);
                            }
                        }

                        edge = edge.Next;
                    }
                }

                //}
            }
        }
Esempio n. 16
0
        protected override Joint OnCreateConstraint(Component_PhysicalBody2D creationBodyA, Component_PhysicalBody2D creationBodyB)
        {
            var anchor = Physics2DUtility.Convert(TransformV.Position.ToVector2());

            return(new WeldJoint(creationBodyA.Physics2DBody, creationBodyB.Physics2DBody, anchor, anchor, true));
        }
        void CreateBody()
        {
            if (!CanCreate)
            {
                return;
            }

            duringCreateDestroy = true;

            var physicsWorldData = GetPhysicsWorldData(true);

            if (physicsWorldData != null)
            {
                if (rigidBody != null)
                {
                    Log.Fatal("Component_RigidBody2D: CreateBody: rigidBody != null.");
                }
                if (!EnabledInHierarchy)
                {
                    Log.Fatal("Component_RigidBody2D: CreateBody: !EnabledInHierarchy.");
                }

                var bodyTransform      = Transform.Value;
                var bodyTransformScale = new Transform(Vector3.Zero, Quaternion.Identity, bodyTransform.Scale);

                //get shapes. calculate local transforms with applied body scaling.
                var componentShapes = new List <Tuple <Component_CollisionShape2D, Transform> >();
                foreach (var child in GetComponents <Component_CollisionShape2D>(false, false, true))
                {
                    GetComponentShapesRecursive(child, bodyTransformScale * child.TransformRelativeToParent.Value, componentShapes);
                }

                if (componentShapes.Count > 0)
                {
                    //use local variable to prevent double update inside properties.
                    Body body = new Body();

                    foreach (var shapeItem in componentShapes)
                    {
                        var shape    = shapeItem.Item1;
                        var fixtures = shape.CreateShape(body, shapeItem.Item2, rigidBodyLocalPoints);
                        if (fixtures != null)
                        {
                            foreach (var fixture in fixtures)
                            {
                                fixture.Tag                 = shape;
                                fixture.Friction            = (float)shape.Friction;
                                fixture.Restitution         = (float)shape.Restitution;
                                fixture.CollisionCategories = shape.CollisionCategories;
                                fixture.CollidesWith        = shape.CollidesWith;
                                fixture.CollisionGroup      = (short)shape.CollisionGroup;
                            }
                        }
                    }

                    if (body.FixtureList.Count != 0)
                    {
                        body.Position      = Physics2DUtility.Convert(bodyTransform.Position.ToVector2());
                        body.Rotation      = -(float)MathEx.DegreeToRadian(bodyTransform.Rotation.ToAngles().Yaw);
                        body.FixedRotation = FixedRotation;

                        switch (MotionType.Value)
                        {
                        case MotionTypeEnum.Static: body.BodyType = BodyType.Static; break;

                        case MotionTypeEnum.Dynamic: body.BodyType = BodyType.Dynamic; break;

                        case MotionTypeEnum.Kinematic: body.BodyType = BodyType.Kinematic; break;
                        }

                        body.IsBullet = CCD;

                        if (MotionType.Value == MotionTypeEnum.Dynamic)
                        {
                            UpdateMassAndInertia(body);

                            body.SleepingAllowed = AllowSleep;
                            body.LocalCenter     = Physics2DUtility.Convert(LocalCenter);

                            body.LinearDamping   = (float)LinearDamping;
                            body.AngularDamping  = (float)AngularDamping;
                            body.LinearVelocity  = Physics2DUtility.Convert(LinearVelocity);
                            body.AngularVelocity = (float)MathEx.DegreeToRadian(AngularVelocity);
                            body.IgnoreGravity   = !EnableGravity;
                        }

                        rigidBody     = body;
                        rigidBody.Tag = this;

                        physicsWorldData.world.Add(rigidBody);
                        rigidBodyCreatedTransformScale = bodyTransform.Scale;
                    }
                }

                SpaceBoundsUpdate();
            }

            duringCreateDestroy = false;
        }
        //[Browsable( false )]
        //public List<ContactsDataItem> ContactsData
        //{
        //	get { return contactsData; }
        //	set { contactsData = value; }
        //}

        /// <summary>
        /// Apply a force at a world point. If the force is not applied at the center of mass, it will generate a torque and affect the angular velocity. This wakes up the body.
        /// </summary>
        /// <param name="force">The world force vector, usually in Newtons (N).</param>
        /// <param name="point">The world position of the point of application.</param>
        public void ApplyForce(Vector2 force, Vector2 point)
        {
            rigidBody?.ApplyForce(Physics2DUtility.Convert(force), Physics2DUtility.Convert(point));
            //rigidBody?.ApplyForce( Physics2DUtility.Convert( force ), rigidBody.Position + Physics2DUtility.Convert( point ) );
        }
 /// <summary>
 /// Applies a force at the center of mass.
 /// </summary>
 /// <param name="force">The force.</param>
 public void ApplyForce(Vector2 force)
 {
     rigidBody?.ApplyForce(Physics2DUtility.Convert(force));
 }
 /// <summary>
 /// Apply an impulse at a point. This immediately modifies the velocity. It also modifies the angular velocity if the point of application
 /// is not at the center of mass. This wakes up the body.
 /// </summary>
 /// <param name="impulse">The world impulse vector, usually in N-seconds or kg-m/s.</param>
 /// <param name="point">The world position of the point of application.</param>
 public void ApplyLinearImpulse(Vector2 impulse, Vector2 point)
 {
     rigidBody?.ApplyLinearImpulse(Physics2DUtility.Convert(impulse), Physics2DUtility.Convert(point));
     //rigidBody?.ApplyLinearImpulse( Physics2DUtility.Convert( impulse ), rigidBody.Position + Physics2DUtility.Convert( point ) );
 }