Пример #1
0
        public void ConstructorTest()
        {
            CollisionFilter filter = new CollisionFilter();
              filter.Get(0); // No exception.
              filter.Get(31); // No exception.
              Assert.AreEqual(32, filter.MaxNumberOfGroups);

              CollisionFilter filter400 = new CollisionFilter(400);
              filter400.Get(0); // No exception.
              filter400.Get(399); // No exception.
              Assert.AreEqual(400, filter400.MaxNumberOfGroups);
        }
Пример #2
0
        private static List<Filter<IUserChangedEvent>> GetFilters(XElement filters, params JointID[] joints)
        {
            IOrderedEnumerable<XElement> myFilters = from node in filters.Descendants()
                                                     orderby node.Attribute(XName.Get("Sequence")).Value ascending
                                                     select node;

            var filterCollection = new List<Filter<IUserChangedEvent>>(myFilters.Count());
            foreach (XElement filter in myFilters)
            {
                Filter<IUserChangedEvent> createdFilter = null;
                if (filter.Name == "FramesFilter")
                {
                    int fpsCount;
                    string fps = filter.Attribute(XName.Get("FPS")).Value;
                    if (int.TryParse(fps, out fpsCount))
                    {
                        createdFilter = new FramesFilter(fpsCount);
                    }
                    else
                    {
                        createdFilter = new FramesFilter(10);
                    }
                }
                else if (filter.Name == "CollisionFilter")
                {
                    int x, y, z;
                    string xValue = filter.Attribute(XName.Get("MarginX")).Value;
                    string yValue = filter.Attribute(XName.Get("MarginY")).Value;
                    string zValue = filter.Attribute(XName.Get("MarginZ")).Value;

                    if (int.TryParse(xValue, out x) && int.TryParse(yValue, out y) && int.TryParse(zValue, out z))
                    {
                        createdFilter = new CollisionFilter(new Point3D(x, y, z), joints);
                    }
                    else
                    {
                        var exception = new ArgumentException("You need to provide the XYZ margins");

                        _log.IfError(string.Empty, exception);

                        throw exception;
                    }
                }
                else if (filter.Name == "CorrectionFilter")
                {
                    var correction = new Point3D();
                    correction.X = SafeFloatParse(filter.Attribute(XName.Get("MarginX")));
                    correction.Y = SafeFloatParse(filter.Attribute(XName.Get("MarginY")));
                    correction.Z = SafeFloatParse(filter.Attribute(XName.Get("MarginZ")));
                    JointID joint;

                    //TODO better catch if XML isn't correct? DTD
                    if (Enum.TryParse(filter.Attribute(XName.Get("SkeletonJoint")).Value, out joint))
                    {
                        createdFilter = new CorrectionFilter(joint, correction);
                    }
                    else
                    {
                        var exception = new ArgumentException("You need to provide a SkeletonJoint to correct");

                        _log.IfError(string.Empty, exception);

                        throw exception;
                    }
                }
                else
                {
                    var exception = new ArgumentException("The provided filter isn't supported");

                    _log.IfError(string.Empty, exception);

                    throw exception;
                }

                if (createdFilter != null)
                {
                    filterCollection.Add(createdFilter);
                }
            }
            return filterCollection;
        }
Пример #3
0
    protected override void OnUpdate()
    {
        CollisionFilter collisionFilter = new CollisionFilter()
        {
            BelongsTo    = ~0u,
            CollidesWith = ~0u, // all 1s, so all layers, collide with everything
            GroupIndex   = 0
        };
        EntityManager  entityManager  = World.EntityManager;
        CollisionWorld collisionWorld = physicsWorld.PhysicsWorld.CollisionWorld;

        Dependency = Entities.WithAll <AnimalTag>().ForEach((ref AnimalMovementData mvmtData, in Translation translation) => {
            float3 start = new float3(translation.Value.x, translation.Value.y, translation.Value.z + 0.2f);

            #region front
            RaycastInput inputFront = new RaycastInput()
            {
                Start  = start,
                End    = new float3(translation.Value.x, translation.Value.y, translation.Value.z + (2.5f * mvmtData.movementSpeed)),
                Filter = collisionFilter
            };
            RaycastHit hitFront = new RaycastHit();
            bool hasHitFront    = collisionWorld.CastRay(inputFront, out hitFront);
            #endregion
            #region front right
            RaycastInput inputFR = new RaycastInput()
            {
                Start  = start,
                End    = new float3(translation.Value.x + (2.5f * mvmtData.movementSpeed), translation.Value.y, translation.Value.z + (2.5f * mvmtData.movementSpeed)),
                Filter = collisionFilter
            };
            RaycastHit hitFR = new RaycastHit();
            bool hasHitFR    = collisionWorld.CastRay(inputFR, out hitFR);
            #endregion
            #region front left
            RaycastInput inputFL = new RaycastInput()
            {
                Start  = start,
                End    = new float3(translation.Value.x - (2.5f * mvmtData.movementSpeed), translation.Value.y, translation.Value.z + (2.5f * mvmtData.movementSpeed)),
                Filter = collisionFilter
            };
            RaycastHit hitFL = new RaycastHit();
            bool hasHitFL    = collisionWorld.CastRay(inputFR, out hitFL);
            #endregion

            if (hasHitFront)
            {
                float3 normal = hitFront.SurfaceNormal;
                //AnimalMovementData mvmtDataHitEntity = entityManager.GetComponentData<AnimalMovementData>(hitEntity);
                //float maxSpeed = math.max(mvmtData.movementSpeed, mvmtDataHitEntity.movementSpeed);

                float dotProduct = math.dot(math.normalize(mvmtData.targetDirection - translation.Value), math.normalize(hitFront.SurfaceNormal));

                float angle = 0.262f;
                angle      += 1f - math.abs(dotProduct);
                //angle += (1f - (maxSpeed * 0.1f));
                angle = math.clamp(angle, 0f, StaticValues.AVOIDANCE_MIN_ANGLE);
                quaternion newRotation = quaternion.RotateY(angle);
                float3 newDirection    = math.rotate(newRotation, mvmtData.direction);
                newDirection           = math.normalizesafe(newDirection);
                // Set EntityA's target direction
                mvmtData.targetDirection = newDirection;
            }
            else if (hasHitFR)
            {
                float3 normal = hitFR.SurfaceNormal;
                //AnimalMovementData mvmtDataHitEntity = entityManager.GetComponentData<AnimalMovementData>(hitEntity);
                //float maxSpeed = math.max(mvmtData.movementSpeed, mvmtDataHitEntity.movementSpeed);

                float dotProduct = math.dot(math.normalize(mvmtData.targetDirection - translation.Value), math.normalize(hitFR.SurfaceNormal));

                float angle = 0.262f;
                angle      += 1f - math.abs(dotProduct);
                //angle += (1f - (maxSpeed * 0.1f));
                angle = math.clamp(angle, 0f, StaticValues.AVOIDANCE_MIN_ANGLE);
                quaternion newRotation = quaternion.RotateY(angle);
                float3 newDirection    = math.rotate(newRotation, mvmtData.direction);
                newDirection           = math.normalizesafe(newDirection);
                // Set EntityA's target direction
                mvmtData.targetDirection = newDirection;
            }
            else if (hasHitFL)
            {
                float3 normal = hitFR.SurfaceNormal;
                //AnimalMovementData mvmtDataHitEntity = entityManager.GetComponentData<AnimalMovementData>(hitEntity);
                //float maxSpeed = math.max(mvmtData.movementSpeed, mvmtDataHitEntity.movementSpeed);

                float dotProduct = math.dot(math.normalize(mvmtData.targetDirection - translation.Value), math.normalize(hitFR.SurfaceNormal));

                float angle = 0.262f;
                angle      += 1f - math.abs(dotProduct);
                //angle += (1f - (maxSpeed * 0.1f));
                angle = math.clamp(angle, 0f, StaticValues.AVOIDANCE_MIN_ANGLE);
                quaternion newRotation = quaternion.RotateY(angle);
                float3 newDirection    = math.rotate(newRotation, mvmtData.direction);
                newDirection           = math.normalizesafe(newDirection);
                // Set EntityA's target direction
                mvmtData.targetDirection = newDirection;
            }
        }).Schedule(Dependency);

        Dependency.Complete();
    }
Пример #4
0
    private bool _cullingEnabled = true;   // True to use frustum culling. False to disable frustum culling.


    public FrustumCullingSample(Microsoft.Xna.Framework.Game game)
      : base(game)
    {
      GraphicsScreen.ClearBackground = true;
      GraphicsScreen.BackgroundColor = Color.CornflowerBlue;

      // The top-down camera.
      var orthographicProjection = new OrthographicProjection();
      orthographicProjection.Set(
        LevelSize * 1.1f * GraphicsService.GraphicsDevice.Viewport.AspectRatio,
        LevelSize * 1.1f,
        1,
        10000f);
      var topDownCamera = new Camera(orthographicProjection);
      _topDownCameraNode = new CameraNode(topDownCamera)
      {
        View = Matrix.CreateLookAt(new Vector3(0, 1000, 0), new Vector3(0, 0, 0), -Vector3.UnitZ),
      };

      // The perspective camera moving through the scene.
      var perspectiveProjection = new PerspectiveProjection();
      perspectiveProjection.SetFieldOfView(
        MathHelper.ToRadians(45),
        GraphicsService.GraphicsDevice.Viewport.AspectRatio,
        1,
        500);
      var sceneCamera = new Camera(perspectiveProjection);
      _sceneCameraNode = new CameraNode(sceneCamera);

      // Initialize collision detection.
      // We use one collision domain that manages all objects.
      _domain = new CollisionDomain(new CollisionDetection())
      {
        // We exchange the default broad phase with a DualPartition. The DualPartition
        // has special support for frustum culling.
        BroadPhase = new DualPartition<CollisionObject>(),
      };

      // Create a lot of random objects and add them to the collision domain.
      RandomHelper.Random = new Random(12345);
      for (int i = 0; i < NumberOfObjects; i++)
      {
        // A real scene consists of a lot of complex objects such as characters, vehicles,
        // buildings, lights, etc. When doing frustum culling we need to test each objects against
        // the viewing frustum. If it intersects with the viewing frustum, the object is visible
        // from the camera's point of view. However, in practice we do not test the exact object
        // against the viewing frustum. Each objects is approximated by a simpler shape. In our
        // example, we assume that each object is approximated with an oriented bounding box.
        // (We could also use an other shape, such as a bounding sphere.)

        // Create a random box.
        Shape randomShape = new BoxShape(RandomHelper.Random.NextVector3(1, 10));

        // Create a random position.
        Vector3 randomPosition;
        randomPosition.X = RandomHelper.Random.NextFloat(-LevelSize / 2, LevelSize / 2);
        randomPosition.Y = RandomHelper.Random.NextFloat(0, 2);
        randomPosition.Z = RandomHelper.Random.NextFloat(-LevelSize / 2, LevelSize / 2);

        // Create a random orientation.
        Quaternion randomOrientation = RandomHelper.Random.NextQuaternion();

        // Create object and add it to collision domain.
        var geometricObject = new GeometricObject(randomShape, new Pose(randomPosition, randomOrientation));
        var collisionObject = new CollisionObject(geometricObject)
        {
          CollisionGroup = 0,
        };
        _domain.CollisionObjects.Add(collisionObject);
      }

      // Per default, the collision domain computes collision between all objects. 
      // In this sample we do not need this information and disable it with a collision 
      // filter.
      // In a real application, we would use this collision information for rendering,
      // for example, to find out which lights overlap with which meshes, etc.
      var filter = new CollisionFilter();
      // Disable collision between objects in collision group 0.
      filter.Set(0, 0, false);
      _domain.CollisionDetection.CollisionFilter = filter;

      // Start with the scene camera.
      GraphicsScreen.CameraNode = _sceneCameraNode;

      // We will collect a few statistics for debugging.
      Profiler.SetFormat("NoCull", 1000, "Time in ms to submit DebugRenderer draw jobs without frustum culling.");
      Profiler.SetFormat("WithCull", 1000, "Time in ms to submit DebugRenderer draw jobs with frustum culling.");
    }
