Пример #1
0
        public BasicBody(IDynamicBody dynamics, IElectroMag eMProps, BasicMaterial material, IEdgeIntersector collisionShape, IVolume shape, IOverlapable boundVolume)
        {
            Dynamics       = dynamics;
            EMProps        = eMProps;
            Material       = material;
            CollisionShape = collisionShape;
            Shape          = shape;
            BoundVolume    = boundVolume;

            Dynamics.FrameFinished += (sender, e) => FrameFinished?.Invoke(sender, e);
        }
Пример #2
0
        public BasicBody(IDynamicBody dynamics, IElectroMag eMProps, BasicMaterial material, IEdgeIntersector collisionShape, IVolume shape, IOverlapable boundVolume)
        {
            Dynamics = dynamics;
            EMProps = eMProps;
            Material = material;
            CollisionShape = collisionShape;
            Shape = shape;
            BoundVolume = boundVolume;

            Dynamics.FrameFinished += (sender, e) => FrameFinished?.Invoke(sender, e);
        }
Пример #3
0
        protected override IEnumerable <Intersection> EnactStrategyInternal(IEdgeIntersector firstShape, IEdgeIntersector secondShape, Transformation firstToSecond)
        {
            var sphere    = firstShape as SphereIntersectorVolume ?? secondShape as SphereIntersectorVolume;
            var triangles = firstShape as CompositeIntersector ?? secondShape as CompositeIntersector;

            if (sphere == null || triangles == null)
            {
                throw new ArgumentException("Invalid shape types for this strategy");
            }

            Vector3 spherePos    = sphere == firstShape ? firstToSecond.TransformA.Pos : firstToSecond.TransformB.Pos;
            Vector3 trianglesPos = triangles == firstShape ? firstToSecond.TransformA.Pos : firstToSecond.TransformB.Pos;


            foreach (TriangleIntersector tri in triangles.Primitives)
            {
                Vector3 trianglePos      = trianglesPos + (1.0 / 3.0) * (tri.A + tri.B + tri.C);
                Vector3 sphereToTriangle = trianglePos - spherePos;

                if (sphereToTriangle * tri.N > 0)
                {
                    continue;                               // triangle is facing away from sphere -> no contact
                }
                // find d in the plane equation (http://mathworld.wolfram.com/Plane.html)
                double d = -trianglePos * tri.N;
                // http://mathworld.wolfram.com/Point-PlaneDistance.html
                double dist = spherePos * tri.N + d;

                if (dist > sphere.Radius)
                {
                    continue;
                }

                Vector3 intersectionPt = spherePos + dist * -tri.N;

                // check if itnersectionPt is b/w the 3 vertices
                bool b1 = Sign(intersectionPt, spherePos, trianglesPos + tri.A, trianglesPos + tri.B) < 0.0;
                bool b2 = Sign(intersectionPt, spherePos, trianglesPos + tri.B, trianglesPos + tri.C) < 0.0;
                bool b3 = Sign(intersectionPt, spherePos, trianglesPos + tri.C, trianglesPos + tri.A) < 0.0;
                if (b1 != b2)
                {
                    continue;
                }
                if (b2 != b3)
                {
                    continue;
                }

                yield return(new Intersection(intersectionPt, triangles == firstShape ? tri.N : -tri.N));
            }
        }
Пример #4
0
        protected override IEnumerable <Intersection> EnactStrategyInternal(IEdgeIntersector firstShape, IEdgeIntersector secondShape, Transformation firstToSecond)
        {
            var sphereOne = (SphereIntersectorVolume)firstShape;
            var sphereTwo = (SphereIntersectorVolume)secondShape;

            var firstPos  = firstToSecond.TransformA.Pos;
            var secondPos = firstToSecond.TransformB.Pos;

            Vector3 firstPosToSecond = secondPos - firstPos;
            double  totalRadius      = sphereOne.Radius + sphereTwo.Radius;

            if (firstPosToSecond.Magnitude > totalRadius)
            {
                yield break;
            }
            yield return(new Intersection(firstPos + firstPosToSecond * (sphereOne.Radius / totalRadius), firstPosToSecond.UnitDirection));
        }
Пример #5
0
        // all of the contacts where second's edges intersect first's body
        // handles all cordinate transformation from each body to the world
        private IEnumerable <Contact> ContactsOnFirst(IBody first, IBody second)
        {
            IEdgeIntersector firstShape      = first.CollisionShape;
            IEdgeIntersector secondShape     = second.CollisionShape;
            Transform        firstTransform  = first.Dynamics.Transform;
            Transform        secondTransform = second.Dynamics.Transform;
            var secondToFirst = new Transformation(secondTransform, firstTransform);

            if (IntersectStrats.HasStrategy(firstShape, secondShape))
            {
                return(IntersectStrats.EnactStrategy(firstShape, secondShape, secondToFirst.Reverse()).Select(i => new Contact(i, first, second)));
            }

            // general case
            return
                // everything is converted to the firsts local transform coords
                (secondShape.Edges.SelectMany(secondEdge => firstShape.FindIntersections(secondToFirst.TransformEdge(secondEdge))
                                              .Select(i => new Contact(firstTransform.ToWorldSpace(i), first, second)))); // then to world coords
        }
Пример #6
0
 public BasicBody WithCollisionShape(IEdgeIntersector newCollisionShape) => new BasicBody(Dynamics, EMProps, Material, newCollisionShape, Shape, BoundVolume);
Пример #7
0
 public BasicBody WithCollisionShape(IEdgeIntersector newCollisionShape) => new BasicBody(Dynamics, EMProps, Material, newCollisionShape, Shape, BoundVolume);