Пример #5
0
        public void Test1()
        {
            CollisionObject object1A = new CollisionObject();

            object1A.CollisionGroup = 1;
            CollisionObject object1B = new CollisionObject();

            object1B.CollisionGroup = 1;

            CollisionObject object2A = new CollisionObject();

            object2A.CollisionGroup = 2;
            CollisionObject object2B = new CollisionObject();

            object2B.CollisionGroup = 2;

            CollisionFilter filter = new CollisionFilter();

            Assert.IsTrue(filter.Filter(new Pair <CollisionObject>(object1A, object1B)));
            Assert.IsTrue(filter.Filter(new Pair <CollisionObject>(object2A, object2B)));
            Assert.IsTrue(filter.Filter(new Pair <CollisionObject>(object2A, object1B)));
            Assert.IsTrue(filter.Filter(new Pair <CollisionObject>(object1A, object2B)));

            filter.Set(2, false);
            Assert.IsTrue(filter.Filter(new Pair <CollisionObject>(object1A, object1B)));
            Assert.IsFalse(filter.Filter(new Pair <CollisionObject>(object2A, object2B)));
            Assert.IsFalse(filter.Filter(new Pair <CollisionObject>(object2A, object1B)));
            Assert.IsFalse(filter.Filter(new Pair <CollisionObject>(object1A, object2B)));

            filter.Set(1, false);
            Assert.IsFalse(filter.Filter(new Pair <CollisionObject>(object1A, object1B)));
            Assert.IsFalse(filter.Filter(new Pair <CollisionObject>(object2A, object2B)));
            Assert.IsFalse(filter.Filter(new Pair <CollisionObject>(object2A, object1B)));
            Assert.IsFalse(filter.Filter(new Pair <CollisionObject>(object1A, object2B)));

            filter.Set(2, true);
            Assert.IsFalse(filter.Filter(new Pair <CollisionObject>(object1A, object1B)));
            Assert.IsTrue(filter.Filter(new Pair <CollisionObject>(object2A, object2B)));
            Assert.IsFalse(filter.Filter(new Pair <CollisionObject>(object2A, object1B)));
            Assert.IsFalse(filter.Filter(new Pair <CollisionObject>(object1A, object2B)));

            filter.Set(1, true);
            Assert.IsTrue(filter.Filter(new Pair <CollisionObject>(object1A, object1B)));
            Assert.IsTrue(filter.Filter(new Pair <CollisionObject>(object2A, object2B)));
            Assert.IsTrue(filter.Filter(new Pair <CollisionObject>(object2A, object1B)));
            Assert.IsTrue(filter.Filter(new Pair <CollisionObject>(object1A, object2B)));

            filter.Set(1, 1, false);
            Assert.IsFalse(filter.Filter(new Pair <CollisionObject>(object1A, object1B)));
            Assert.IsTrue(filter.Filter(new Pair <CollisionObject>(object2A, object2B)));
            Assert.IsTrue(filter.Filter(new Pair <CollisionObject>(object2A, object1B)));
            Assert.IsTrue(filter.Filter(new Pair <CollisionObject>(object1A, object2B)));

            filter.Set(2, 1, false);
            Assert.IsFalse(filter.Filter(new Pair <CollisionObject>(object1A, object1B)));
            Assert.IsTrue(filter.Filter(new Pair <CollisionObject>(object2A, object2B)));
            Assert.IsFalse(filter.Filter(new Pair <CollisionObject>(object2A, object1B)));
            Assert.IsFalse(filter.Filter(new Pair <CollisionObject>(object1A, object2B)));

            filter.Set(1, 1, true);
            filter.Set(1, 2, true);
            Assert.IsTrue(filter.Filter(new Pair <CollisionObject>(object1A, object1B)));
            Assert.IsTrue(filter.Filter(new Pair <CollisionObject>(object2A, object2B)));
            Assert.IsTrue(filter.Filter(new Pair <CollisionObject>(object2A, object1B)));
            Assert.IsTrue(filter.Filter(new Pair <CollisionObject>(object1A, object2B)));

            filter.Set(object1A, object2B, false);
            filter.Set(object1B, object1A, false);
            Assert.IsFalse(filter.Filter(new Pair <CollisionObject>(object1A, object1B)));
            Assert.IsTrue(filter.Filter(new Pair <CollisionObject>(object2A, object2B)));
            Assert.IsTrue(filter.Filter(new Pair <CollisionObject>(object2A, object1B)));
            Assert.IsFalse(filter.Filter(new Pair <CollisionObject>(object1A, object2B)));

            filter.Set(object1A, object2B, true);
            filter.Set(object1B, object1A, true);
            Assert.IsTrue(filter.Filter(new Pair <CollisionObject>(object1A, object1B)));
            Assert.IsTrue(filter.Filter(new Pair <CollisionObject>(object2A, object2B)));
            Assert.IsTrue(filter.Filter(new Pair <CollisionObject>(object2A, object1B)));
            Assert.IsTrue(filter.Filter(new Pair <CollisionObject>(object1A, object2B)));

            filter.Set(object1B, object1A, false);
            filter.Reset();
            Assert.IsTrue(filter.Filter(new Pair <CollisionObject>(object1A, object1B)));
            Assert.IsTrue(filter.Filter(new Pair <CollisionObject>(object2A, object2B)));
            Assert.IsTrue(filter.Filter(new Pair <CollisionObject>(object2A, object1B)));
            Assert.IsTrue(filter.Filter(new Pair <CollisionObject>(object1A, object2B)));
        }
 protected RaycastHit GetPointerRaycastHit(float2 inputPos, CollisionFilter collisionFilter)
 {
     ref PhysicsWorld physicsWorld = ref World.DefaultGameObjectInjectionWorld.GetExistingSystem <BuildPhysicsWorld>().PhysicsWorld;
        // Update is called once per frame
        protected override void OnUpdate()
        {
            // Make sure the world has finished building before querying it
            CreatePhysicsWorldSystem.GetOutputDependency().Complete();

            PhysicsWorld world = CreatePhysicsWorldSystem.PhysicsWorld;

            Entities
            .WithoutBurst()
            .ForEach((in VehicleMechanics mechanics) =>
            {
                if (mechanics.wheels.Count == 0)
                {
                    return;
                }

                Entity ce = mechanics.chassisEntity;
                if (ce == Entity.Null)
                {
                    return;
                }

                int ceIdx = world.GetRigidBodyIndex(ce);
                if (-1 == ceIdx || ceIdx >= world.NumDynamicBodies)
                {
                    return;
                }

                //float ceMass = world.GetMass(ceIdx);
                float3 cePosition     = EntityManager.GetComponentData <Translation>(ce).Value;
                quaternion ceRotation = EntityManager.GetComponentData <Rotation>(ce).Value;
                float3 ceCenterOfMass = world.GetCenterOfMass(ceIdx);
                float3 ceUp           = math.mul(ceRotation, mechanics.chassisUp);
                float3 ceForward      = math.mul(ceRotation, mechanics.chassisForward);
                float3 ceRight        = math.mul(ceRotation, mechanics.chassisRight);

                var rayResults    = new NativeArray <RaycastHit>(mechanics.wheels.Count, Allocator.TempJob);
                var rayVelocities = new NativeArray <float3>(mechanics.wheels.Count, Allocator.TempJob);

                // Collect the RayCast results
                var rayInputs          = new NativeArray <RaycastInput>(mechanics.wheels.Count, Allocator.TempJob);
                CollisionFilter filter = world.GetCollisionFilter(ceIdx);
                for (int i = 0; i < mechanics.wheels.Count; i++)
                {
                    GameObject weGO = mechanics.wheels[i];

                    float3 wheelCurrentPos = weGO.transform.position;

                    float3 rayStart = weGO.transform.parent.position;
                    float3 rayEnd   = (-ceUp * (mechanics.suspensionLength + mechanics.wheelBase)) + rayStart;

                    if (mechanics.drawDebugInformation)
                    {
                        Debug.DrawRay(rayStart, rayEnd - rayStart);
                    }

                    rayInputs[i] = new RaycastInput
                    {
                        Start  = rayStart,
                        End    = rayEnd,
                        Filter = filter
                    };
                }
                JobHandle rayJobHandle = ScheduleBatchRayCast(world.CollisionWorld, rayInputs, rayResults);
                rayJobHandle.Complete();
                for (int i = 0; i < mechanics.wheels.Count; i++)
                {
                    RaycastHit rayResult = rayResults[i];

                    rayVelocities[i] = float3.zero;
                    if (rayResult.RigidBodyIndex != -1)
                    {
                        float3 wheelPos = rayResult.Position;
                        wheelPos       -= (cePosition - ceCenterOfMass);

                        float3 velocityAtWheel = world.GetLinearVelocity(ceIdx, wheelPos);
                        rayVelocities[i]       = velocityAtWheel;
                    }
                }
                rayInputs.Dispose();


                // Calculate a simple slip factor based on chassis tilt.
                float slopeSlipFactor = math.pow(math.abs(math.dot(ceUp, math.up())), 4.0f);

                // Proportional apply velocity changes to each wheel
                float invWheelCount = 1.0f / mechanics.wheels.Count;
                for (int i = 0; i < mechanics.wheels.Count; i++)
                {
                    GameObject weGO = mechanics.wheels[i];

                    float3 rayStart = weGO.transform.parent.position;
                    float3 rayEnd   = (-ceUp * (mechanics.suspensionLength + mechanics.wheelBase)) + rayStart;

                    float3 rayDir = rayEnd - rayStart;

                    RaycastHit rayResult = rayResults[i];
                    //float3 velocityAtWheel = rayVelocities[i];

                    float3 wheelPos = rayResult.Position;
                    wheelPos       -= (cePosition - ceCenterOfMass);

                    float3 velocityAtWheel = world.GetLinearVelocity(ceIdx, wheelPos);

                    float3 weUp      = ceUp;
                    float3 weRight   = ceRight;
                    float3 weForward = ceForward;

                    #region handle wheel steering
                    {
                        bool bIsSteeringWheel = mechanics.steeringWheels.Contains(weGO);
                        if (bIsSteeringWheel)
                        {
                            float steeringAngle = math.radians(mechanics.steeringAngle);
                            //if((mechanics.steeringWheels.IndexOf(weGO)+1) > (0.5f * mechanics.steeringWheels.Count))
                            //    steeringAngle = -steeringAngle;

                            quaternion wRotation = quaternion.AxisAngle(ceUp, steeringAngle);
                            weRight   = math.rotate(wRotation, weRight);
                            weForward = math.rotate(wRotation, weForward);

                            weGO.transform.localRotation = quaternion.AxisAngle(mechanics.chassisUp, steeringAngle);
                        }
                    }
                    #endregion

                    float currentSpeedUp      = math.dot(velocityAtWheel, weUp);
                    float currentSpeedForward = math.dot(velocityAtWheel, weForward);
                    float currentSpeedRight   = math.dot(velocityAtWheel, weRight);

                    #region handle wheel rotation
                    {
                        var rGO = weGO.transform.GetChild(0);
                        if (rGO)
                        {
                            bool isDriven    = (mechanics.driveEngaged && mechanics.driveWheels.Contains(weGO));
                            float weRotation = isDriven
                                ? (mechanics.driveDesiredSpeed / mechanics.wheelBase)
                                : (currentSpeedForward / mechanics.wheelBase);

                            weRotation = math.radians(weRotation);
                            rGO.transform.localRotation *= quaternion.AxisAngle(mechanics.chassisRight, weRotation);
                        }
                    }
                    #endregion


                    float3 wheelCurrentPos = weGO.transform.position;
                    bool hit = !math.all(rayResult.SurfaceNormal == float3.zero);
                    if (!hit)
                    {
                        float3 wheelDesiredPos  = (-ceUp * mechanics.suspensionLength) + rayStart;
                        weGO.transform.position = math.lerp(wheelCurrentPos, wheelDesiredPos, mechanics.suspensionDamping / mechanics.suspensionStrength);
                    }
                    else
                    {
                        // remove the wheelbase to get wheel position.
                        float fraction = rayResult.Fraction - (mechanics.wheelBase) / (mechanics.suspensionLength + mechanics.wheelBase);

                        float3 wheelDesiredPos  = math.lerp(rayStart, rayEnd, fraction);
                        weGO.transform.position = math.lerp(wheelCurrentPos, wheelDesiredPos, mechanics.suspensionDamping / mechanics.suspensionStrength);

                        #region Suspension
                        {
                            // Calculate and apply the impulses
                            var posA = rayEnd;
                            var posB = rayResult.Position;
                            var lvA  = currentSpeedUp * weUp;// world.GetLinearVelocity(ceIdx, posA);
                            var lvB  = world.GetLinearVelocity(rayResult.RigidBodyIndex, posB);

                            var impulse     = mechanics.suspensionStrength * (posB - posA) + mechanics.suspensionDamping * (lvB - lvA);
                            impulse         = impulse * invWheelCount;
                            float impulseUp = math.dot(impulse, weUp);

                            // Suspension shouldn't necessarily pull the vehicle down!
                            float downForceLimit = -0.25f;
                            if (downForceLimit < impulseUp)
                            {
                                impulse = impulseUp * weUp;

                                world.ApplyImpulse(ceIdx, impulse, posA);
                                //world.ApplyImpulse(rayResult.RigidBodyIndex, -impulse, posB);

                                if (mechanics.drawDebugInformation)
                                {
                                    Debug.DrawRay(wheelDesiredPos, impulse, Color.green);
                                }
                            }
                        }
                        #endregion

                        #region Sideways friction
                        {
                            float deltaSpeedRight = (0.0f - currentSpeedRight);
                            deltaSpeedRight       = math.clamp(deltaSpeedRight, -mechanics.wheelMaxImpulseRight, mechanics.wheelMaxImpulseRight);
                            deltaSpeedRight      *= mechanics.wheelFrictionRight;
                            deltaSpeedRight      *= slopeSlipFactor;

                            float3 impulse      = deltaSpeedRight * weRight;
                            float effectiveMass = world.GetEffectiveMass(ceIdx, impulse, wheelPos);
                            impulse             = impulse * effectiveMass * invWheelCount;

                            world.ApplyImpulse(ceIdx, impulse, wheelPos);
                            world.ApplyImpulse(rayResult.RigidBodyIndex, -impulse, wheelPos);

                            if (mechanics.drawDebugInformation)
                            {
                                Debug.DrawRay(wheelDesiredPos, impulse, Color.red);
                            }
                        }
                        #endregion

                        #region Drive
                        {
                            if (mechanics.driveEngaged && mechanics.driveWheels.Contains(weGO))
                            {
                                float deltaSpeedForward = (mechanics.driveDesiredSpeed - currentSpeedForward);
                                deltaSpeedForward       = math.clamp(deltaSpeedForward, -mechanics.wheelMaxImpulseForward, mechanics.wheelMaxImpulseForward);
                                deltaSpeedForward      *= mechanics.wheelFrictionForward;
                                deltaSpeedForward      *= slopeSlipFactor;

                                float3 impulse = deltaSpeedForward * weForward;

                                float effectiveMass = world.GetEffectiveMass(ceIdx, impulse, wheelPos);
                                impulse             = impulse * effectiveMass * invWheelCount;

                                world.ApplyImpulse(ceIdx, impulse, wheelPos);
                                world.ApplyImpulse(rayResult.RigidBodyIndex, -impulse, wheelPos);

                                if (mechanics.drawDebugInformation)
                                {
                                    Debug.DrawRay(wheelDesiredPos, impulse, Color.blue);
                                }
                            }
                        }
                        #endregion
                    }
                }

                rayResults.Dispose();
                rayVelocities.Dispose();
            }).Run();
        /// <summary>
        /// Variant of <see cref="TrimByFilter{T}(ref NativeList{T}, EntityManager, CollisionFilter)"/> to be used within a Job which does not have access to an <see cref="EntityManager"/>.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="castResults"></param>
        /// <param name="colliderData"></param>
        /// <param name="filter"></param>
        public unsafe static void TrimByFilter <T>(ref NativeList <T> castResults, ComponentDataFromEntity <PhysicsCollider> colliderData, CollisionFilter filter) where T : struct, IQueryResult
        {
            for (int i = (castResults.Length - 1); i >= 0; --i)
            {
                if (colliderData.HasComponent(castResults[i].Entity))
                {
                    PhysicsCollider collider = colliderData[castResults[i].Entity];

                    if (CollisionFilter.IsCollisionEnabled(filter, collider.ColliderPtr->Filter))
                    {
                        continue;
                    }
                }

                castResults.RemoveAt(i);
            }
        }
        // Update is called once per frame
        protected override void OnUpdate( )
        {
            EntityCommandBuffer.ParallelWriter ecbp = becb.CreateCommandBuffer().AsParallelWriter();

            CollisionFilter collisionFilter = new CollisionFilter();

            collisionFilter.BelongsTo    = 1;
            collisionFilter.CollidesWith = 1;

            Entities
            .WithName("CreateBarrierCollidersJob")
            .WithAll <CreateColliderTag, BarrierTag> ()
            .ForEach((Entity entity, int entityInQueryIndex, in CompositeScale scale) =>
            {
                float3 f3_scale = new float3(scale.Value.c0.x, scale.Value.c1.y, 1);
                BlobAssetReference <Unity.Physics.Collider> collider = Unity.Physics.BoxCollider.Create(new BoxGeometry {
                    Center = 0, Size = f3_scale, Orientation = quaternion.identity
                }, collisionFilter);

                PhysicsCollider physicsCollider = new PhysicsCollider()
                {
                    Value = collider
                };

                ecbp.AddComponent(entityInQueryIndex, entity, physicsCollider);
                ecbp.RemoveComponent <CreateColliderTag> (entityInQueryIndex, entity);
            }).ScheduleParallel();

            collisionFilter.BelongsTo    = 2;
            collisionFilter.CollidesWith = 1;

            Entities
            .WithName("CreateScoreCollidersJob")
            .WithAll <CreateColliderTag, ScoreTag> ()
            .ForEach((Entity entity, int entityInQueryIndex, in CompositeScale scale) =>
            {
                float3 f3_scale = new float3(scale.Value.c0.x, scale.Value.c1.y, 1);
                BlobAssetReference <Unity.Physics.Collider> collider = Unity.Physics.BoxCollider.Create(new BoxGeometry {
                    Center = 0, Size = f3_scale, Orientation = quaternion.identity
                }, collisionFilter);

                PhysicsCollider physicsCollider = new PhysicsCollider()
                {
                    Value = collider
                };

                ecbp.AddComponent(entityInQueryIndex, entity, physicsCollider);
                ecbp.RemoveComponent <CreateColliderTag> (entityInQueryIndex, entity);
            }).ScheduleParallel();

            collisionFilter.BelongsTo    = 1;  // 4
            collisionFilter.CollidesWith = 1;

            Entities
            .WithName("CreateVehicleCollidersJob")
            .WithAll <CreateColliderTag, VehicleControllsComponent> ()
            .ForEach((Entity entity, int entityInQueryIndex, in CompositeScale scale) =>
            {
                float3 f3_scale = new float3(scale.Value.c0.x, scale.Value.c1.y, 1);
                BlobAssetReference <Unity.Physics.Collider> collider = Unity.Physics.BoxCollider.Create(new BoxGeometry {
                    Center = 0, Size = f3_scale, Orientation = quaternion.identity
                }, collisionFilter);

                PhysicsCollider physicsCollider = new PhysicsCollider()
                {
                    Value = collider
                };

                ecbp.AddComponent(entityInQueryIndex, entity, physicsCollider);
                ecbp.RemoveComponent <CreateColliderTag> (entityInQueryIndex, entity);
            }).ScheduleParallel();

            becb.AddJobHandleForProducer(Dependency);
        }
Пример #10
0
        /// <summary>Gets a point on a navigable surface (either the current surface or a jumpable one) for the provided agent entity via the out hit parameter. Returns true if there is a navigable surface, false if not.</summary>
        public static bool GetPointOnNavigableSurface(Vector3 point, Entity agentEntity, Camera cam, PhysicsWorld physicsWorld, float raycastDistance, EntityManager entityManager, CollisionFilter filter, out Unity.Physics.RaycastHit hit)
        {
            var screenPointToRay = cam.ScreenPointToRay(point);

            var rayInput = new RaycastInput
            {
                Start  = screenPointToRay.origin,
                End    = screenPointToRay.GetPoint(raycastDistance),
                Filter = filter
            };

            if (!physicsWorld.CastRay(rayInput, out hit) || hit.RigidBodyIndex == -1)
            {
                return(false);
            }

            if (!NavMesh.SamplePosition(hit.Position, out var navMeshHit, 1, NavMesh.AllAreas))
            {
                return(false);
            }

            var hitSurfaceEntity = physicsWorld.Bodies[hit.RigidBodyIndex].Entity;

            if (hitSurfaceEntity == Entity.Null)
            {
                return(false);
            }

            if (!entityManager.HasComponent <Parent>(agentEntity))
            {
                return(false);
            }

            var surfaceEntity = entityManager.GetComponentData <Parent>(agentEntity).Value;

            if (surfaceEntity == Entity.Null)
            {
                return(false);
            }

            if (surfaceEntity == hitSurfaceEntity)
            {
                return(true);
            }

            if (!entityManager.HasComponent <NavJumpableBufferElement>(surfaceEntity))
            {
                return(false);
            }

            var jumpableSurfaces = entityManager.GetBuffer <NavJumpableBufferElement>(surfaceEntity);

            for (var i = 0; i < jumpableSurfaces.Length; ++i)
            {
                if (hitSurfaceEntity == jumpableSurfaces[i])
                {
                    return(true);
                }
            }

            return(false);
        }
    public static bool CastRay(float3 start, float3 end, out Unity.Physics.RaycastHit result, CollisionWorld world, CollisionFilter filter)
    {
        var input = new RaycastInput
        {
            Start  = start,
            End    = end,
            Filter = filter,
        };

        return(world.CastRay(input, out result));
    }
Пример #12
0
        /// <summary>
        /// creates and returns the pokemoon's PhysicsCollider
        /// </summary>
        /// <param name="pokemonName">Name of the pokemon</param>
        /// <returns>PhysicsCollider</returns>
        public static PhysicsCollider getPokemonPhysicsCollider(string pokemonName, PokemonEntityData ped,
                                                                CollisionFilter collisionFilter = new CollisionFilter(), float scale = 1f, Unity.Physics.Material material = new Unity.Physics.Material(),
                                                                int groupIndex = 1)
        {
            ///FUTURE UPDATE
            ///allow specific colliders to recieve specific filters and materials!

            //needs collision groups
            PhysicsCollider physicsCollider = new PhysicsCollider {
            };
            Quaternion rotation             = new quaternion();

            //if default collision filter is detected then create one realted to the pokemon
            if (collisionFilter.Equals(new CollisionFilter()))
            {
                Debug.Log("Creating new Collision Filter");
                collisionFilter = new CollisionFilter
                {
                    BelongsTo    = TriggerEventClass.Pokemon | TriggerEventClass.Collidable,
                    CollidesWith = TriggerEventClass.Collidable,
                    GroupIndex   = groupIndex
                };
            }
            if (material.Equals(new Unity.Physics.Material()))
            {
                material = GetPokemonColliderMaterial(StringToPokedexEntry(pokemonName));
            }
            switch (pokemonName)
            {
            case "Cubone":
                var colliders = new NativeArray <CompoundCollider.ColliderBlobInstance>(5, Allocator.Temp);
                colliders[0] = new CompoundCollider.ColliderBlobInstance
                {
                    Collider = Unity.Physics.SphereCollider.Create(new SphereGeometry {
                        Center = new float3(0, 0.27f, 0.03f), Radius = 0.225f
                    }, collisionFilter, material),
                    CompoundFromChild = new RigidTransform {
                        pos = new float3 {
                            x = 0, y = 0, z = 0
                        }, rot = quaternion.identity
                    }
                };
                var a = GenerateCapsuleData(float3.zero, Vector3.right, 0.1f, 0.3f);
                rotation.SetFromToRotation(Vector3.right, new Vector3(0, 90f, 0));
                colliders[1] = new CompoundCollider.ColliderBlobInstance
                {
                    Collider = Unity.Physics.CapsuleCollider.Create(new CapsuleGeometry {
                        Vertex0 = a.pointA, Vertex1 = a.pointB, Radius = 0.1f
                    }, collisionFilter, material),
                    CompoundFromChild = new RigidTransform {
                        pos = new float3(-0.17f, 0.19f, 0), rot = rotation
                    }
                };
                colliders[2] = new CompoundCollider.ColliderBlobInstance
                {
                    Collider = Unity.Physics.CapsuleCollider.Create(new CapsuleGeometry {
                        Vertex0 = a.pointA, Vertex1 = a.pointB, Radius = 0.1f
                    }, collisionFilter, material),
                    CompoundFromChild = new RigidTransform {
                        pos = new float3(0.17f, 0.19f, 0), rot = rotation
                    }
                };
                colliders[3] = new CompoundCollider.ColliderBlobInstance
                {
                    Collider = Unity.Physics.SphereCollider.Create(new SphereGeometry {
                        Center = float3.zero, Radius = 0.23f
                    }, collisionFilter, material),
                    CompoundFromChild = new RigidTransform {
                        pos = new float3(0, 0.75f, 0.03f), rot = rotation
                    }
                };
                a            = GenerateCapsuleData(float3.zero, Vector3.right, 0.1f, 0.3f);
                rotation     = Quaternion.Euler(0, 90f, 26f);
                colliders[4] = new CompoundCollider.ColliderBlobInstance
                {
                    Collider = Unity.Physics.CapsuleCollider.Create(new CapsuleGeometry {
                        Vertex0 = a.pointA, Vertex1 = a.pointB, Radius = 0.1f
                    }, collisionFilter, material),
                    CompoundFromChild = new RigidTransform {
                        pos = new float3(0, 0.63f, 0.33f), rot = rotation
                    }
                };
                physicsCollider = new PhysicsCollider {
                    Value = CompoundCollider.Create(colliders)
                };
                if (scale > 1f)
                {
                    Debug.LogWarning("Cannot scale Cubone");
                }
                colliders.Dispose();
                break;

            case "Electrode":
                Debug.Log("Creating PHysicwsCollider for Electrode");
                physicsCollider = new PhysicsCollider {
                    Value = Unity.Physics.SphereCollider.Create(new SphereGeometry
                    {
                        Center = float3.zero,
                        Radius = ped.Height / 2 * scale
                    },
                                                                collisionFilter,
                                                                material
                                                                )
                };
                break;

            default:
                Debug.LogError("Failed to find collider for pokemon \"" + pokemonName + "\"");
                physicsCollider = new PhysicsCollider
                {
                    Value = Unity.Physics.SphereCollider.Create(new SphereGeometry
                    {
                        Center = float3.zero,
                        Radius = ped.Height / 2 * scale
                    },
                                                                collisionFilter,
                                                                material
                                                                )
                };
                break;
            }
            //		Debug.Log("Returning Physics Collide for \""+pokemonName+"\"");
            return(physicsCollider);
        }
Пример #13
0
        public static CompoundCollider.ColliderBlobInstance[] GeneratePokemonCollider(int i, CollisionFilter collisionFilter, Unity.Physics.Material material, int groupIndex = 1, float scale = 1f)
        {
            CompoundCollider.ColliderBlobInstance[] colliders = new CompoundCollider.ColliderBlobInstance[0];
            Quaternion rotation = new Quaternion();

            switch (i)
            {
            case 104:
                colliders    = new CompoundCollider.ColliderBlobInstance[5];
                colliders[0] = new CompoundCollider.ColliderBlobInstance
                {
                    Collider = Unity.Physics.SphereCollider.Create(new SphereGeometry {
                        Center = new float3(0, 0.27f, 0.03f), Radius = 0.225f
                    }, collisionFilter, material),
                    CompoundFromChild = new RigidTransform {
                        pos = new float3 {
                            x = 0, y = 0, z = 0
                        }, rot = quaternion.identity
                    }
                };
                var a = GenerateCapsuleData(float3.zero, Vector3.right, 0.1f, 0.3f);
                rotation.SetFromToRotation(Vector3.right, new Vector3(0, 90f, 0));
                colliders[1] = new CompoundCollider.ColliderBlobInstance
                {
                    Collider = Unity.Physics.CapsuleCollider.Create(new CapsuleGeometry {
                        Vertex0 = a.pointA, Vertex1 = a.pointB, Radius = 0.1f
                    }, collisionFilter, material),
                    CompoundFromChild = new RigidTransform {
                        pos = new float3(-0.17f, 0.19f, 0), rot = rotation
                    }
                };
                colliders[2] = new CompoundCollider.ColliderBlobInstance
                {
                    Collider = Unity.Physics.CapsuleCollider.Create(new CapsuleGeometry {
                        Vertex0 = a.pointA, Vertex1 = a.pointB, Radius = 0.1f
                    }, collisionFilter, material),
                    CompoundFromChild = new RigidTransform {
                        pos = new float3(0.17f, 0.19f, 0), rot = rotation
                    }
                };
                colliders[3] = new CompoundCollider.ColliderBlobInstance
                {
                    Collider = Unity.Physics.SphereCollider.Create(new SphereGeometry {
                        Center = float3.zero, Radius = 0.23f
                    }, collisionFilter, material),
                    CompoundFromChild = new RigidTransform {
                        pos = new float3(0, 0.75f, 0.03f), rot = rotation
                    }
                };
                a            = GenerateCapsuleData(float3.zero, Vector3.right, 0.1f, 0.3f);
                rotation     = Quaternion.Euler(0, 90f, 26f);
                colliders[4] = new CompoundCollider.ColliderBlobInstance
                {
                    Collider = Unity.Physics.CapsuleCollider.Create(new CapsuleGeometry {
                        Vertex0 = a.pointA, Vertex1 = a.pointB, Radius = 0.1f
                    }, collisionFilter, material),
                    CompoundFromChild = new RigidTransform {
                        pos = new float3(0, 0.63f, 0.33f), rot = rotation
                    }
                };
                break;

            case 101:
                colliders    = new CompoundCollider.ColliderBlobInstance[1];
                colliders[0] = new CompoundCollider.ColliderBlobInstance
                {
                    Collider = Unity.Physics.SphereCollider.Create(new SphereGeometry
                    {
                        Center = float3.zero,
                        Radius = PokemonBaseEntityData[i].Height / 2
                    },
                                                                   collisionFilter,
                                                                   material
                                                                   )
                };
                break;

            default:
                Debug.LogWarning("Failed to find collider for pokemon \"" + PokedexEntryToString((ushort)i) + "\"");
                colliders    = new CompoundCollider.ColliderBlobInstance[1];
                colliders[0] = new CompoundCollider.ColliderBlobInstance
                {
                    Collider = Unity.Physics.SphereCollider.Create(new SphereGeometry
                    {
                        Center = float3.zero,
                        Radius = PokemonBaseEntityData[i].Height > 0 ? PokemonBaseEntityData[i].Height / 2 : 1f
                    },
                                                                   collisionFilter,
                                                                   material
                                                                   )
                };
                break;
            }
            return(colliders);
        }
Пример #14
0
        public static bool HasLayer(this CollisionFilter filter, int layer)
        {
            uint mask = 1u << layer;

            return((filter.BelongsTo & mask) == mask);
        }
    protected override void OnUpdate()
    {
        //Get Physic World
        PhysicsWorld physicsWorld = buildPhysicsWorld.PhysicsWorld;

        //Create ECB
        var entityCommandBuffer = endSimulationEntityCommandBufferSystem.CreateCommandBuffer().ToConcurrent();

        //Create parallel writer
        NativeQueue <BulletInfo> .ParallelWriter events = bulletEvents.AsParallelWriter();

        //Get all enemy existing
        ComponentDataContainer <EnemyTag> enemies = new ComponentDataContainer <EnemyTag>
        {
            Components = GetComponentDataFromEntity <EnemyTag>(true)
        };
        //Get all entities with life
        ComponentDataContainer <LifeComponent> entitiesLife = new ComponentDataContainer <LifeComponent>
        {
            Components = GetComponentDataFromEntity <LifeComponent>(true)
        };
        //
        ComponentDataContainer <DropChanceComponent> dropChance = new ComponentDataContainer <DropChanceComponent>
        {
            Components = GetComponentDataFromEntity <DropChanceComponent>(true)
        };
        //Get Player entity
        Entity player = GameVariables.Player.Entity;

        JobHandle job = Entities.ForEach((Entity entity, int entityInQueryIndex, ref DamageProjectile projectile,
                                          ref Translation translation, in Rotation rotation, in BulletCollider bulletCollider,
                                          in BulletPreviousPositionData previousPosition) =>
        {
            //Create Personal Filter for each Bullet
            CollisionFilter filter = new CollisionFilter
            {
                BelongsTo    = bulletCollider.BelongsTo.Value,
                CollidesWith = bulletCollider.CollidesWith.Value,
                GroupIndex   = bulletCollider.GroupIndex
            };

            //Find direction
            float3 direction = translation.Value - previousPosition.Value;
            direction        = math.normalizesafe(direction);

            //Find Vector to add
            float3 offset   = default;
            float offsetRad = math.radians(90f);
            float cos       = math.cos(offsetRad);
            float sin       = math.sin(offsetRad);
            offset.x        = direction.x * cos - direction.z * sin;
            offset.z        = direction.x * sin + direction.z * cos;
            offset         *= projectile.Radius;

            //Create Ray Inputs
            RaycastInput middleRayCast =
                GetRayCastInput(filter, translation.Value, previousPosition.Value, float3.zero);
            RaycastInput rightRayCast =
                GetRayCastInput(filter, translation.Value, previousPosition.Value, offset);
            RaycastInput leftRayCast =
                GetRayCastInput(filter, translation.Value, previousPosition.Value,
                                -offset); //Adding a negative radius

            bool hitDetected   = false;
            Entity hitEntity   = Entity.Null;
            RaycastHit hit     = default;
            float3 hitPosition = default;

            //Try first RayCast
            if (physicsWorld.CollisionWorld.CastRay(middleRayCast, out RaycastHit middleRayCastHit))
            {
                hitDetected = true;
                hit         = middleRayCastHit;
                hitPosition = float3.zero;

                //Get Hit Entity
                hitEntity = physicsWorld.Bodies[middleRayCastHit.RigidBodyIndex].Entity;
            }
            else if (physicsWorld.CollisionWorld.CastRay(rightRayCast, out RaycastHit rightRayCastHit))
            {
                hitDetected = true;
                hit         = rightRayCastHit;
                hitPosition = -offset;

                //Get Hit Entity
                hitEntity = physicsWorld.Bodies[rightRayCastHit.RigidBodyIndex].Entity;
            }
            //Try second RayCast (Only if first one didnt hit)
            else if (physicsWorld.CollisionWorld.CastRay(leftRayCast, out RaycastHit leftRayCastHit))
            {
                hitDetected = true;
                hit         = leftRayCastHit;
                hitPosition = offset;

                //Get Hit Entity
                hitEntity = physicsWorld.Bodies[leftRayCastHit.RigidBodyIndex].Entity;
            }

            //Make sure theres a collision
            if (!hitDetected)
            {
                return;
            }
            //Make sure an Entity was found
            if (hitEntity == Entity.Null)
            {
                return;
            }

            //Make sure collision hasn't been found before
            //TODO

            //Treat Collision

            //Collision = Wall until proven opposite
            BulletInfo.BulletCollisionType collisionType = BulletInfo.BulletCollisionType.ON_WALL;

            //Look if HitEntity is Player's
            if (hitEntity == player)
            {
                collisionType = BulletInfo.BulletCollisionType.ON_PLAYER;
            }
            //Look if HitEntity is an enemy
            else if (enemies.Components.HasComponent(hitEntity))
            {
                collisionType = BulletInfo.BulletCollisionType.ON_ENEMY;
            }

            bool shouldBulletBeDestroyed = true;

            //Damage entity
            if (collisionType != BulletInfo.BulletCollisionType.ON_WALL)
            {
                //Make sure HitEntity has LifeComponent
                if (entitiesLife.Components.HasComponent(hitEntity))
                {
                    //Make sure HitEntity has LifeComponent
                    if (entitiesLife.Components.HasComponent(hitEntity))
                    {
                        //Get LifeComponent of this entity
                        LifeComponent life = entitiesLife.Components[hitEntity];

                        //Decrease life
                        if (player == hitEntity)
                        {
                            shouldBulletBeDestroyed = life.DecrementLifeWithInvincibility();
                        }
                        else if (entitiesLife.Components[hitEntity].Life.Value <= 0)
                        {
                            shouldBulletBeDestroyed = false;
                        }
                        else
                        {
                            life.DecrementLife();
                        }

                        //Set Back
                        entityCommandBuffer.SetComponent(entityInQueryIndex, hitEntity, life);
                    }
                }
            }

            //Destroy bullet
            if (shouldBulletBeDestroyed)
            {
                entityCommandBuffer.DestroyEntity(entityInQueryIndex, entity);
                events.Enqueue(new BulletInfo
                {
                    HitEntity      = hitEntity,
                    ProjectileType = projectile.Type,
                    CollisionType  = collisionType,
                    HitPosition    = hit.Position + hitPosition,
                    HitRotation    = rotation.Value
                });
            }
        }).ScheduleParallel(Dependency);
Пример #16
0
    private static PhysicsCollider CreateBoxCollider(float sizeX, float sizeY, float sizeZ, float centerX, float centerY, float centerZ, CollisionFilter filter, PhysicsMaterial physicsMaterial)
    {
        BoxGeometry boxGeo = new BoxGeometry
        {
            Center      = new float3(centerX, centerY, centerZ),
            Orientation = quaternion.identity,
            Size        = new float3(sizeX, sizeY, sizeZ),
            BevelRadius = 0.05f
        };

        return(new PhysicsCollider {
            Value = BoxCollider.Create(boxGeo, filter, physicsMaterial)
        });
    }
Пример #17
0
    protected unsafe override void OnUpdate()
    {
        var _ecb                  = m_EntityCommandBufferSystem.CreateCommandBuffer();
        var _ecbo                 = m_EntityCommandBufferSystemo.CreateCommandBuffer();
        var _ecbEndSimilation     = m_endSimulationEntityCommandBufferSystem.CreateCommandBuffer();
        var _ecbBeginPresentation = m_beginPresentationEntityCommandBufferSystem.CreateCommandBuffer();

        var            _physicsWorldSystem = World.DefaultGameObjectInjectionWorld.GetExistingSystem <Unity.Physics.Systems.BuildPhysicsWorld>();
        CollisionWorld _collisionWorld     = _physicsWorldSystem.PhysicsWorld.CollisionWorld;
        var            _physicsWorld       = _physicsWorldSystem.PhysicsWorld;

        float3 _startPosition      = ECS_RTSControls.instance._startScreenPosition;
        float3 _endPosition        = ECS_RTSControls.instance._endScreenPosition;
        float3 _lowerLeftPosition  = ECS_RTSControls.instance._lowerLeftScreenPosition;
        float3 _upperRightPosition = ECS_RTSControls.instance._upperRightScreenPosition;

        Dependency = JobHandle.CombineDependencies(Dependency, m_EndFramePhysicsSystem.GetOutputDependency());

        if (_inputReady)
        {
            if (Input_Mouse_0_Up == true && Input_Mouse_0_Up != EntityManager.HasComponent <Input_Mouse_0_Up>(_inputEntity))
            {
                Input_Mouse_0_GetDown = true;
                Input_Mouse_0_Up      = false;
            }

            if (Input_Mouse_0_Up == false && (Input_Mouse_0_Up != EntityManager.HasComponent <Input_Mouse_0_Up>(_inputEntity)))
            {
                Input_Mouse_0_GetUp = true;
                Input_Mouse_0_Up    = true;
            }

            if (Input_Mouse_1_Up == true && (Input_Mouse_1_Up != EntityManager.HasComponent <Input_Mouse_1_Up>(_inputEntity)))
            {
                Input_Mouse_1_GetDown = true;
                Input_Mouse_1_Up      = false;
            }
            if (Input_Mouse_1_Up == false && (Input_Mouse_1_Up != EntityManager.HasComponent <Input_Mouse_1_Up>(_inputEntity)))
            {
                Input_Mouse_1_GetUp = true;
                Input_Mouse_1_Up    = true;
            }
        }
        else
        {
            if (_queryInput.CalculateEntityCount() > 0)
            {
                _inputEntity     = _queryInput.GetSingletonEntity();
                _inputReady      = true;
                Input_Mouse_0_Up = EntityManager.HasComponent <Input_Mouse_0_Up>(_inputEntity);
                Input_Mouse_1_Up = EntityManager.HasComponent <Input_Mouse_1_Up>(_inputEntity);
            }
        }

        if (Time.ElapsedTime > 4)
        {
            /*this.Dependency =  Entities.WithoutBurst().ForEach((in Translation _translation, in UnitSelected _unitSelected, in Selectable _selectable, in GrisTag _grisTag, in Entity _entity) =>
             * {
             *   var e = _ecbEndSimilation.Instantiate(PrefabConvert._DalleVerte);
             *   _ecbEndSimilation.SetComponent<Translation>(e, _translation);
             *   _ecbEndSimilation.DestroyEntity(_entity);
             *   Debug.Log("Unity3d : 'va te faire foutre'");
             *
             * }).Schedule(this.Dependency);*/
        }

        if (Input_Mouse_0_GetUp == true)
        {
            bool  selectOnlyOneEntity  = false;
            float selectionAreaMinSize = 10f;
            float selectionAreaSize    = math.distance(_lowerLeftPosition, _upperRightPosition);
            if (selectionAreaSize < selectionAreaMinSize)
            {
                // Selection area too small
                _lowerLeftPosition  += new float3(-1, -1, 0) * (selectionAreaMinSize - selectionAreaSize) * .5f;
                _upperRightPosition += new float3(+1, +1, 0) * (selectionAreaMinSize - selectionAreaSize) * .5f;
                selectOnlyOneEntity  = true;
            }

            // Deselect all selected Entities
            this.Dependency = Entities.WithAll <UnitSelected>().ForEach((Entity entity) => {
                _ecb.RemoveComponent <UnitSelected>(entity);
            }).Schedule(this.Dependency);



            Unity.Physics.RaycastHit _hit1 = new Unity.Physics.RaycastHit();
            Unity.Physics.RaycastHit _hit2 = new Unity.Physics.RaycastHit();
            Unity.Physics.RaycastHit _hit3 = new Unity.Physics.RaycastHit();
            Unity.Physics.RaycastHit _hit4 = new Unity.Physics.RaycastHit();
            Unity.Physics.RaycastHit _hit5 = new Unity.Physics.RaycastHit();

            var _ray1 = ECS_RTSControls.instance._ray1;
            var _ray2 = ECS_RTSControls.instance._ray2;
            var _ray3 = ECS_RTSControls.instance._ray3;
            var _ray4 = ECS_RTSControls.instance._ray4;
            var _ray5 = ECS_RTSControls.instance._ray5;

            /*RaycastInput _inputo = new RaycastInput()
             * {
             *  Start = _ray1.origin,
             *  End = _ray1.origin + _ray1.direction * 1000,
             *  Filter = new CollisionFilter()
             *  {
             *      BelongsTo = (uint)10 << 10,
             *      CollidesWith = (uint)7 << 8,
             *      GroupIndex = 8
             *  }
             * };*/

            GetRaycastHit(_collisionWorld, _ray1, _ray2, _ray3, _ray4, _ray5, out _hit1, out _hit2, out _hit3, out _hit4, out _hit5);


            var _filter = new CollisionFilter()
            {
                BelongsTo    = ~1u,
                CollidesWith = ~1u, // all 1s, so all layers, collide with everything
                GroupIndex   = 0
            };

            NativeList <ColliderCastHit> _allHits = new NativeList <ColliderCastHit>(Allocator.TempJob);


            _polygonCollider = Unity.Physics.PolygonCollider.CreateQuad(_hit1.Position, _hit2.Position, _hit3.Position, _hit4.Position, _filter);

            /*SphereGeometry sphereGeometry = new SphereGeometry() { Center = float3.zero, Radius = 3 };
             * _sphereCollider = Unity.Physics.SphereCollider.Create(sphereGeometry, _filter);*/
            /*
             * Unity.Physics.ColliderCastInput colliderCastInput = new ColliderCastInput()
             * {
             *  Collider = (Unity.Physics.Collider*)_sphereCollider.GetUnsafePtr(),
             *  Orientation = ECS_RTSControls.instance._camera.transform.rotation,
             *  Start = ECS_RTSControls.instance._camera.transform.position,
             *  End = _ray1.origin + _ray1.direction * 1000
             * };*/
            var _moyPoly = new float3((_hit1.Position.x + _hit2.Position.x + _hit3.Position.x + _hit4.Position.x) / 4,
                                      (_hit1.Position.y + _hit2.Position.y + _hit3.Position.y + _hit4.Position.y) / 4,
                                      (_hit1.Position.z + _hit2.Position.z + _hit3.Position.z + _hit4.Position.z) / 4);



            Debug.Log(_moyPoly + "_moyPoly");

            //var  _pouitCollider = BlobAssetReference<Unity.Physics.Collider>.Create(_polygonCollider.GetUnsafePtr(), 1);

            /* this.Dependency = Job.WithoutBurst().WithCode(() =>
             * {
             *   var e = _ecb.Instantiate(PrefabConvert._CubeRouge);
             *   _ecb.SetComponent<Translation>(e, new Translation { Value = _hit1.Position + new float3(0, 5, 0) });
             *   e = _ecb.Instantiate(PrefabConvert._CubeRouge);
             *   _ecb.SetComponent<Translation>(e, new Translation { Value = _hit2.Position + new float3(0, 5, 0) });
             *   e = _ecb.Instantiate(PrefabConvert._CubeRouge);
             *   _ecb.SetComponent<Translation>(e, new Translation { Value = _hit3.Position + new float3(0, 5, 0) });
             *   e = _ecb.Instantiate(PrefabConvert._CubeRouge);
             *   _ecb.SetComponent<Translation>(e, new Translation { Value = _hit4.Position + new float3(0, 5, 0) });
             * }).Schedule(this.Dependency);
             * Debug.Log(_dalleSelectedQuery.CalculateEntityCount() + "_dalleSelectedQueryCount");
             * Debug.Log(_dalleQuery.CalculateEntityCount() + "_dalleQueryCount");
             *
             * /*Mesh _mesh = new Mesh { }
             *
             * RenderMesh huiaef = new RenderMesh { mesh = }
             *
             * this.Dependency.Complete();*/

            ColliderCastJob _colliderCastJob = new ColliderCastJob();
            _colliderCastJob.CollectAllHits   = true;
            _colliderCastJob.Collider         = (Unity.Physics.Collider *)_polygonCollider.GetUnsafePtr();
            _colliderCastJob.ColliderCastHits = _allHits;
            _colliderCastJob.End         = new float3(0, -2, 0); // _moyPoly;
            _colliderCastJob.Orientation = quaternion.identity;  //ECS_RTSControls.instance._camera.transform.rotation;
            _colliderCastJob.Start       = /*_moyPoly +*/ new float3(0, 5, 0);
            _colliderCastJob.World       = _physicsWorld;
            Dependency = _colliderCastJob.ScheduleSingle(_query, this.Dependency);

            //World.GetOrCreateSystem<StepPhysicsWorld>().FinalSimulationJobHandle.Complete();

            this.Dependency.Complete();

            /*Debug.Log(_query.CalculateEntityCount() + "_queryMovestats");
             * Debug.Log(_allHits.Length + "_allHits.Length");*/
            this.Dependency = Job.WithoutBurst().WithDisposeOnCompletion(_allHits).WithCode(() =>
            {
                for (int i = 0; i < _allHits.Length; i++)
                {
                    _ecbEndSimilation.AddComponent(_allHits[i].Entity, new UnitSelected());
                }

                Debug.Log(_allHits.Length + "entityHits");
            }).Schedule(this.Dependency);

            this.Dependency.Complete();
        }

        if (Input_Mouse_1_Up == false)
        {
            if (Time.ElapsedTime > 2)
            {
                Debug.Log("yoloZoulou");
                this.Dependency = Entities.WithoutBurst().WithAll <PlaneLayer>().WithAll <Player1>().ForEach((Entity entity) => {
                    _ecb.DestroyEntity(entity);//.RemoveComponent<UnitSelected>(entity);
                }).Schedule(this.Dependency);
            }

            //Debug.Log(Input.GetMouseButtonDown(1));
            // Right mouse button down
            float3        targetPosition   = UtilsClass.GetMouseWorldPosition();
            List <float3> movePositionList = GetPositionListAround(targetPosition, new float[] { 10f, 20f, 30f }, new int[] { 5, 10, 20 });
            int           positionIndex    = 0;
            Entities.WithAll <UnitSelected>().ForEach((Entity entity, ref MoveStats _moveStats) => {
                /*moveTo.position = movePositionList[positionIndex];
                 * positionIndex = (positionIndex + 1) % movePositionList.Count;
                 * moveTo.move = true;*/
            }).Schedule();
        }
        //m_EntityCommandBufferSystem.AddJobHandleForProducer(this.Dependency);
        World.GetOrCreateSystem <StepPhysicsWorld>().FinalSimulationJobHandle.Complete();
        this.Dependency.Complete();
        m_EntityCommandBufferSystemo.AddJobHandleForProducer(this.Dependency);
        m_endSimulationEntityCommandBufferSystem.AddJobHandleForProducer(this.Dependency);
        m_EntityCommandBufferSystemo.AddJobHandleForProducer(this.Dependency);

        if (_polygonCollider.IsCreated)
        {
            _polygonCollider.Dispose();
        }
        if (_sphereCollider.IsCreated)
        {
            _sphereCollider.Dispose();
        }
        Input_Mouse_0_GetUp   = false;
        Input_Mouse_0_GetDown = false;
    }
Пример #18
0
    private static PhysicsCollider CreateCapsuleCollider(float bottomPoint, float topPoint, float radius, CollisionFilter filter, PhysicsMaterial physicsMaterial)
    {
        CapsuleGeometry capsuleGeo = new CapsuleGeometry
        {
            Vertex0 = new float3(0f, bottomPoint, 0f),
            Vertex1 = new float3(0f, topPoint, 0f),
            Radius  = radius
        };

        return(new PhysicsCollider {
            Value = CapsuleCollider.Create(capsuleGeo, filter, physicsMaterial)
        });
    }
        private static List <Filter <IUserChangedEvent> > GetFilters(XElement filters, params JointID[] joints)
        {
            IOrderedEnumerable <XElement> myFilters = from node in filters.Descendants()
                                                      orderby node.Attribute(XName.Get("Sequence")).Value ascending
                                                      select node;

            var filterCollection = new List <Filter <IUserChangedEvent> >(myFilters.Count());

            foreach (XElement filter in myFilters)
            {
                Filter <IUserChangedEvent> createdFilter = null;
                if (filter.Name == "FramesFilter")
                {
                    int    fpsCount;
                    string fps = filter.Attribute(XName.Get("FPS")).Value;
                    if (int.TryParse(fps, out fpsCount))
                    {
                        createdFilter = new FramesFilter(fpsCount);
                    }
                    else
                    {
                        createdFilter = new FramesFilter(10);
                    }
                }
                else if (filter.Name == "CollisionFilter")
                {
                    int    x, y, z;
                    string xValue = filter.Attribute(XName.Get("MarginX")).Value;
                    string yValue = filter.Attribute(XName.Get("MarginY")).Value;
                    string zValue = filter.Attribute(XName.Get("MarginZ")).Value;

                    if (int.TryParse(xValue, out x) && int.TryParse(yValue, out y) && int.TryParse(zValue, out z))
                    {
                        createdFilter = new CollisionFilter(new Point3D(x, y, z), joints);
                    }
                    else
                    {
                        var exception = new ArgumentException("You need to provide the XYZ margins");

                        _log.IfError(string.Empty, exception);

                        throw exception;
                    }
                }
                else if (filter.Name == "CorrectionFilter")
                {
                    var correction = new Point3D();
                    correction.X = SafeFloatParse(filter.Attribute(XName.Get("MarginX")));
                    correction.Y = SafeFloatParse(filter.Attribute(XName.Get("MarginY")));
                    correction.Z = SafeFloatParse(filter.Attribute(XName.Get("MarginZ")));
                    JointID joint;

                    //TODO better catch if XML isn't correct? DTD
                    if (Enum.TryParse(filter.Attribute(XName.Get("SkeletonJoint")).Value, out joint))
                    {
                        createdFilter = new CorrectionFilter(joint, correction);
                    }
                    else
                    {
                        var exception = new ArgumentException("You need to provide a SkeletonJoint to correct");

                        _log.IfError(string.Empty, exception);

                        throw exception;
                    }
                }
                else
                {
                    var exception = new ArgumentException("The provided filter isn't supported");

                    _log.IfError(string.Empty, exception);

                    throw exception;
                }

                if (createdFilter != null)
                {
                    filterCollection.Add(createdFilter);
                }
            }
            return(filterCollection);
        }
Пример #20
0
    private static PhysicsCollider CreateMeshCollider(Resource.Mesh mesh, float3 scale, CollisionFilter filter, PhysicsMaterial physicsMaterial)
    {
        UnityEngine.Vector3[] v3Verts = Resource.GetMesh(mesh).vertices;
        float3[] float3Verts          = new float3[v3Verts.Length];
        for (int i = 0; i < v3Verts.Length; i++)
        {
            float3Verts[i] = v3Verts[i] * scale;
        }
        NativeArray <float3> nativeVerts = new NativeArray <float3>(float3Verts, Allocator.Temp);

        return(new PhysicsCollider {
            Value = ConvexCollider.Create(nativeVerts, ConvexHullGenerationParameters.Default, filter, physicsMaterial)
        });
    }
Пример #21
0
    public static bool CastRayFromMouse(float3 cameraPos, float3 mouseWorldPos, float distance, out Unity.Physics.RaycastHit closestHit, CollisionFilter collisionFilter, CollisionWorld collisionWorld)
    {
        float3 origin    = cameraPos;
        float3 direction = math.normalize(mouseWorldPos - origin);

        RaycastInput rayInput = new RaycastInput()
        {
            Start  = origin,
            End    = origin + (direction * distance),
            Filter = collisionFilter
        };

        return(collisionWorld.CastRay(rayInput, out closestHit));
    }
Пример #22
0
    private void CreateRagdoll(float3 positionOffset, quaternion rotationOffset, float3 initialVelocity, int ragdollIndex = 1, bool internalCollisions = false, float rangeGain = 1.0f)
    {
        var entityManager = BasePhysicsDemo.DefaultWorld.EntityManager;

        var entities      = new NativeList <Entity>(Allocator.Temp);
        var rangeModifier = new float2(math.max(0, math.min(rangeGain, 1)));

        // Head
        float  headRadius   = 0.1f;
        float3 headPosition = new float3(0, 1.8f, headRadius);
        Entity head;

        {
            CollisionFilter filter = internalCollisions ? layerFilter(layer.Head, layer.Torso) : groupFilter(-ragdollIndex);
            BlobAssetReference <Unity.Physics.Collider> headCollider = Unity.Physics.CapsuleCollider.Create(new CapsuleGeometry
            {
                Vertex0 = new float3(0, 0, 0),
                Vertex1 = new float3(0, 0, headRadius / 4),
                Radius  = headRadius
            }, filter);
            head = CreateDynamicBody(headPosition, quaternion.identity, headCollider, float3.zero, float3.zero, 5.0f);
        }
        entities.Add(head);

        // Torso
        float3 torsoSize;
        float3 torsoPosition;
        Entity torso;

        {
            //UnityEngine.Mesh torsoMesh = (UnityEngine.Mesh)Resources.Load("torso", typeof(UnityEngine.Mesh));
            torsoSize     = torsoMesh.bounds.size;
            torsoPosition = headPosition - new float3(0, headRadius * 3.0f / 4.0f + torsoSize.y, 0);

            CollisionFilter filter = internalCollisions ? layerFilter(layer.Torso, layer.Thigh | layer.Head | layer.UpperArm | layer.Pelvis) : groupFilter(-ragdollIndex);

            NativeArray <float3> points = new NativeArray <float3>(torsoMesh.vertices.Length, Allocator.TempJob);
            for (int i = 0; i < torsoMesh.vertices.Length; i++)
            {
                points[i] = torsoMesh.vertices[i];
            }
            BlobAssetReference <Unity.Physics.Collider> collider = ConvexCollider.Create(
                points, ConvexHullGenerationParameters.Default, CollisionFilter.Default
                );
            points.Dispose();
            collider.Value.Filter = filter;
            torso = CreateDynamicBody(torsoPosition, quaternion.identity, collider, float3.zero, float3.zero, 20.0f);
        }
        entities.Add(torso);

        // Neck
        {
            float3     pivotHead          = new float3(0, -headRadius, 0);
            float3     pivotTorso         = math.transform(math.inverse(GetBodyTransform(torso)), math.transform(GetBodyTransform(head), pivotHead));
            float3     axisHead           = new float3(0, 0, 1);
            float3     perpendicular      = new float3(1, 0, 0);
            FloatRange coneAngle          = new FloatRange(math.radians(0), math.radians(45)) * rangeModifier;
            FloatRange perpendicularAngle = new FloatRange(math.radians(-30), math.radians(+30)) * rangeModifier;
            FloatRange twistAngle         = new FloatRange(math.radians(-5), math.radians(5)) * rangeModifier;

            var axisTorso = math.rotate(math.inverse(GetBodyTransform(torso).rot), math.rotate(GetBodyTransform(head).rot, axisHead));
            axisTorso = math.rotate(quaternion.AxisAngle(perpendicular, math.radians(10)), axisTorso);

            var headFrame = new BodyFrame {
                Axis = axisHead, PerpendicularAxis = perpendicular, Position = pivotHead
            };
            var torsoFrame = new BodyFrame {
                Axis = axisTorso, PerpendicularAxis = perpendicular, Position = pivotTorso
            };

            PhysicsJoint.CreateRagdoll(headFrame, torsoFrame, coneAngle.Max, perpendicularAngle, twistAngle, out var ragdoll0, out var ragdoll1);
            CreateJoint(ragdoll0, head, torso);
            CreateJoint(ragdoll1, head, torso);
        }

        // Arms
        {
            float           armLength      = 0.25f;
            float           armRadius      = 0.05f;
            CollisionFilter armUpperFilter = internalCollisions ? layerFilter(layer.UpperArm, layer.Torso | layer.Forearm) : groupFilter(-ragdollIndex);
            CollisionFilter armLowerFilter = internalCollisions ? layerFilter(layer.Forearm, layer.UpperArm | layer.Hand) : groupFilter(-ragdollIndex);

            BlobAssetReference <Unity.Physics.Collider> upperArmCollider = Unity.Physics.CapsuleCollider.Create(new CapsuleGeometry
            {
                Vertex0 = new float3(-armLength / 2, 0, 0),
                Vertex1 = new float3(armLength / 2, 0, 0),
                Radius  = armRadius
            }, armUpperFilter);
            BlobAssetReference <Unity.Physics.Collider> foreArmCollider = Unity.Physics.CapsuleCollider.Create(new CapsuleGeometry
            {
                Vertex0 = new float3(-armLength / 2, 0, 0),
                Vertex1 = new float3(armLength / 2, 0, 0),
                Radius  = armRadius
            }, armLowerFilter);

            float           handLength = 0.025f;
            float           handRadius = 0.055f;
            CollisionFilter handFilter = internalCollisions ? layerFilter(layer.Hand, layer.Forearm) : groupFilter(-ragdollIndex);

            BlobAssetReference <Unity.Physics.Collider> handCollider = Unity.Physics.CapsuleCollider.Create(new CapsuleGeometry
            {
                Vertex0 = new float3(-handLength / 2, 0, 0),
                Vertex1 = new float3(handLength / 2, 0, 0),
                Radius  = handRadius
            }, handFilter);

            for (int i = 0; i < 2; i++)
            {
                float s = i * 2 - 1.0f;

                float3 upperArmPosition = torsoPosition + new float3(s * (torsoSize.x + armLength) / 2.0f, 0.9f * torsoSize.y - armRadius, 0.0f);
                Entity upperArm         = CreateDynamicBody(upperArmPosition, quaternion.identity, upperArmCollider, float3.zero, float3.zero, 10.0f);
                float3 foreArmPosition  = upperArmPosition + new float3(armLength * s, 0, 0);
                Entity foreArm          = CreateDynamicBody(foreArmPosition, quaternion.identity, foreArmCollider, float3.zero, float3.zero, 5.0f);
                float3 handPosition     = foreArmPosition + new float3((armLength + handLength) / 2.0f * s, 0, 0);
                Entity hand             = CreateDynamicBody(handPosition, quaternion.identity, handCollider, float3.zero, float3.zero, 2.0f);

                entities.Add(upperArm);
                entities.Add(foreArm);
                entities.Add(hand);

                // shoulder
                {
                    float3     pivotArm           = new float3(-s * armLength / 2.0f, 0, 0);
                    float3     pivotTorso         = math.transform(math.inverse(GetBodyTransform(torso)), math.transform(GetBodyTransform(upperArm), pivotArm));
                    float3     axisArm            = new float3(-s, 0, 0);
                    float3     perpendicularArm   = new float3(0, 1, 0);
                    FloatRange coneAngle          = new FloatRange(math.radians(0), math.radians(80)) * rangeModifier;
                    FloatRange perpendicularAngle = new FloatRange(math.radians(-70), math.radians(20)) * rangeModifier;
                    FloatRange twistAngle         = new FloatRange(math.radians(-5), math.radians(5)) * rangeModifier;

                    var axisTorso = math.rotate(math.inverse(GetBodyTransform(torso).rot), math.rotate(GetBodyTransform(upperArm).rot, axisArm));
                    axisTorso = math.rotate(quaternion.AxisAngle(perpendicularArm, math.radians(-s * 45.0f)), axisTorso);

                    var armFrame = new BodyFrame {
                        Axis = axisArm, PerpendicularAxis = perpendicularArm, Position = pivotArm
                    };
                    var bodyFrame = new BodyFrame {
                        Axis = axisTorso, PerpendicularAxis = perpendicularArm, Position = pivotTorso
                    };

                    PhysicsJoint.CreateRagdoll(armFrame, bodyFrame, coneAngle.Max, perpendicularAngle, twistAngle, out var ragdoll0, out var ragdoll1);
                    CreateJoint(ragdoll0, upperArm, torso);
                    CreateJoint(ragdoll1, upperArm, torso);
                }

                // elbow
                {
                    float3 pivotUpper    = new float3(s * armLength / 2.0f, 0, 0);
                    float3 pivotFore     = -pivotUpper;
                    float3 axis          = new float3(0, -s, 0);
                    float3 perpendicular = new float3(-s, 0, 0);

                    var lowerArmFrame = new BodyFrame {
                        Axis = axis, PerpendicularAxis = perpendicular, Position = pivotFore
                    };
                    var upperArmFrame = new BodyFrame {
                        Axis = axis, PerpendicularAxis = perpendicular, Position = pivotUpper
                    };
                    var hingeRange = new FloatRange(math.radians(0), math.radians(100));
                    hingeRange = (hingeRange - new float2(hingeRange.Mid)) * rangeModifier + hingeRange.Mid;
                    PhysicsJoint hinge = PhysicsJoint.CreateLimitedHinge(lowerArmFrame, upperArmFrame, hingeRange);
                    CreateJoint(hinge, foreArm, upperArm);
                }

                // wrist
                {
                    float3 pivotFore     = new float3(s * armLength / 2.0f, 0, 0);
                    float3 pivotHand     = new float3(-s * handLength / 2.0f, 0, 0);
                    float3 axis          = new float3(0, 0, -s);
                    float3 perpendicular = new float3(0, 0, 1);

                    var handFrame = new BodyFrame {
                        Axis = axis, PerpendicularAxis = perpendicular, Position = pivotHand
                    };
                    var forearmFrame = new BodyFrame {
                        Axis = axis, PerpendicularAxis = perpendicular, Position = pivotFore
                    };
                    var          hingeRange = new FloatRange(math.radians(0), math.radians(135)) * rangeModifier;
                    PhysicsJoint hinge      = PhysicsJoint.CreateLimitedHinge(handFrame, forearmFrame, hingeRange);
                    CreateJoint(hinge, hand, foreArm);
                }
            }
        }

        // Pelvis
        float  pelvisRadius   = 0.08f;
        float  pelvisLength   = 0.22f;
        float3 pelvisPosition = torsoPosition - new float3(0, pelvisRadius * 0.75f, 0.0f);
        Entity pelvis;

        {
            CollisionFilter filter = internalCollisions ? layerFilter(layer.Pelvis, layer.Torso | layer.Thigh) : groupFilter(-ragdollIndex);
            BlobAssetReference <Unity.Physics.Collider> collider = Unity.Physics.CapsuleCollider.Create(new CapsuleGeometry
            {
                Vertex0 = new float3(-pelvisLength / 2, 0, 0),
                Vertex1 = new float3(pelvisLength / 2, 0, 0),
                Radius  = pelvisRadius
            }, filter);
            pelvis = CreateDynamicBody(pelvisPosition, quaternion.identity, collider, float3.zero, float3.zero, 15.0f);
        }
        entities.Add(pelvis);

        // Waist
        {
            float3     pivotTorso         = float3.zero;
            float3     pivotPelvis        = math.transform(math.inverse(GetBodyTransform(pelvis)), math.transform(GetBodyTransform(torso), pivotTorso));
            float3     axis               = new float3(0, 1, 0);
            float3     perpendicular      = new float3(0, 0, 1);
            FloatRange coneAngle          = new FloatRange(math.radians(0), math.radians(5)) * rangeModifier;
            FloatRange perpendicularAngle = new FloatRange(math.radians(-5), math.radians(90)) * rangeModifier;
            FloatRange twistAngle         = new FloatRange(-math.radians(-5), math.radians(5)) * rangeModifier;

            var pelvisFrame = new BodyFrame {
                Axis = axis, PerpendicularAxis = perpendicular, Position = pivotPelvis
            };
            var torsoFrame = new BodyFrame {
                Axis = axis, PerpendicularAxis = perpendicular, Position = pivotTorso
            };
            PhysicsJoint.CreateRagdoll(pelvisFrame, torsoFrame, coneAngle.Max, perpendicularAngle, twistAngle, out var ragdoll0, out var ragdoll1);
            CreateJoint(ragdoll0, pelvis, torso);
            CreateJoint(ragdoll1, pelvis, torso);
        }

        // Legs
        {
            float           thighLength = 0.32f;
            float           thighRadius = 0.08f;
            CollisionFilter thighFilter = internalCollisions ? layerFilter(layer.Thigh, layer.Pelvis | layer.Calf) : groupFilter(-ragdollIndex);
            BlobAssetReference <Unity.Physics.Collider> thighCollider = Unity.Physics.CapsuleCollider.Create(new CapsuleGeometry
            {
                Vertex0 = new float3(0, -thighLength / 2, 0),
                Vertex1 = new float3(0, thighLength / 2, 0),
                Radius  = thighRadius
            }, thighFilter);

            float           calfLength = 0.32f;
            float           calfRadius = 0.06f;
            CollisionFilter calfFilter = internalCollisions ? layerFilter(layer.Calf, layer.Thigh | layer.Foot) : groupFilter(-ragdollIndex);
            BlobAssetReference <Unity.Physics.Collider> calfCollider = Unity.Physics.CapsuleCollider.Create(new CapsuleGeometry
            {
                Vertex0 = new float3(0, -calfLength / 2, 0),
                Vertex1 = new float3(0, calfLength / 2, 0),
                Radius  = calfRadius
            }, calfFilter);

            float           footLength = 0.08f;
            float           footRadius = 0.06f;
            CollisionFilter footFilter = internalCollisions ? layerFilter(layer.Foot, layer.Calf) : groupFilter(-ragdollIndex);
            BlobAssetReference <Unity.Physics.Collider> footCollider = Unity.Physics.CapsuleCollider.Create(new CapsuleGeometry
            {
                Vertex0 = new float3(0),
                Vertex1 = new float3(0, 0, footLength),
                Radius  = footRadius
            }, footFilter);

            for (int i = 0; i < 2; i++)
            {
                float s = i * 2 - 1.0f;

                float3 thighPosition = pelvisPosition + new float3(s * pelvisLength / 2.0f, -thighLength / 2.0f, 0.0f);
                Entity thigh         = CreateDynamicBody(thighPosition, quaternion.identity, thighCollider, float3.zero, float3.zero, 10.0f);
                float3 calfPosition  = thighPosition + new float3(0, -(thighLength + calfLength) / 2.0f, 0);
                Entity calf          = CreateDynamicBody(calfPosition, quaternion.identity, calfCollider, float3.zero, float3.zero, 5.0f);
                float3 footPosition  = calfPosition + new float3(0, -calfLength / 2.0f, 0);
                Entity foot          = CreateDynamicBody(footPosition, quaternion.identity, footCollider, float3.zero, float3.zero, 2.0f);

                entities.Add(thigh);
                entities.Add(calf);
                entities.Add(foot);

                // hip
                {
                    float3     pivotThigh         = new float3(0, thighLength / 2.0f, 0);
                    float3     pivotPelvis        = math.transform(math.inverse(GetBodyTransform(pelvis)), math.transform(GetBodyTransform(thigh), pivotThigh));
                    float3     axisLeg            = new float3(0, -1, 0);
                    float3     perpendicularLeg   = new float3(-s, 0, 0);
                    FloatRange coneAngle          = new FloatRange(math.radians(0), math.radians(60)) * rangeModifier;
                    FloatRange perpendicularAngle = new FloatRange(math.radians(-10), math.radians(40)) * rangeModifier;
                    FloatRange twistAngle         = new FloatRange(-math.radians(5), math.radians(5)) * rangeModifier;

                    var axisPelvis = math.rotate(math.inverse(GetBodyTransform(pelvis).rot), math.rotate(GetBodyTransform(thigh).rot, axisLeg));
                    axisPelvis = math.rotate(quaternion.AxisAngle(perpendicularLeg, math.radians(s * 45.0f)), axisPelvis);

                    var upperLegFrame = new BodyFrame {
                        Axis = axisLeg, PerpendicularAxis = perpendicularLeg, Position = pivotThigh
                    };
                    var pelvisFrame = new BodyFrame {
                        Axis = axisPelvis, PerpendicularAxis = perpendicularLeg, Position = pivotPelvis
                    };

                    PhysicsJoint.CreateRagdoll(upperLegFrame, pelvisFrame, coneAngle.Max, perpendicularAngle, twistAngle, out var ragdoll0, out var ragdoll1);
                    CreateJoint(ragdoll0, thigh, pelvis);
                    CreateJoint(ragdoll1, thigh, pelvis);
                }

                // knee
                {
                    float3 pivotThigh    = new float3(0, -thighLength / 2.0f, 0);
                    float3 pivotCalf     = math.transform(math.inverse(GetBodyTransform(calf)), math.transform(GetBodyTransform(thigh), pivotThigh));
                    float3 axis          = new float3(-1, 0, 0);
                    float3 perpendicular = new float3(0, 0, 1);

                    var lowerLegFrame = new BodyFrame {
                        Axis = axis, PerpendicularAxis = perpendicular, Position = pivotCalf
                    };
                    var upperLegFrame = new BodyFrame {
                        Axis = axis, PerpendicularAxis = perpendicular, Position = pivotThigh
                    };
                    var hingeRange = new FloatRange(math.radians(-90), math.radians(0));
                    hingeRange = (hingeRange - new float2(hingeRange.Mid)) * rangeModifier + hingeRange.Mid;
                    PhysicsJoint hinge = PhysicsJoint.CreateLimitedHinge(lowerLegFrame, upperLegFrame, hingeRange);
                    CreateJoint(hinge, calf, thigh);
                }

                // ankle
                {
                    float3 pivotCalf     = new float3(0, -calfLength / 2.0f, 0);
                    float3 pivotFoot     = float3.zero;
                    float3 axis          = new float3(-1, 0, 0);
                    float3 perpendicular = new float3(0, 0, 1);

                    var footFrame = new BodyFrame {
                        Axis = axis, PerpendicularAxis = perpendicular, Position = pivotFoot
                    };
                    var lowerLegFrame = new BodyFrame {
                        Axis = axis, PerpendicularAxis = perpendicular, Position = pivotCalf
                    };
                    var          hingeRange = new FloatRange(math.radians(-5), math.radians(5)) * rangeModifier;
                    PhysicsJoint hinge      = PhysicsJoint.CreateLimitedHinge(footFrame, lowerLegFrame, hingeRange);
                    CreateJoint(hinge, foot, calf);
                }
            }
        }

        // reposition with offset information
        if (entities.Length > 0)
        {
            for (int i = 0; i < entities.Length; i++)
            {
                var e = entities[i];

                bool isTorso = (i == 1);
                SwapRenderMesh(e, isTorso);

                Translation     positionComponent = entityManager.GetComponentData <Translation>(e);
                Rotation        rotationComponent = entityManager.GetComponentData <Rotation>(e);
                PhysicsVelocity velocityComponent = entityManager.GetComponentData <PhysicsVelocity>(e);

                float3     position = positionComponent.Value;
                quaternion rotation = rotationComponent.Value;

                float3 localPosition = position - pelvisPosition;
                localPosition = math.rotate(rotationOffset, localPosition);

                position = localPosition + pelvisPosition + positionOffset;
                rotation = math.mul(rotation, rotationOffset);

                positionComponent.Value = position;
                rotationComponent.Value = rotation;

                velocityComponent.Linear = initialVelocity;

                entityManager.SetComponentData <PhysicsVelocity>(e, velocityComponent);
                entityManager.SetComponentData <Translation>(e, positionComponent);
                entityManager.SetComponentData <Rotation>(e, rotationComponent);
            }
        }
    }
Пример #23
0
    private void CreateRagdoll(float3 positionOffset, quaternion rotationOffset, int ragdollIndex = 1, bool internalCollisions = false)
    {
        var entities = new NativeList <Entity>(Allocator.Temp);

        // Head
        float  headRadius   = 0.1f;
        float3 headPosition = new float3(0, 1.8f, 0);
        Entity head;

        {
            CollisionFilter filter = internalCollisions ? layerFilter(layer.Head, layer.Torso) : groupFilter(-ragdollIndex);
            BlobAssetReference <Unity.Physics.Collider> collider = Unity.Physics.SphereCollider.Create(new SphereGeometry
            {
                Center = float3.zero,
                Radius = headRadius
            }, filter);
            head = CreateDynamicBody(headPosition, quaternion.identity, collider, float3.zero, float3.zero, 5.0f);
        }
        entities.Add(head);

        // Torso
        float3 torsoSize;
        float3 torsoPosition;
        Entity torso;

        {
            //UnityEngine.Mesh torsoMesh = (UnityEngine.Mesh)Resources.Load("torso", typeof(UnityEngine.Mesh));
            torsoSize     = torsoMesh.bounds.size;
            torsoPosition = headPosition - new float3(0, headRadius * 3.0f / 4.0f + torsoSize.y, 0);

            CollisionFilter filter = internalCollisions ? layerFilter(layer.Torso, layer.Thigh | layer.Head | layer.UpperArm | layer.Pelvis) : groupFilter(-ragdollIndex);

            NativeArray <float3> points = new NativeArray <float3>(torsoMesh.vertices.Length, Allocator.TempJob);
            for (int i = 0; i < torsoMesh.vertices.Length; i++)
            {
                points[i] = torsoMesh.vertices[i];
            }
            BlobAssetReference <Unity.Physics.Collider> collider = ConvexCollider.Create(
                points, ConvexHullGenerationParameters.Default, CollisionFilter.Default
                );
            points.Dispose();
            collider.Value.Filter = filter;
            torso = CreateDynamicBody(torsoPosition, quaternion.identity, collider, float3.zero, float3.zero, 20.0f);
        }
        entities.Add(torso);

        // Neck
        {
            float3 pivotHead             = new float3(0, -headRadius, 0);
            float3 pivotBody             = math.transform(math.inverse(GetBodyTransform(torso)), math.transform(GetBodyTransform(head), pivotHead));
            float3 axis                  = new float3(0, 1, 0);
            float3 perpendicular         = new float3(0, 0, 1);
            float  coneAngle             = (float)math.PI / 5.0f;
            float  minPerpendicularAngle = 0.0f;           // unlimited
            float  maxPerpendicularAngle = (float)math.PI; // unlimited
            float  twistAngle            = (float)math.PI / 3.0f;

            BlobAssetReference <JointData> ragdoll0, ragdoll1;
            JointData.CreateRagdoll(pivotHead, pivotBody, axis, axis, perpendicular, perpendicular,
                                    coneAngle, minPerpendicularAngle, maxPerpendicularAngle, -twistAngle, twistAngle,
                                    out ragdoll0, out ragdoll1);
            CreateJoint(ragdoll0, head, torso);
            CreateJoint(ragdoll1, head, torso);
        }

        // Arms
        {
            float           armLength      = 0.25f;
            float           armRadius      = 0.05f;
            CollisionFilter armUpperFilter = internalCollisions ? layerFilter(layer.UpperArm, layer.Torso | layer.Forearm) : groupFilter(-ragdollIndex);
            CollisionFilter armLowerFilter = internalCollisions ? layerFilter(layer.Forearm, layer.UpperArm | layer.Hand) : groupFilter(-ragdollIndex);

            BlobAssetReference <Unity.Physics.Collider> upperArmCollider = Unity.Physics.CapsuleCollider.Create(new CapsuleGeometry
            {
                Vertex0 = new float3(-armLength / 2, 0, 0),
                Vertex1 = new float3(armLength / 2, 0, 0),
                Radius  = armRadius
            }, armUpperFilter);
            BlobAssetReference <Unity.Physics.Collider> foreArmCollider = Unity.Physics.CapsuleCollider.Create(new CapsuleGeometry
            {
                Vertex0 = new float3(-armLength / 2, 0, 0),
                Vertex1 = new float3(armLength / 2, 0, 0),
                Radius  = armRadius
            }, armLowerFilter);

            float           handLength = 0.025f;
            float           handRadius = 0.055f;
            CollisionFilter handFilter = internalCollisions ? layerFilter(layer.Hand, layer.Forearm) : groupFilter(-ragdollIndex);

            BlobAssetReference <Unity.Physics.Collider> handCollider = Unity.Physics.CapsuleCollider.Create(new CapsuleGeometry
            {
                Vertex0 = new float3(-handLength / 2, 0, 0),
                Vertex1 = new float3(handLength / 2, 0, 0),
                Radius  = handRadius
            }, handFilter);

            for (int i = 0; i < 2; i++)
            {
                float s = i * 2 - 1.0f;

                float3 upperArmPosition = torsoPosition + new float3(s * (torsoSize.x + armLength) / 2.0f, 0.9f * torsoSize.y - armRadius, 0.0f);
                Entity upperArm         = CreateDynamicBody(upperArmPosition, quaternion.identity, upperArmCollider, float3.zero, float3.zero, 10.0f);
                float3 foreArmPosition  = upperArmPosition + new float3(armLength * s, 0, 0);
                Entity foreArm          = CreateDynamicBody(foreArmPosition, quaternion.identity, foreArmCollider, float3.zero, float3.zero, 5.0f);
                float3 handPosition     = foreArmPosition + new float3((armLength + handLength) / 2.0f * s, 0, 0);
                Entity hand             = CreateDynamicBody(handPosition, quaternion.identity, handCollider, float3.zero, float3.zero, 2.0f);

                entities.Add(upperArm);
                entities.Add(foreArm);
                entities.Add(hand);

                // shoulder
                {
                    float3 pivotArm              = new float3(-s * armLength / 2.0f, 0, 0);
                    float3 pivotBody             = math.transform(math.inverse(GetBodyTransform(torso)), math.transform(GetBodyTransform(upperArm), pivotArm));
                    float3 axis                  = new float3(s, 0, 0);
                    float3 perpendicular         = new float3(0, 0, 1);
                    float  coneAngle             = (float)math.PI / 2.0f;
                    float  minPerpendicularAngle = 0.0f;
                    float  maxPerpendicularAngle = (float)math.PI / 2.0f;
                    float  twistAngle            = (float)math.PI / 4.0f;

                    BlobAssetReference <JointData> ragdoll0, ragdoll1;
                    JointData.CreateRagdoll(pivotArm, pivotBody, axis, axis, perpendicular, perpendicular,
                                            coneAngle, minPerpendicularAngle, maxPerpendicularAngle, -twistAngle, twistAngle,
                                            out ragdoll0, out ragdoll1);
                    CreateJoint(ragdoll0, upperArm, torso);
                    CreateJoint(ragdoll1, upperArm, torso);
                }

                // elbow
                {
                    float3 pivotUpper    = new float3(s * armLength / 2.0f, 0, 0);
                    float3 pivotFore     = -pivotUpper;
                    float3 axis          = new float3(0, -s, 0);
                    float3 perpendicular = new float3(s, 0, 0);
                    float  minAngle      = 0.0f;
                    float  maxAngle      = 3.0f;

                    BlobAssetReference <JointData> hinge = JointData.CreateLimitedHinge(pivotFore, pivotUpper, axis, axis, perpendicular, perpendicular, minAngle, maxAngle);
                    CreateJoint(hinge, foreArm, upperArm);
                }

                // wrist
                {
                    float3 pivotFore     = new float3(s * armLength / 2.0f, 0, 0);
                    float3 pivotHand     = new float3(-s * handLength / 2.0f, 0, 0);
                    float3 axis          = new float3(0, -s, 0);
                    float3 perpendicular = new float3(s, 0, 0);
                    float  minAngle      = -0.3f;
                    float  maxAngle      = 0.6f;

                    BlobAssetReference <JointData> hinge = JointData.CreateLimitedHinge(pivotHand, pivotFore, axis, axis, perpendicular, perpendicular, minAngle, maxAngle);
                    CreateJoint(hinge, hand, foreArm);
                }
            }
        }

        // Pelvis
        float  pelvisRadius   = 0.08f;
        float  pelvisLength   = 0.22f;
        float3 pelvisPosition = torsoPosition - new float3(0, pelvisRadius * 0.75f, 0.0f);
        Entity pelvis;

        {
            CollisionFilter filter = internalCollisions ? layerFilter(layer.Pelvis, layer.Torso | layer.Thigh) : groupFilter(-ragdollIndex);
            BlobAssetReference <Unity.Physics.Collider> collider = Unity.Physics.CapsuleCollider.Create(new CapsuleGeometry
            {
                Vertex0 = new float3(-pelvisLength / 2, 0, 0),
                Vertex1 = new float3(pelvisLength / 2, 0, 0),
                Radius  = pelvisRadius
            }, filter);
            pelvis = CreateDynamicBody(pelvisPosition, quaternion.identity, collider, float3.zero, float3.zero, 15.0f);
        }
        entities.Add(pelvis);

        // Waist
        {
            float3 pivotTorso            = float3.zero;
            float3 pivotPelvis           = math.transform(math.inverse(GetBodyTransform(pelvis)), math.transform(GetBodyTransform(torso), pivotTorso));
            float3 axis                  = new float3(0, -1, 0);
            float3 perpendicular         = new float3(0, 0, 1);
            float  coneAngle             = 0.1f;
            float  minPerpendicularAngle = -0.1f;
            float  maxPerpendicularAngle = (float)math.PI;
            float  twistAngle            = 0.1f;

            BlobAssetReference <JointData> ragdoll0, ragdoll1;
            JointData.CreateRagdoll(pivotPelvis, pivotTorso, axis, axis, perpendicular, perpendicular,
                                    coneAngle, minPerpendicularAngle, maxPerpendicularAngle, -twistAngle, twistAngle,
                                    out ragdoll0, out ragdoll1);
            CreateJoint(ragdoll0, pelvis, torso);
            CreateJoint(ragdoll1, pelvis, torso);
        }

        // Legs
        {
            float           thighLength = 0.32f;
            float           thighRadius = 0.08f;
            CollisionFilter thighFilter = internalCollisions ? layerFilter(layer.Thigh, layer.Pelvis | layer.Calf) : groupFilter(-ragdollIndex);
            BlobAssetReference <Unity.Physics.Collider> thighCollider = Unity.Physics.CapsuleCollider.Create(new CapsuleGeometry
            {
                Vertex0 = new float3(0, -thighLength / 2, 0),
                Vertex1 = new float3(0, thighLength / 2, 0),
                Radius  = thighRadius
            }, thighFilter);

            float           calfLength = 0.32f;
            float           calfRadius = 0.06f;
            CollisionFilter calfFilter = internalCollisions ? layerFilter(layer.Calf, layer.Thigh | layer.Foot) : groupFilter(-ragdollIndex);
            BlobAssetReference <Unity.Physics.Collider> calfCollider = Unity.Physics.CapsuleCollider.Create(new CapsuleGeometry
            {
                Vertex0 = new float3(0, -calfLength / 2, 0),
                Vertex1 = new float3(0, calfLength / 2, 0),
                Radius  = calfRadius
            }, calfFilter);

            float           footLength = 0.08f;
            float           footRadius = 0.06f;
            CollisionFilter footFilter = internalCollisions ? layerFilter(layer.Foot, layer.Calf) : groupFilter(-ragdollIndex);
            BlobAssetReference <Unity.Physics.Collider> footCollider = Unity.Physics.CapsuleCollider.Create(new CapsuleGeometry
            {
                Vertex0 = new float3(0),
                Vertex1 = new float3(0, 0, footLength),
                Radius  = footRadius
            }, footFilter);

            for (int i = 0; i < 2; i++)
            {
                float s = i * 2 - 1.0f;

                float3 thighPosition = pelvisPosition + new float3(s * pelvisLength / 2.0f, -thighLength / 2.0f, 0.0f);
                Entity thigh         = CreateDynamicBody(thighPosition, quaternion.identity, thighCollider, float3.zero, float3.zero, 10.0f);
                float3 calfPosition  = thighPosition + new float3(0, -(thighLength + calfLength) / 2.0f, 0);
                Entity calf          = CreateDynamicBody(calfPosition, quaternion.identity, calfCollider, float3.zero, float3.zero, 5.0f);
                float3 footPosition  = calfPosition + new float3(0, -calfLength / 2.0f, 0);
                Entity foot          = CreateDynamicBody(footPosition, quaternion.identity, footCollider, float3.zero, float3.zero, 2.0f);

                entities.Add(thigh);
                entities.Add(calf);
                entities.Add(foot);

                // hip
                {
                    float3 pivotThigh            = new float3(0, thighLength / 2.0f, 0);
                    float3 pivotBody             = math.transform(math.inverse(GetBodyTransform(torso)), math.transform(GetBodyTransform(thigh), pivotThigh));
                    float3 axis                  = new float3(0, -1, 0);
                    float3 perpendicular         = new float3(s, 0, 0);
                    float  coneAngle             = (float)math.PI / 4.0f;
                    float  minPerpendicularAngle = 0.0f;
                    float  maxPerpendicularAngle = 0.2f + (float)math.PI / 2.0f;
                    float  twistAngle            = 0.2f;

                    BlobAssetReference <JointData> ragdoll0, ragdoll1;
                    JointData.CreateRagdoll(pivotThigh, pivotBody, axis, axis, perpendicular, perpendicular,
                                            coneAngle, minPerpendicularAngle, maxPerpendicularAngle, -twistAngle, twistAngle,
                                            out ragdoll0, out ragdoll1);
                    CreateJoint(ragdoll0, thigh, torso);
                    CreateJoint(ragdoll1, thigh, torso);
                }

                // knee
                {
                    float3 pivotThigh    = new float3(0, -thighLength / 2.0f, 0);
                    float3 pivotCalf     = math.transform(math.inverse(GetBodyTransform(calf)), math.transform(GetBodyTransform(thigh), pivotThigh));
                    float3 axis          = new float3(-1, 0, 0);
                    float3 perpendicular = new float3(0, 0, 1);
                    float  minAngle      = -1.2f;
                    float  maxAngle      = 0.0f;

                    BlobAssetReference <JointData> hinge = JointData.CreateLimitedHinge(pivotCalf, pivotThigh, axis, axis, perpendicular, perpendicular, minAngle, maxAngle);
                    CreateJoint(hinge, calf, thigh);
                }

                // ankle
                {
                    float3 pivotCalf     = new float3(0, -calfLength / 2.0f, 0);
                    float3 pivotFoot     = float3.zero;
                    float3 axis          = new float3(-1, 0, 0);
                    float3 perpendicular = new float3(0, 0, 1);
                    float  minAngle      = -0.4f;
                    float  maxAngle      = 0.1f;

                    BlobAssetReference <JointData> hinge = JointData.CreateLimitedHinge(pivotFoot, pivotCalf, axis, axis, perpendicular, perpendicular, minAngle, maxAngle);
                    CreateJoint(hinge, foot, calf);
                }
            }
        }

        var entityManager = BasePhysicsDemo.DefaultWorld.EntityManager;

        // reposition with offset information
        if (entities.Length > 0)
        {
            float3 center = float3.zero;
            for (int i = 0; i < entities.Length; i++)
            {
                var e = entities[i];
                center += entityManager.GetComponentData <Translation>(e).Value;
            }
            center /= entities.Length;
            for (int i = 0; i < entities.Length; i++)
            {
                var         e = entities[i];
                Translation positionComponent = entityManager.GetComponentData <Translation>(e);
                Rotation    rotationComponent = entityManager.GetComponentData <Rotation>(e);

                float3     position = positionComponent.Value;
                quaternion rotation = rotationComponent.Value;

                float3 localPosition = position - center;
                localPosition = math.rotate(rotationOffset, localPosition);

                position = localPosition + center + positionOffset;
                rotation = math.mul(rotation, rotationOffset);

                positionComponent.Value = position;
                rotationComponent.Value = rotation;

                entityManager.SetComponentData <Translation>(e, positionComponent);
                entityManager.SetComponentData <Rotation>(e, rotationComponent);
            }
        }
    }
Пример #24
0
    protected override void OnUpdate()
    {
        var physicsWorld     = _physicsWorldSystem.PhysicsWorld;
        var physicsBodiesMap = _physicsWorldSystem.EntityToPhysicsBody;
        var hits             = new NativeList <DistanceHit>(Allocator.TempJob);
        var outActions       = _gameActionSystem.CreateRequestBuffer();
        var teams            = GetComponentDataFromEntity <Team>(isReadOnly: true);
        var firstInstigators = GetComponentDataFromEntity <FirstInstigator>(isReadOnly: true);
        var tileColliderTags = GetComponentDataFromEntity <TileColliderTag>(isReadOnly: true);
        var mutedActions     = GetSingletonBuffer <MutedContactActionElement>();

        Entities
        .WithReadOnly(physicsWorld)
        .WithReadOnly(physicsBodiesMap)
        .WithReadOnly(teams)
        .WithReadOnly(firstInstigators)
        .WithReadOnly(tileColliderTags)
        .ForEach((Entity entity, DynamicBuffer <ActionOnOverlap> actionsOnOverlap, in FixTranslation position) =>
        {
            bool ignoreLocalEntity      = physicsBodiesMap.Lookup.TryGetValue(entity, out int physicsBody);
            ActorFilterInfo entityAInfo = Helpers.GetActorFilterInfo(entity, teams, firstInstigators, tileColliderTags);

            for (int i = 0; i < actionsOnOverlap.Length; i++)
            {
                var actionOnContact = actionsOnOverlap[i];

                PointDistanceInput pointDistance = new PointDistanceInput()
                {
                    Filter      = CollisionFilter.ThatCollidesWith(actionOnContact.OverlapFilter),
                    MaxDistance = (float)actionOnContact.OverlapRadius,
                    Position    = (float2)position.Value
                };

                if (ignoreLocalEntity)
                {
                    pointDistance.Ignore = new IgnoreHit(physicsBody);
                }

                if (physicsWorld.CalculateDistance(pointDistance, ref hits))
                {
                    foreach (var hit in hits)
                    {
                        if (mutedActions.IsMuted(entity, hit.Entity, actionOnContact.Data.Id))
                        {
                            continue;
                        }

                        ActorFilterInfo entityBInfo = Helpers.GetActorFilterInfo(hit.Entity, teams, firstInstigators, tileColliderTags);

                        if (Helpers.ActorFilterMatches(entityAInfo, entityBInfo, actionOnContact.Data.ActionFilter))
                        {
                            outActions.Add(new GameActionRequest()
                            {
                                Instigator   = entity,
                                Target       = hit.Entity,
                                ActionEntity = actionOnContact.Data.ActionEntity,
                            });

                            if (actionOnContact.Data.SameTargetCooldown > 0)
                            {
                                mutedActions.Add(new MutedContactActionElement()
                                {
                                    Instigator            = entity,
                                    ContactActionBufferId = actionOnContact.Data.Id,
                                    ExpirationTime        = actionOnContact.Data.SameTargetCooldown,
                                    Target = hit.Entity
                                });
                            }
                        }
                    }

                    hits.Clear();
                }
            }
        }).WithDisposeOnCompletion(hits)
        .Schedule();

        _gameActionSystem.HandlesToWaitFor.Add(Dependency);
    }
Пример #25
0
        public unsafe void OverlapTaskFilteringTest([Values(2, 10, 33, 100)] int elementCount)
        {
            elementCount *= 2;
            int numNodes = elementCount + Constants.MaxNumTreeBranches;

            var points      = new NativeArray <PointAndIndex>(elementCount, Allocator.Temp, NativeArrayOptions.UninitializedMemory);
            var aabbs       = new NativeArray <Aabb>(elementCount, Allocator.Temp, NativeArrayOptions.UninitializedMemory);
            var bodyFilters = new NativeArray <CollisionFilter>(elementCount, Allocator.Temp, NativeArrayOptions.UninitializedMemory);

            InitInputWithCopyArrays(points, aabbs, bodyFilters);

            var   nodes    = new NativeArray <Node>(numNodes, Allocator.Temp, NativeArrayOptions.UninitializedMemory);
            Node *nodesPtr = (Node *)nodes.GetUnsafePtr();

            var seenUnfiltered = new HashSet <BodyIndexPair>();
            {
                var bvhUnfiltered = new BoundingVolumeHierarchy(nodes);
                bvhUnfiltered.Build(points, aabbs, out int numNodesOut);
                bvhUnfiltered.CheckIntegrity();

                EverythingWriter pairWriter = new EverythingWriter {
                    SeenPairs = seenUnfiltered
                };
                BoundingVolumeHierarchy.TreeOverlap(ref pairWriter, nodesPtr, nodesPtr);
            }

            var nodeFilters = new NativeArray <CollisionFilter>(numNodes, Allocator.Temp, NativeArrayOptions.UninitializedMemory);
            var bvhFiltered = new BoundingVolumeHierarchy(nodes, nodeFilters);
            int numNodesFilteredTree;

            bvhFiltered.Build(points, aabbs, out numNodesFilteredTree);
            bvhFiltered.BuildCombinedCollisionFilter(bodyFilters, 0, numNodesFilteredTree - 1);

            var filteredCollisionPairs = new NativeStream(1, Allocator.TempJob);

            NativeStream.Writer filteredPairWriter = filteredCollisionPairs.AsWriter();
            filteredPairWriter.BeginForEachIndex(0);
            CollisionFilter *bodyFiltersPtr = (CollisionFilter *)bodyFilters.GetUnsafePtr();
            var bufferedPairs = new Broadphase.BodyPairWriter(&filteredPairWriter, bodyFiltersPtr, bodyFiltersPtr, 0, 0);

            CollisionFilter *nodeFiltersPtr = (CollisionFilter *)nodeFilters.GetUnsafePtr();

            BoundingVolumeHierarchy.TreeOverlap(ref bufferedPairs, nodesPtr, nodesPtr, nodeFiltersPtr, nodeFiltersPtr);
            bufferedPairs.Close();
            filteredPairWriter.EndForEachIndex();

            NativeStream.Reader filteredPairReader = filteredCollisionPairs.AsReader();
            filteredPairReader.BeginForEachIndex(0);

            // Check that every pair in our filtered set also appears in the unfiltered set
            while (filteredPairReader.RemainingItemCount > 0)
            {
                var pair = filteredPairReader.Read <BodyIndexPair>();

                Assert.IsTrue(seenUnfiltered.Contains(pair));
                seenUnfiltered.Remove(pair); // Remove the pair
            }

            // Pairs were removed, so the only remaining ones should be filtered
            foreach (BodyIndexPair pair in seenUnfiltered)
            {
                bool shouldCollide = CollisionFilter.IsCollisionEnabled(bodyFilters[pair.BodyAIndex], bodyFilters[pair.BodyBIndex]);
                Assert.IsFalse(shouldCollide);
            }

            nodeFilters.Dispose();
            nodes.Dispose();
            bodyFilters.Dispose();
            aabbs.Dispose();
            points.Dispose();
            filteredCollisionPairs.Dispose();
        }
Пример #26
0
    public override void UpdateSystem()
    {
        CollisionWorld            collisionWorld    = m_physicsWorldBuilder.PhysicsWorld.CollisionWorld;
        NativeArray <Translation> cameraTranslation = m_entityQuery.ToComponentDataArrayAsync <Translation>(Allocator.TempJob, out JobHandle cameraTranslationHandle);
        float3                      mousePos        = m_inputManagementSystem.InputData.mouseInput.mouseWorldPos;
        CollisionFilter             collisionFilter = m_collisionFilter;
        NativeArray <RaycastResult> raycastResult   = m_raycastResult;

        ComponentDataFromEntity <UnitTag> unitTagLookup = GetComponentDataFromEntity <UnitTag>();

        Dependency = JobHandle.CombineDependencies(Dependency, cameraTranslationHandle);

        Dependency = Job
                     .WithReadOnly(cameraTranslation)
                     .WithCode(() =>
        {
            float3 cameraPos = cameraTranslation[0].Value;
            RaycastResult result;
            if (InputManagementSystem.CastRayFromMouse(cameraPos, mousePos, 1000.0f, out Unity.Physics.RaycastHit closestHit, collisionFilter, collisionWorld))
            {
                Entity hitEntity = closestHit.Entity;

                if (HasComponent <EnemyTag>(hitEntity))
                {
                    result = new RaycastResult
                    {
                        raycastTargetType   = RaycastTargetType.Enemy,
                        hitPosition         = closestHit.Position,
                        raycastTargetEntity = closestHit.Entity
                    };
                    raycastResult[0] = result;

                    return;
                }

                if (HasComponent <UnitTag>(hitEntity))
                {
                    result = new RaycastResult
                    {
                        raycastTargetType   = RaycastTargetType.Unit,
                        hitPosition         = closestHit.Position,
                        raycastTargetEntity = closestHit.Entity
                    };
                    raycastResult[0] = result;

                    return;
                }

                if (HasComponent <ResourceNode>(hitEntity))
                {
                    result = new RaycastResult
                    {
                        raycastTargetType   = RaycastTargetType.ResourceNode,
                        hitPosition         = closestHit.Position,
                        raycastTargetEntity = closestHit.Entity
                    };
                    raycastResult[0] = result;

                    return;
                }
                result = new RaycastResult
                {
                    raycastTargetType   = RaycastTargetType.Ground,
                    hitPosition         = closestHit.Position,
                    raycastTargetEntity = closestHit.Entity
                };
                raycastResult[0] = result;
            }
Пример #27
0
        public void Test1()
        {
            CollisionObject object1A = new CollisionObject();
              object1A.CollisionGroup = 1;
              CollisionObject object1B = new CollisionObject();
              object1B.CollisionGroup = 1;

              CollisionObject object2A = new CollisionObject();
              object2A.CollisionGroup = 2;
              CollisionObject object2B = new CollisionObject();
              object2B.CollisionGroup = 2;

              CollisionFilter filter = new CollisionFilter();

              Assert.IsTrue(filter.Filter(new Pair<CollisionObject>(object1A, object1B)));
              Assert.IsTrue(filter.Filter(new Pair<CollisionObject>(object2A, object2B)));
              Assert.IsTrue(filter.Filter(new Pair<CollisionObject>(object2A, object1B)));
              Assert.IsTrue(filter.Filter(new Pair<CollisionObject>(object1A, object2B)));

              filter.Set(2, false);
              Assert.IsTrue(filter.Filter(new Pair<CollisionObject>(object1A, object1B)));
              Assert.IsFalse(filter.Filter(new Pair<CollisionObject>(object2A, object2B)));
              Assert.IsFalse(filter.Filter(new Pair<CollisionObject>(object2A, object1B)));
              Assert.IsFalse(filter.Filter(new Pair<CollisionObject>(object1A, object2B)));

              filter.Set(1, false);
              Assert.IsFalse(filter.Filter(new Pair<CollisionObject>(object1A, object1B)));
              Assert.IsFalse(filter.Filter(new Pair<CollisionObject>(object2A, object2B)));
              Assert.IsFalse(filter.Filter(new Pair<CollisionObject>(object2A, object1B)));
              Assert.IsFalse(filter.Filter(new Pair<CollisionObject>(object1A, object2B)));

              filter.Set(2, true);
              Assert.IsFalse(filter.Filter(new Pair<CollisionObject>(object1A, object1B)));
              Assert.IsTrue(filter.Filter(new Pair<CollisionObject>(object2A, object2B)));
              Assert.IsFalse(filter.Filter(new Pair<CollisionObject>(object2A, object1B)));
              Assert.IsFalse(filter.Filter(new Pair<CollisionObject>(object1A, object2B)));

              filter.Set(1, true);
              Assert.IsTrue(filter.Filter(new Pair<CollisionObject>(object1A, object1B)));
              Assert.IsTrue(filter.Filter(new Pair<CollisionObject>(object2A, object2B)));
              Assert.IsTrue(filter.Filter(new Pair<CollisionObject>(object2A, object1B)));
              Assert.IsTrue(filter.Filter(new Pair<CollisionObject>(object1A, object2B)));

              filter.Set(1, 1, false);
              Assert.IsFalse(filter.Filter(new Pair<CollisionObject>(object1A, object1B)));
              Assert.IsTrue(filter.Filter(new Pair<CollisionObject>(object2A, object2B)));
              Assert.IsTrue(filter.Filter(new Pair<CollisionObject>(object2A, object1B)));
              Assert.IsTrue(filter.Filter(new Pair<CollisionObject>(object1A, object2B)));

              filter.Set(2, 1, false);
              Assert.IsFalse(filter.Filter(new Pair<CollisionObject>(object1A, object1B)));
              Assert.IsTrue(filter.Filter(new Pair<CollisionObject>(object2A, object2B)));
              Assert.IsFalse(filter.Filter(new Pair<CollisionObject>(object2A, object1B)));
              Assert.IsFalse(filter.Filter(new Pair<CollisionObject>(object1A, object2B)));

              filter.Set(1, 1, true);
              filter.Set(1, 2, true);
              Assert.IsTrue(filter.Filter(new Pair<CollisionObject>(object1A, object1B)));
              Assert.IsTrue(filter.Filter(new Pair<CollisionObject>(object2A, object2B)));
              Assert.IsTrue(filter.Filter(new Pair<CollisionObject>(object2A, object1B)));
              Assert.IsTrue(filter.Filter(new Pair<CollisionObject>(object1A, object2B)));

              filter.Set(object1A, object2B, false);
              filter.Set(object1B, object1A, false);
              Assert.IsFalse(filter.Filter(new Pair<CollisionObject>(object1A, object1B)));
              Assert.IsTrue(filter.Filter(new Pair<CollisionObject>(object2A, object2B)));
              Assert.IsTrue(filter.Filter(new Pair<CollisionObject>(object2A, object1B)));
              Assert.IsFalse(filter.Filter(new Pair<CollisionObject>(object1A, object2B)));

              filter.Set(object1A, object2B, true);
              filter.Set(object1B, object1A, true);
              Assert.IsTrue(filter.Filter(new Pair<CollisionObject>(object1A, object1B)));
              Assert.IsTrue(filter.Filter(new Pair<CollisionObject>(object2A, object2B)));
              Assert.IsTrue(filter.Filter(new Pair<CollisionObject>(object2A, object1B)));
              Assert.IsTrue(filter.Filter(new Pair<CollisionObject>(object1A, object2B)));

              filter.Set(object1B, object1A, false);
              filter.Reset();
              Assert.IsTrue(filter.Filter(new Pair<CollisionObject>(object1A, object1B)));
              Assert.IsTrue(filter.Filter(new Pair<CollisionObject>(object2A, object2B)));
              Assert.IsTrue(filter.Filter(new Pair<CollisionObject>(object2A, object1B)));
              Assert.IsTrue(filter.Filter(new Pair<CollisionObject>(object1A, object2B)));
        }
Пример #28
0
 public static uint GetFilter(CollisionFilter collisionFilter)
 {
     return((uint)(1 << (int)collisionFilter));
 }
Пример #29
0
        private void KinectUserCreated(object sender, KinectUserEventArgs e)
        {
            WindowMessage = "User found";
            lock (SyncRoot)
            {
                if (_activeUser != null)
                {
                    return;
                }
                _activeUser = _kinect.GetUser(e.User.Id);
                _activeUser.Updated += ActiveUserUpdated;

                var framesFilter = new FramesFilter(15);

                //Initialize filters
                _lefthandRighthandCollision = new CollisionFilter(new Point3D(100, 50, 130), JointID.HandLeft, JointID.HandRight);
                _lefthandHeadCollision = new CollisionFilter(new Point3D(150, 30, 500), JointID.HandLeft, JointID.Head);
                _lefthandRightShoulderCollision = new CollisionFilter(new Point3D(50, 50, 300), JointID.HandLeft, JointID.ShoulderRight);
                _righthandHeadCollision = new CollisionFilter(new Point3D(125, 40, 150), JointID.HandRight, JointID.Head);
                _righthandLeftShoulderCollision = new CollisionFilter(new Point3D(50, 50, 300), JointID.HandRight, JointID.ShoulderLeft);
                _righthandRightHipCollision = new CollisionFilter(new Point3D(80, 30, 200), JointID.HandRight, JointID.HipRight);

                //Initialize gestures
                _lefthandRighthandGesture = new SelfTouchGesture(1);
                _lefthandHeadGesture = new SelfTouchGesture(1);
                _lefthandRightShoulderGesture = new SelfTouchGesture(1);
                _righthandHeadGesture = new SelfTouchGesture(1);
                _righthandLeftShoulderGesture = new SelfTouchGesture(1);
                _righthandRightHipGesture = new SelfTouchGesture(1);

                //Attach filters and gestures
                _activeUser.AttachPipeline(framesFilter);
                framesFilter.AttachPipeline(_lefthandRighthandCollision);
                framesFilter.AttachPipeline(_lefthandHeadCollision);
                framesFilter.AttachPipeline(_lefthandRightShoulderCollision);
                framesFilter.AttachPipeline(_righthandHeadCollision);
                framesFilter.AttachPipeline(_righthandLeftShoulderCollision);
                framesFilter.AttachPipeline(_righthandRightHipCollision);
                _lefthandRighthandCollision.AttachPipeline(_lefthandRighthandGesture);
                _lefthandHeadCollision.AttachPipeline(_lefthandHeadGesture);
                _lefthandRightShoulderCollision.AttachPipeline(_lefthandRightShoulderGesture);
                _righthandHeadCollision.AttachPipeline(_righthandHeadGesture);
                _righthandLeftShoulderCollision.AttachPipeline(_righthandLeftShoulderGesture);
                _righthandRightHipCollision.AttachPipeline(_righthandRightHipGesture);

                _righthandLeftShoulderGesture.SelfTouchDetected += SwitchMode;

                //Debug info
                //_righthandLeftShoulderCollision.Filtered += (s, args) => ShowDebugInfo(args, "Filter info: ");
                _lefthandRightShoulderGesture.SelfTouchDetected += FireCustomEvent;
                SwitchMode(null, null);
            }
        }
Пример #30
0
        private static List<Filter<IUserChangedEvent>> GetStandardSelfTouchFilters(JointID[] joints)
        {
            if (joints.Length < 2)
            {
                throw new ArgumentException("At least 2 joints are expected for a SelfTouchGesture", "joints");
            }

            var list = new List<Filter<IUserChangedEvent>>();
            list.Add(new FramesFilter(6));
            var correctionFilter = new CorrectionFilter(joints[1], new Point3D());
            var collisionFilter = new CollisionFilter(new Point3D(), joints);
            return list;
        }