Beispiel #1
0
        void GenerateArgumentPermutations(StateData stateData, NativeList <ActionKey> argumentPermutations)
        {
            var AgentFilter = new NativeArray <ComponentType>(2, Allocator.Temp)
            {
                [0] = ComponentType.ReadWrite <Generated.AI.Planner.StateRepresentation.Agent>(), [1] = ComponentType.ReadWrite <Unity.AI.Planner.DomainLanguage.TraitBased.Location>(),
            };
            var CollectibleFilter = new NativeArray <ComponentType>(2, Allocator.Temp)
            {
                [0] = ComponentType.ReadWrite <Unity.AI.Planner.DomainLanguage.TraitBased.Location>(), [1] = ComponentType.ReadWrite <Generated.AI.Planner.StateRepresentation.Collectible>(),
            };
            var AgentObjectIndices = new NativeList <int>(2, Allocator.Temp);

            stateData.GetTraitBasedObjectIndices(AgentObjectIndices, AgentFilter);

            var CollectibleObjectIndices = new NativeList <int>(2, Allocator.Temp);

            stateData.GetTraitBasedObjectIndices(CollectibleObjectIndices, CollectibleFilter);

            var AgentBuffer       = stateData.AgentBuffer;
            var CollectibleBuffer = stateData.CollectibleBuffer;



            for (int i0 = 0; i0 < AgentObjectIndices.Length; i0++)
            {
                var AgentIndex  = AgentObjectIndices[i0];
                var AgentObject = stateData.TraitBasedObjects[AgentIndex];

                if (!(AgentBuffer[AgentObject.AgentIndex].Ammo < 5))
                {
                    continue;
                }



                for (int i1 = 0; i1 < CollectibleObjectIndices.Length; i1++)
                {
                    var CollectibleIndex  = CollectibleObjectIndices[i1];
                    var CollectibleObject = stateData.TraitBasedObjects[CollectibleIndex];


                    if (!(CollectibleBuffer[CollectibleObject.CollectibleIndex].Provides == Consumable.Ammo))
                    {
                        continue;
                    }

                    if (!(CollectibleBuffer[CollectibleObject.CollectibleIndex].Active == true))
                    {
                        continue;
                    }



                    var actionKey = new ActionKey(k_MaxArguments)
                    {
                        ActionGuid           = ActionGuid,
                        [k_AgentIndex]       = AgentIndex,
                        [k_CollectibleIndex] = CollectibleIndex,
                    };
                    argumentPermutations.Add(actionKey);
                }
            }
            AgentObjectIndices.Dispose();
            CollectibleObjectIndices.Dispose();
            AgentFilter.Dispose();
            CollectibleFilter.Dispose();
        }
Beispiel #2
0
    public static unsafe void CollideAndIntegrate(
        CharacterControllerStepInput stepInput, float characterMass, bool affectBodies, Unity.Physics.Collider *collider,
        ref RigidTransform transform, ref float3 linearVelocity, ref NativeStream.Writer deferredImpulseWriter,
        NativeList <StatefulCollisionEvent> collisionEvents = default, NativeList <StatefulTriggerEvent> triggerEvents = default)
    {
        // Copy parameters
        float        deltaTime = stepInput.DeltaTime;
        float3       up        = stepInput.Up;
        PhysicsWorld world     = stepInput.World;

        float remainingTime = deltaTime;

        float3     newPosition = transform.pos;
        quaternion orientation = transform.rot;
        float3     newVelocity = linearVelocity;

        float maxSlopeCos = math.cos(stepInput.MaxSlope);

        const float timeEpsilon = 0.000001f;

        for (int i = 0; i < stepInput.MaxIterations && remainingTime > timeEpsilon; i++)
        {
            NativeList <SurfaceConstraintInfo> constraints = new NativeList <SurfaceConstraintInfo>(k_DefaultConstraintsCapacity, Allocator.Temp);

            // Do a collider cast
            {
                float3 displacement = newVelocity * remainingTime;
                NativeList <ColliderCastHit> triggerHits = default;
                if (triggerEvents.IsCreated)
                {
                    triggerHits = new NativeList <ColliderCastHit>(k_DefaultQueryHitsCapacity / 4, Allocator.Temp);
                }
                NativeList <ColliderCastHit> castHits = new NativeList <ColliderCastHit>(k_DefaultQueryHitsCapacity, Allocator.Temp);
                CharacterControllerAllHitsCollector <ColliderCastHit> collector = new CharacterControllerAllHitsCollector <ColliderCastHit>(
                    stepInput.RigidBodyIndex, 1.0f, ref castHits, world, triggerHits);
                ColliderCastInput input = new ColliderCastInput()
                {
                    Collider    = collider,
                    Orientation = orientation,
                    Start       = newPosition,
                    End         = newPosition + displacement
                };
                world.CastCollider(input, ref collector);

                // Iterate over hits and create constraints from them
                for (int hitIndex = 0; hitIndex < collector.NumHits; hitIndex++)
                {
                    ColliderCastHit hit = collector.AllHits[hitIndex];
                    CreateConstraint(stepInput.World, stepInput.Up,
                                     hit.RigidBodyIndex, hit.ColliderKey, hit.Position, hit.SurfaceNormal, math.dot(-hit.SurfaceNormal, hit.Fraction * displacement),
                                     stepInput.SkinWidth, maxSlopeCos, ref constraints);
                }

                // Update trigger events
                if (triggerEvents.IsCreated)
                {
                    UpdateTriggersSeen(stepInput, triggerHits, triggerEvents, collector.MinHitFraction);
                }
            }

            // Then do a collider distance for penetration recovery,
            // but only fix up penetrating hits
            {
                // Collider distance query
                NativeList <DistanceHit> distanceHits = new NativeList <DistanceHit>(k_DefaultQueryHitsCapacity, Allocator.Temp);
                CharacterControllerAllHitsCollector <DistanceHit> distanceHitsCollector = new CharacterControllerAllHitsCollector <DistanceHit>(
                    stepInput.RigidBodyIndex, stepInput.ContactTolerance, ref distanceHits, world);
                {
                    ColliderDistanceInput input = new ColliderDistanceInput()
                    {
                        MaxDistance = stepInput.ContactTolerance,
                        Transform   = transform,
                        Collider    = collider
                    };
                    world.CalculateDistance(input, ref distanceHitsCollector);
                }

                // Iterate over penetrating hits and fix up distance and normal
                int numConstraints = constraints.Length;
                for (int hitIndex = 0; hitIndex < distanceHitsCollector.NumHits; hitIndex++)
                {
                    DistanceHit hit = distanceHitsCollector.AllHits[hitIndex];
                    if (hit.Distance < stepInput.SkinWidth)
                    {
                        bool found = false;

                        // Iterate backwards to locate the original constraint before the max slope constraint
                        for (int constraintIndex = numConstraints - 1; constraintIndex >= 0; constraintIndex--)
                        {
                            SurfaceConstraintInfo constraint = constraints[constraintIndex];
                            if (constraint.RigidBodyIndex == hit.RigidBodyIndex &&
                                constraint.ColliderKey.Equals(hit.ColliderKey))
                            {
                                // Fix up the constraint (normal, distance)
                                {
                                    // Create new constraint
                                    CreateConstraintFromHit(world, hit.RigidBodyIndex, hit.ColliderKey,
                                                            hit.Position, hit.SurfaceNormal, hit.Distance,
                                                            stepInput.SkinWidth, out SurfaceConstraintInfo newConstraint);

                                    // Resolve its penetration
                                    ResolveConstraintPenetration(ref newConstraint);

                                    // Write back
                                    constraints[constraintIndex] = newConstraint;
                                }

                                found = true;
                                break;
                            }
                        }

                        // Add penetrating hit not caught by collider cast
                        if (!found)
                        {
                            CreateConstraint(stepInput.World, stepInput.Up,
                                             hit.RigidBodyIndex, hit.ColliderKey, hit.Position, hit.SurfaceNormal, hit.Distance,
                                             stepInput.SkinWidth, maxSlopeCos, ref constraints);
                        }
                    }
                }
            }

            // Min delta time for solver to break
            float minDeltaTime = 0.0f;
            if (math.lengthsq(newVelocity) > k_SimplexSolverEpsilonSq)
            {
                // Min delta time to travel at least 1cm
                minDeltaTime = 0.01f / math.length(newVelocity);
            }

            // Solve
            float3 prevVelocity = newVelocity;
            float3 prevPosition = newPosition;
            SimplexSolver.Solve(remainingTime, minDeltaTime, up, stepInput.MaxMovementSpeed, constraints, ref newPosition, ref newVelocity, out float integratedTime);

            // Apply impulses to hit bodies and store collision events
            if (affectBodies || collisionEvents.IsCreated)
            {
                CalculateAndStoreDeferredImpulsesAndCollisionEvents(stepInput, affectBodies, characterMass,
                                                                    prevVelocity, constraints, ref deferredImpulseWriter, collisionEvents);
            }

            // Calculate new displacement
            float3 newDisplacement = newPosition - prevPosition;

            // If simplex solver moved the character we need to re-cast to make sure it can move to new position
            if (math.lengthsq(newDisplacement) > k_SimplexSolverEpsilon)
            {
                // Check if we can walk to the position simplex solver has suggested
                var newCollector = new CharacterControllerClosestHitCollector <ColliderCastHit>(constraints, world, stepInput.RigidBodyIndex, 1.0f);

                ColliderCastInput input = new ColliderCastInput()
                {
                    Collider    = collider,
                    Orientation = orientation,
                    Start       = prevPosition,
                    End         = prevPosition + newDisplacement
                };

                world.CastCollider(input, ref newCollector);

                if (newCollector.NumHits > 0)
                {
                    ColliderCastHit hit = newCollector.ClosestHit;

                    // Move character along the newDisplacement direction until it reaches this new contact
                    {
                        Assert.IsTrue(hit.Fraction >= 0.0f && hit.Fraction <= 1.0f);

                        integratedTime *= hit.Fraction;
                        newPosition     = prevPosition + newDisplacement * hit.Fraction;
                    }
                }
            }

            // Reduce remaining time
            remainingTime -= integratedTime;

            // Write back position so that the distance query will update results
            transform.pos = newPosition;
        }

        // Write back final velocity
        linearVelocity = newVelocity;
    }
Beispiel #3
0
    private static void UpdateTriggersSeen <T>(CharacterControllerStepInput stepInput, NativeList <T> triggerHits,
                                               NativeList <StatefulTriggerEvent> currentFrameTriggerEvents, float maxFraction) where T : struct, IQueryResult
    {
        var world = stepInput.World;

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

            if (hit.Fraction > maxFraction)
            {
                continue;
            }

            var found = false;
            for (int j = 0; j < currentFrameTriggerEvents.Length; j++)
            {
                var triggerEvent = currentFrameTriggerEvents[j];
                if ((triggerEvent.EntityB == hit.Entity) &&
                    (triggerEvent.ColliderKeyB.Value == hit.ColliderKey.Value))
                {
                    found = true;
                    break;
                }
            }
            if (!found)
            {
                currentFrameTriggerEvents.Add(new StatefulTriggerEvent(world.Bodies[stepInput.RigidBodyIndex].Entity, hit.Entity,
                                                                       stepInput.RigidBodyIndex, hit.RigidBodyIndex, ColliderKey.Empty, hit.ColliderKey));
            }
        }
    }
        public static void DifferenceSorted <T>(this NativeArray <T> a, ref NativeArray <T> b, ref NativeList <T> resultCapacityOfA)
            where T : struct, IComparable <T>
        {
            var i = 0;
            var j = 0;

            while (i < a.Length && j < b.Length)
            {
                if (a[i].CompareTo(b[j]) < 0)
                {
                    resultCapacityOfA.Add(a[i]);
                    i++;
                }
                else if (b[j].CompareTo(a[i]) < 0)
                {
                    j++;
                }
                else
                {
                    i++;
                    j++;
                }
            }

            while (i < a.Length)
            {
                resultCapacityOfA.Add(a[i]);
                ++i;
            }
        }
Beispiel #5
0
 private void OnEnable()
 {
     RenderMeshes = new QuadTerrainRenderMesh[9];
     Planes       = new NativeArray <float4>(6, Allocator.Persistent);
     RenderNodes  = new NativeList <RenderNode>(Allocator.Persistent);
 }
Beispiel #6
0
    // Start is called before the first frame update
    void Start()
    {
        var areaMeasurement = new AreaMeasurement()
        {
            V0 = this.V0,
            V1 = this.V1,
            V2 = this.V2,
            V3 = this.V3
        };
        var measure = areaMeasurement.Measure();

        _width  = measure.x;
        _height = measure.y;

        var activeSamples = new NativeList <float2>(Allocator.TempJob);
        var results       = new NativeList <float2>(Allocator.TempJob);

        var cellSize = _radius / math.sqrt(2);

        var gridWidth  = (int)math.ceil(_width / cellSize);
        var gridHeight = (int)math.ceil(_height / cellSize);

        var gridArray = new NativeArray <float2>(gridWidth * gridHeight, Allocator.TempJob);

        for (var i = 0; i < gridArray.Length; i++)
        {
            gridArray[i] = new float2(float.MinValue, float.MinValue);
        }

        var poissonDiscSampler = new PoissonDiscSampler()
        {
            // Area Parameters
            Width      = _width,
            Height     = _height,
            Radius     = _radius,
            CellSize   = cellSize,
            RandomSeed = _randomSeed,
            // Grid Parameters
            GridWidth  = gridWidth,
            GridHeight = gridHeight,
            GridArray  = gridArray,

            // Origin and angle
            Origin = new float2(V0.position.x, V0.position.z),

            // Sample and Results
            ActiveSamples = activeSamples,
            Result        = results
        };

        var handle = poissonDiscSampler.Schedule();

        handle.Complete();
        Debug.Log($"Length of result is: {results.Length}");
        for (int i = 0; i < results.Length; i++)
        {
            var sampleSphere = GameObject.CreatePrimitive(PrimitiveType.Sphere);
            sampleSphere.transform.position   = new Vector3(results[i].x, 0, results[i].y);
            sampleSphere.transform.localScale = Vector3.one * _sphereSize;
        }
        activeSamples.Dispose();
        results.Dispose();
        gridArray.Dispose();
    }
 internal PickupKeyAction(NativeList <StateEntityKey> statesToExpand, StateDataContext stateDataContext)
 {
     m_StatesToExpand   = statesToExpand.AsDeferredJobArray();
     m_StateDataContext = stateDataContext;
 }
Beispiel #8
0
        public static unsafe void Solve(
            sfloat deltaTime, sfloat minDeltaTime, float3 up, sfloat maxVelocity,
            NativeList <SurfaceConstraintInfo> constraints, ref float3 position, ref float3 velocity, out sfloat integratedTime, bool useConstraintVelocities = true
            )
        {
            // List of planes to solve against (up to 4)
            SurfaceConstraintInfo *supportPlanes = stackalloc SurfaceConstraintInfo[4];
            int numSupportPlanes = 0;

            sfloat remainingTime = deltaTime;
            sfloat currentTime   = sfloat.Zero;

            // Clamp the input velocity to max movement speed
            ClampToMaxLength(maxVelocity, ref velocity);

            while (remainingTime > sfloat.Zero)
            {
                int    hitIndex         = -1;
                sfloat minCollisionTime = remainingTime;

                // Iterate over constraints and solve them
                for (int i = 0; i < constraints.Length; i++)
                {
                    if (constraints[i].Touched)
                    {
                        continue;
                    }

                    SurfaceConstraintInfo constraint = constraints[i];

                    float3 relVel     = velocity - (useConstraintVelocities ? constraint.Velocity : float3.zero);
                    sfloat relProjVel = -math.dot(relVel, constraint.Plane.Normal);
                    if (relProjVel < k_Epsilon)
                    {
                        continue;
                    }

                    // Clamp distance to 0, since penetration is handled by constraint.Velocity already
                    sfloat distance = math.max(constraint.Plane.Distance, sfloat.Zero);
                    if (distance < minCollisionTime * relProjVel)
                    {
                        minCollisionTime = distance / relProjVel;
                        hitIndex         = i;
                    }
                }

                // Integrate
                {
                    currentTime   += minCollisionTime;
                    remainingTime -= minCollisionTime;
                    position      += minCollisionTime * velocity;
                }

                if (hitIndex < 0 || currentTime > minDeltaTime)
                {
                    break;
                }

                // Mark constraint as touched
                {
                    var constraint = constraints[hitIndex];
                    constraint.Touched    = true;
                    constraints[hitIndex] = constraint;
                }

                // Add the hit to the current list of active planes
                supportPlanes[numSupportPlanes] = constraints[hitIndex];
                if (!useConstraintVelocities)
                {
                    supportPlanes[numSupportPlanes].Velocity = float3.zero;
                }
                numSupportPlanes++;

                // Solve support planes
                ExamineActivePlanes(up, supportPlanes, ref numSupportPlanes, ref velocity);

                // Clamp the solved velocity to max movement speed
                ClampToMaxLength(maxVelocity, ref velocity);

                // Can't handle more than 4 support planes
                if (numSupportPlanes == 4)
                {
                    break;
                }
            }

            integratedTime = currentTime;
        }
        public void Convert(Entity entity, EntityManager dstManager, GameObjectConversionSystem conversionSystem)
        {
            var renderEntities = new NativeList <RenderElement>(Allocator.Temp);
            var batchSpans     = new NativeList <BatchedSpanElement>(Allocator.Temp);

            // Flat map the batch of render elements to a single array.
            int startIndex = 0;

            for (int i = 0; i < Batches.Length; i++)
            {
                var currentBatch = Batches[i].Elements;

                for (int j = 0; j < currentBatch.Length; j++)
                {
                    var uiElement = currentBatch[j];
                    var uiEntity  = conversionSystem.GetPrimaryEntity(uiElement);
                    renderEntities.Add(new RenderElement {
                        Value = uiEntity
                    });
                }

                batchSpans.Add(new int2(startIndex, currentBatch.Length));
                startIndex += currentBatch.Length;
            }

            // Build the material property batch by only taking the first element of the BatchedElements.
            // This is due to the first elementing being representative of the entire batch.
            var propertyBatch = new MaterialPropertyBatch {
                Value = new MaterialPropertyBlock[Batches.Length]
            };

            for (int i = 0; i < Batches.Length; i++)
            {
                var block = new MaterialPropertyBlock();

                if (Batches[i].Elements[0].TryGetComponent(out Image image))
                {
                    var texture = image.sprite != null ? image.sprite.texture : Texture2D.whiteTexture;
                    block.SetTexture(ShaderIDConstants.MainTex, texture);

                    for (int k = 0; k < Batches[i].Elements.Length; k++)
                    {
                        var associativeEntity = conversionSystem.GetPrimaryEntity(Batches[i].Elements[k]);
                        dstManager.AddComponentData(associativeEntity, new MaterialPropertyIndex {
                            Value = (ushort)i
                        });
                    }
                }

                propertyBatch.Value[i] = new MaterialPropertyBlock();
            }

            dstManager.AddComponentData(entity, propertyBatch);

            unsafe {
                var renderBatches = dstManager.AddBuffer <RenderElement>(entity);
                var size          = UnsafeUtility.SizeOf <RenderElement>() * renderEntities.Length;

                renderBatches.ResizeUninitialized(renderEntities.Length);
                UnsafeUtility.MemCpy(renderBatches.GetUnsafePtr(), renderEntities.GetUnsafePtr(), size);

                var renderSpans = dstManager.AddBuffer <BatchedSpanElement>(entity);
                size = UnsafeUtility.SizeOf <BatchedSpanElement>() * batchSpans.Length;

                renderSpans.ResizeUninitialized(batchSpans.Length);
                UnsafeUtility.MemCpy(renderSpans.GetUnsafePtr(), batchSpans.GetUnsafePtr(), size);
            }

            renderEntities.Dispose();
            batchSpans.Dispose();
        }
 public StatisticsReport(int bucketSize)
 {
     BucketSize = bucketSize;
     Samples    = new NativeList <SoakStatisticsPoint>(Allocator.Persistent);
 }
        // Steps the simulation immediately on a single thread without spawning any jobs.
        public static void StepImmediate(SimulationStepInput input, ref SimulationContext simulationContext)
        {
            if (input.TimeStep < 0)
            {
                throw new ArgumentOutOfRangeException();
            }
            if (input.NumSolverIterations <= 0)
            {
                throw new ArgumentOutOfRangeException();
            }

            if (input.World.NumDynamicBodies == 0)
            {
                // No need to do anything, since nothing can move
                return;
            }

            // Inform the context of the timeStep
            simulationContext.TimeStep = input.TimeStep;

            // Find all body pairs that overlap in the broadphase
            var dynamicVsDynamicBodyPairs = new NativeStream(1, Allocator.Temp);
            var dynamicVsStaticBodyPairs  = new NativeStream(1, Allocator.Temp);
            {
                var dynamicVsDynamicBodyPairsWriter = dynamicVsDynamicBodyPairs.AsWriter();
                var dynamicVsStaticBodyPairsWriter  = dynamicVsStaticBodyPairs.AsWriter();
                input.World.CollisionWorld.FindOverlaps(ref dynamicVsDynamicBodyPairsWriter, ref dynamicVsStaticBodyPairsWriter);
            }

            // Create dispatch pairs
            var dispatchPairs = new NativeList <DispatchPairSequencer.DispatchPair>(Allocator.Temp);

            DispatchPairSequencer.CreateDispatchPairs(ref dynamicVsDynamicBodyPairs, ref dynamicVsStaticBodyPairs,
                                                      input.World.NumDynamicBodies, input.World.Joints, ref dispatchPairs);

            // Apply gravity and copy input velocities
            Solver.ApplyGravityAndCopyInputVelocities(input.World.DynamicsWorld.MotionDatas, input.World.DynamicsWorld.MotionVelocities,
                                                      simulationContext.InputVelocities, input.TimeStep * input.Gravity);

            // Narrow phase
            var contacts = new NativeStream(1, Allocator.Temp);
            {
                var contactsWriter = contacts.AsWriter();
                NarrowPhase.CreateContacts(ref input.World, dispatchPairs.AsArray(), input.TimeStep, ref contactsWriter);
            }

            // Build Jacobians
            var jacobians = new NativeStream(1, Allocator.Temp);

            {
                var contactsReader  = contacts.AsReader();
                var jacobiansWriter = jacobians.AsWriter();
                Solver.BuildJacobians(ref input.World, input.TimeStep, input.Gravity, input.NumSolverIterations,
                                      dispatchPairs.AsArray(), ref contactsReader, ref jacobiansWriter);
            }

            // Solve Jacobians
            {
                var jacobiansReader       = jacobians.AsReader();
                var collisionEventsWriter = simulationContext.CollisionEventDataStream.AsWriter();
                var triggerEventsWriter   = simulationContext.TriggerEventDataStream.AsWriter();
                Solver.SolveJacobians(ref jacobiansReader, input.World.DynamicsWorld.MotionVelocities, input.TimeStep, input.NumSolverIterations,
                                      ref collisionEventsWriter, ref triggerEventsWriter);
            }

            // Integrate motions
            Integrator.Integrate(input.World.DynamicsWorld.MotionDatas, input.World.DynamicsWorld.MotionVelocities, input.TimeStep);

            // Synchronize the collision world if asked for
            if (input.SynchronizeCollisionWorld)
            {
                input.World.CollisionWorld.UpdateDynamicTree(ref input.World, input.TimeStep, input.Gravity);
            }
        }
Beispiel #12
0
 static void NLClearer <T>(NativeList <T> list) where T : struct
 {
     list.Clear();
 }
Beispiel #13
0
 static void NLDisposer <T>(NativeList <T> list) where T : struct
 {
     list.Dispose();
 }
Beispiel #14
0
    private void Update()
    {
        if (_NumberOfBeamsInPropagation == 0 | _remodelling)
        {
            int beamPropagationSectionInteger;
            int discreteBeaminteger;

            _remodelling = false;
            ;
            if (CheckForSceneUpdates(out discreteBeaminteger, out beamPropagationSectionInteger))
            {
                ;
                CutBeams(discreteBeaminteger, beamPropagationSectionInteger);
            }
            else
            {
                if (_separateObjectInteractions.Count != 0)
                {
                    SendMultiBeams();
                }
                return;
            }
        }

        var descreteBeamsTointeractIndeces = new List <int>();

        for (int i = 0; i < _discreteBeams.Count; i++)
        {
            if (!ChechFloat3IsZero(_discreteBeams[i].DirectionOfPropagation))
            {
                descreteBeamsTointeractIndeces.Add(i);
            }
        }

        var hit       = new RaycastHit();
        Ray ray       = new Ray();
        int layerMask = ~(1 << 8);

        var limitedBeamDirection     = new NativeList <float3>(Allocator.TempJob);
        var limitedBeamPosition      = new NativeList <float3>(Allocator.TempJob);
        var limitedBeamFinalPosition = new NativeList <float3>(Allocator.TempJob);
        var limitedBeamIndeces       = new List <int>();

        for (int i = 0; i < descreteBeamsTointeractIndeces.Count; i++)
        {
            ray.origin    = _discreteBeams[descreteBeamsTointeractIndeces[i]].LastCoordinate;
            ray.direction = _discreteBeams[descreteBeamsTointeractIndeces[i]].DirectionOfPropagation;

            if (Physics.Raycast(ray, out hit, Mathf.Infinity, layerMask))
            {
                if (_ObjectOfInteractionPrevPosition.ContainsKey(hit.collider.gameObject))
                {
                    if (hit.collider.gameObject.transform.position != _ObjectOfInteractionPrevPosition[hit.collider.gameObject].Item1 |
                        hit.collider.gameObject.transform.rotation != _ObjectOfInteractionPrevPosition[hit.collider.gameObject].Item2)
                    {
                        _remodelling = true;
                    }
                }
                else
                {
                    _ObjectOfInteractionPrevPosition.Add(hit.collider.gameObject, new Tuple <Vector3, Quaternion>(hit.collider.gameObject.transform.position, hit.collider.gameObject.transform.rotation));
                }

                _collisionPositionsPerBeam[descreteBeamsTointeractIndeces[i]].Item2.Add(hit.point);

                if (_separateObjectInteractions.ContainsKey(hit.collider.gameObject))
                {
                    _separateObjectInteractions[hit.collider.gameObject].Item1.Add(descreteBeamsTointeractIndeces[i]);
                    _separateObjectInteractions[hit.collider.gameObject].Item2.Add(hit);
                }
                else
                {
                    _separateObjectInteractions.Add(hit.collider.gameObject, new Tuple <List <int>, List <RaycastHit> >(
                                                        new List <int> {
                        descreteBeamsTointeractIndeces[i]
                    },
                                                        new List <RaycastHit> {
                        hit
                    }
                                                        ));
                }
            }
            else
            {
                _NumberOfBeamsInPropagation--;
                limitedBeamDirection.Add(_discreteBeams[descreteBeamsTointeractIndeces[i]].DirectionOfPropagation);
                limitedBeamPosition.Add(_discreteBeams[descreteBeamsTointeractIndeces[i]].LastCoordinate);
                limitedBeamFinalPosition.Add(float3.zero);
                limitedBeamIndeces.Add(descreteBeamsTointeractIndeces[i]);
            }
        }

        var parallelLimitedPropagation = new ParallelLimitedPropagation();

        parallelLimitedPropagation.discreteBeamsDirection     = limitedBeamDirection;
        parallelLimitedPropagation.discreteBeamsPosition      = limitedBeamPosition;
        parallelLimitedPropagation.discreteBeamsFinalPosition = limitedBeamFinalPosition;
        parallelLimitedPropagation.maxLengthOfPropagation     = maxLengthOfPropagation;

        var handleLimitedPropagation = parallelLimitedPropagation.Schedule(limitedBeamDirection.Length, 1);

        var limitedBeamFinalPositionList = new List <float3>();
        var limitedBeamIndecesList       = new List <int>();

        ;
        foreach (var el in _separateObjectInteractions.Keys)
        {
            var discreteBeamsForInteraction = new List <DiscreteBeam>();
            foreach (var index in _separateObjectInteractions[el].Item1)
            {
                discreteBeamsForInteraction.Add(_discreteBeams[index]);
            }
            ;
            InteractionScriptI    interactionScript;
            MultiBeamInteractionI multiBeamInteraction;

            if (el.TryGetComponent <InteractionScriptI>(out interactionScript))
            {
                var result = interactionScript.InteractWithDescreteBeam(discreteBeamsForInteraction, _separateObjectInteractions[el].Item2);
                if (result.Count != _separateObjectInteractions[el].Item1.Count)
                {
                    throw new ArgumentOutOfRangeException("The returned list size is out of range.");
                }
                for (int i = 0; i < _separateObjectInteractions[el].Item1.Count; i++)
                {
                    AssignValuesAfterInteraction(_separateObjectInteractions[el].Item1[i], result[i][0].Item1, result[i][0].Item2, result[i][0].Item3, result[i][0].Item4);
                }
                _keysForClear.Add(el);
                ;
            }
            else
            {
                for (int i = 0; i < _separateObjectInteractions[el].Item1.Count; i++)
                {
                    _NumberOfBeamsInPropagation--;
                    limitedBeamFinalPositionList.Add(_separateObjectInteractions[el].Item2[i].point);
                    limitedBeamIndecesList.Add(_separateObjectInteractions[el].Item1[i]);
                }
                if (!el.TryGetComponent <MultiBeamInteractionI>(out multiBeamInteraction))
                {
                    _keysForClear.Add(el);
                }
                ;
            }
        }

        handleLimitedPropagation.Complete();

        for (int i = 0; i < limitedBeamFinalPosition.Length; i++)
        {
            limitedBeamFinalPositionList.Add(limitedBeamFinalPosition[i]);
            limitedBeamIndecesList.Add(limitedBeamIndeces[i]);
        }
        AssignValuesForLimitedPropagation(limitedBeamIndecesList, limitedBeamFinalPositionList);

        limitedBeamDirection.Dispose();
        limitedBeamPosition.Dispose();
        limitedBeamFinalPosition.Dispose();

        Project();
        ClearInteractionObjectKeys();
    }
Beispiel #15
0
        internal void MoveChunksFrom(
            NativeArray <ArchetypeChunk> chunks,
            NativeArray <EntityRemapUtility.EntityRemapInfo> entityRemapping,
            EntityComponentStore *srcEntityComponentStore,
            ManagedComponentStore srcManagedComponentStore)
        {
            new MoveChunksJob
            {
                srcEntityComponentStore = srcEntityComponentStore,
                dstEntityComponentStore = EntityComponentStore,
                entityRemapping         = entityRemapping,
                chunks = chunks
            }.Run();

            var managedArrayChunks = new NativeList <IntPtr>(Allocator.Temp);

            int chunkCount  = chunks.Length;
            var remapChunks = new NativeArray <RemapChunk>(chunkCount, Allocator.TempJob);

            for (int i = 0; i < chunkCount; ++i)
            {
                var chunk     = chunks[i].m_Chunk;
                var archetype = chunk->Archetype;

                //TODO: this should not be done more than once for each archetype
                var dstArchetype = EntityComponentStore->GetOrCreateArchetype(archetype->Types, archetype->TypesCount);

                remapChunks[i] = new RemapChunk {
                    chunk = chunk, dstArchetype = dstArchetype
                };

                if (archetype->NumManagedArrays > 0)
                {
                    managedArrayChunks.Add((IntPtr)chunk);
                }

                if (archetype->MetaChunkArchetype != null)
                {
                    Entity srcEntity = chunk->metaChunkEntity;
                    Entity dstEntity;

                    EntityComponentStore->CreateEntities(dstArchetype->MetaChunkArchetype, &dstEntity, 1);

                    var srcEntityInChunk = srcEntityComponentStore->GetEntityInChunk(srcEntity);
                    var dstEntityInChunk = EntityComponentStore->GetEntityInChunk(dstEntity);

                    ChunkDataUtility.SwapComponents(srcEntityInChunk.Chunk, srcEntityInChunk.IndexInChunk, dstEntityInChunk.Chunk, dstEntityInChunk.IndexInChunk, 1,
                                                    srcEntityComponentStore->GlobalSystemVersion, EntityComponentStore->GlobalSystemVersion);
                    EntityRemapUtility.AddEntityRemapping(ref entityRemapping, srcEntity, dstEntity);

                    srcEntityComponentStore->DestroyEntities(&srcEntity, 1);
                }
            }

            var managedArrayDstIndices = new NativeArray <int>(managedArrayChunks.Length, Allocator.TempJob);
            var managedArraySrcIndices = new NativeArray <int>(managedArrayChunks.Length, Allocator.TempJob);

            EntityComponentStore->ReserveManagedObjectArrays(managedArrayDstIndices);

            var remapManaged = new RemapManagedArraysJob
            {
                chunks     = managedArrayChunks,
                dstIndices = managedArrayDstIndices,
                srcIndices = managedArraySrcIndices,
            }.Schedule(managedArrayChunks.Length, 64);

            ManagedComponentStore.Playback(ref EntityComponentStore->ManagedChangesTracker);
            srcManagedComponentStore.Playback(ref srcEntityComponentStore->ManagedChangesTracker);

            k_ProfileMoveObjectComponents.Begin();
            remapManaged.Complete();
            m_ManagedComponentStore.MoveManagedObjectArrays(managedArraySrcIndices, managedArrayDstIndices, srcManagedComponentStore);
            k_ProfileMoveObjectComponents.End();

            managedArrayDstIndices.Dispose();
            managedArraySrcIndices.Dispose();
            managedArrayChunks.Dispose();

            k_ProfileMoveSharedComponents.Begin();
            var remapShared =
                ManagedComponentStore.MoveSharedComponents(srcManagedComponentStore, chunks, Allocator.TempJob);

            k_ProfileMoveSharedComponents.End();

            new ChunkPatchEntities
            {
                RemapChunks          = remapChunks,
                EntityRemapping      = entityRemapping,
                EntityComponentStore = EntityComponentStore
            }.Run();

            var remapChunksJob = new RemapChunksJob
            {
                dstEntityComponentStore = EntityComponentStore,
                remapChunks             = remapChunks,
                entityRemapping         = entityRemapping
            }.Schedule(remapChunks.Length, 1);

            var moveChunksBetweenArchetypeJob = new MoveChunksBetweenArchetypeJob
            {
                remapChunks         = remapChunks,
                remapShared         = remapShared,
                globalSystemVersion = EntityComponentStore->GlobalSystemVersion
            }.Schedule(remapChunksJob);

            moveChunksBetweenArchetypeJob.Complete();

            ManagedComponentStore.Playback(ref EntityComponentStore->ManagedChangesTracker);

            remapShared.Dispose();
            remapChunks.Dispose();
        }
        public unsafe void Execute(ArchetypeChunk chunk, int chunkIndex, int firstEntityIndex)
        {
            float3 up = math.up();

            var chunkCCData              = chunk.GetNativeArray(CharacterControllerComponentType);
            var chunkCCInternalData      = chunk.GetNativeArray(CharacterControllerInternalType);
            var chunkPhysicsColliderData = chunk.GetNativeArray(PhysicsColliderType);
            var chunkTranslationData     = chunk.GetNativeArray(TranslationType);
            var chunkRotationData        = chunk.GetNativeArray(RotationType);

            var hasChunkCollisionEventBufferType = chunk.Has(CollisionEventBufferType);
            var hasChunkTriggerEventBufferType   = chunk.Has(TriggerEventBufferType);

            BufferAccessor <StatefulCollisionEvent> collisionEventBuffers = default;
            BufferAccessor <StatefulTriggerEvent>   triggerEventBuffers   = default;

            if (hasChunkCollisionEventBufferType)
            {
                collisionEventBuffers = chunk.GetBufferAccessor(CollisionEventBufferType);
            }
            if (hasChunkTriggerEventBufferType)
            {
                triggerEventBuffers = chunk.GetBufferAccessor(TriggerEventBufferType);
            }

            DeferredImpulseWriter.BeginForEachIndex(chunkIndex);

            for (int i = 0; i < chunk.Count; i++)
            {
                var ccComponentData = chunkCCData[i];
                var ccInternalData  = chunkCCInternalData[i];
                var collider        = chunkPhysicsColliderData[i];
                var position        = chunkTranslationData[i];
                var rotation        = chunkRotationData[i];
                DynamicBuffer <StatefulCollisionEvent> collisionEventBuffer = default;
                DynamicBuffer <StatefulTriggerEvent>   triggerEventBuffer   = default;

                if (hasChunkCollisionEventBufferType)
                {
                    collisionEventBuffer = collisionEventBuffers[i];
                }

                if (hasChunkTriggerEventBufferType)
                {
                    triggerEventBuffer = triggerEventBuffers[i];
                }

                // Collision filter must be valid
                if (!collider.IsValid || collider.Value.Value.Filter.IsEmpty)
                {
                    continue;
                }

                // Character step input
                CharacterControllerStepInput stepInput = new CharacterControllerStepInput
                {
                    World            = PhysicsWorld,
                    DeltaTime        = DeltaTime,
                    Up               = math.up(),
                    Gravity          = ccComponentData.Gravity,
                    MaxIterations    = ccComponentData.MaxIterations,
                    Tau              = k_DefaultTau,
                    Damping          = k_DefaultDamping,
                    SkinWidth        = ccComponentData.SkinWidth,
                    ContactTolerance = ccComponentData.ContactTolerance,
                    MaxSlope         = ccComponentData.MaxSlope,
                    RigidBodyIndex   = PhysicsWorld.GetRigidBodyIndex(ccInternalData.Entity),
                    CurrentVelocity  = ccInternalData.LinearVelocity,
                    MaxMovementSpeed = ccComponentData.MaxMovementSpeed
                };

                // Character transform
                RigidTransform transform = new RigidTransform
                {
                    pos = position.Value,
                    rot = rotation.Value
                };

                NativeList <StatefulCollisionEvent> currentFrameCollisionEvents = default;
                NativeList <StatefulTriggerEvent>   currentFrameTriggerEvents   = default;

                if (ccComponentData.RaiseCollisionEvents != 0)
                {
                    currentFrameCollisionEvents = new NativeList <StatefulCollisionEvent>(Allocator.Temp);
                }

                if (ccComponentData.RaiseTriggerEvents != 0)
                {
                    currentFrameTriggerEvents = new NativeList <StatefulTriggerEvent>(Allocator.Temp);
                }


                // Check support
                CheckSupport(ref PhysicsWorld, ref collider, stepInput, transform,
                             out ccInternalData.SupportedState, out float3 surfaceNormal, out float3 surfaceVelocity,
                             currentFrameCollisionEvents);

                // User input
                float3 desiredVelocity = ccInternalData.LinearVelocity;
                HandleUserInput(ccComponentData, stepInput.Up, surfaceVelocity, ref ccInternalData, ref desiredVelocity);

                // Calculate actual velocity with respect to surface
                if (ccInternalData.SupportedState == CharacterSupportState.Supported)
                {
                    CalculateMovement(ccInternalData.CurrentRotationAngle, stepInput.Up, ccInternalData.IsJumping,
                                      ccInternalData.LinearVelocity, desiredVelocity, surfaceNormal, surfaceVelocity, out ccInternalData.LinearVelocity);
                }
                else
                {
                    ccInternalData.LinearVelocity = desiredVelocity;
                }

                // World collision + integrate
                CollideAndIntegrate(stepInput, ccComponentData.CharacterMass, ccComponentData.AffectsPhysicsBodies != 0,
                                    collider.ColliderPtr, ref transform, ref ccInternalData.LinearVelocity, ref DeferredImpulseWriter,
                                    currentFrameCollisionEvents, currentFrameTriggerEvents);

                // Update collision event status
                if (currentFrameCollisionEvents.IsCreated)
                {
                    UpdateCollisionEvents(currentFrameCollisionEvents, collisionEventBuffer);
                }

                if (currentFrameTriggerEvents.IsCreated)
                {
                    UpdateTriggerEvents(currentFrameTriggerEvents, triggerEventBuffer);
                }

                // Write back and orientation integration
                position.Value = transform.pos;
                rotation.Value = quaternion.AxisAngle(up, ccInternalData.CurrentRotationAngle);

                // Write back to chunk data
                {
                    chunkCCInternalData[i]  = ccInternalData;
                    chunkTranslationData[i] = position;
                    chunkRotationData[i]    = rotation;
                }
            }

            DeferredImpulseWriter.EndForEachIndex();
        }
Beispiel #17
0
        internal void MoveChunksFrom(
            NativeArray <EntityRemapUtility.EntityRemapInfo> entityRemapping,
            EntityComponentStore *srcEntityComponentStore,
            ManagedComponentStore srcManagedComponentStore)
        {
            var moveChunksJob = new MoveAllChunksJob
            {
                srcEntityComponentStore = srcEntityComponentStore,
                dstEntityComponentStore = EntityComponentStore,
                entityRemapping         = entityRemapping
            }.Schedule();

            JobHandle.ScheduleBatchedJobs();

            int chunkCount = 0;

            for (var i = 0; i < srcEntityComponentStore->m_Archetypes.Length; ++i)
            {
                var srcArchetype = srcEntityComponentStore->m_Archetypes.Ptr[i];
                chunkCount += srcArchetype->Chunks.Count;
            }

            var remapChunks        = new NativeArray <RemapChunk>(chunkCount, Allocator.TempJob);
            var remapArchetypes    = new NativeArray <RemapArchetype>(srcEntityComponentStore->m_Archetypes.Length, Allocator.TempJob);
            var managedArrayChunks = new NativeList <IntPtr>(Allocator.Temp);

            int chunkIndex     = 0;
            int archetypeIndex = 0;

            for (var i = 0; i < srcEntityComponentStore->m_Archetypes.Length; ++i)
            {
                var srcArchetype = srcEntityComponentStore->m_Archetypes.Ptr[i];
                if (srcArchetype->Chunks.Count != 0)
                {
                    var dstArchetype = EntityComponentStore->GetOrCreateArchetype(srcArchetype->Types,
                                                                                  srcArchetype->TypesCount);

                    remapArchetypes[archetypeIndex] = new RemapArchetype
                    {
                        srcArchetype = srcArchetype, dstArchetype = dstArchetype
                    };

                    for (var j = 0; j < srcArchetype->Chunks.Count; ++j)
                    {
                        var srcChunk = srcArchetype->Chunks.p[j];
                        remapChunks[chunkIndex] = new RemapChunk {
                            chunk = srcChunk, dstArchetype = dstArchetype
                        };
                        chunkIndex++;
                    }

                    if (srcArchetype->NumManagedArrays > 0)
                    {
                        for (var j = 0; j < srcArchetype->Chunks.Count; ++j)
                        {
                            var chunk = srcArchetype->Chunks.p[j];
                            managedArrayChunks.Add((IntPtr)chunk);
                        }
                    }

                    archetypeIndex++;

                    EntityComponentStore->IncrementComponentTypeOrderVersion(dstArchetype);
                }
            }

            moveChunksJob.Complete();

            var managedArrayDstIndices = new NativeArray <int>(managedArrayChunks.Length, Allocator.TempJob);
            var managedArraySrcIndices = new NativeArray <int>(managedArrayChunks.Length, Allocator.TempJob);

            EntityComponentStore->ReserveManagedObjectArrays(managedArrayDstIndices);

            var remapManaged = new RemapManagedArraysJob
            {
                chunks     = managedArrayChunks,
                dstIndices = managedArrayDstIndices,
                srcIndices = managedArraySrcIndices,
            }.Schedule(managedArrayChunks.Length, 64);

            ManagedComponentStore.Playback(ref EntityComponentStore->ManagedChangesTracker);
            srcManagedComponentStore.Playback(ref srcEntityComponentStore->ManagedChangesTracker);

            k_ProfileMoveObjectComponents.Begin();
            remapManaged.Complete();
            m_ManagedComponentStore.MoveManagedObjectArrays(managedArraySrcIndices, managedArrayDstIndices, srcManagedComponentStore);
            k_ProfileMoveObjectComponents.End();

            managedArrayDstIndices.Dispose();
            managedArraySrcIndices.Dispose();
            managedArrayChunks.Dispose();

            k_ProfileMoveSharedComponents.Begin();
            var remapShared =
                ManagedComponentStore.MoveAllSharedComponents(srcManagedComponentStore, Allocator.TempJob);

            k_ProfileMoveSharedComponents.End();

            new ChunkPatchEntities
            {
                RemapChunks          = remapChunks,
                EntityRemapping      = entityRemapping,
                EntityComponentStore = EntityComponentStore
            }.Run();

            var remapAllChunksJob = new RemapAllChunksJob
            {
                dstEntityComponentStore = EntityComponentStore,
                remapChunks             = remapChunks,
                entityRemapping         = entityRemapping
            }.Schedule(remapChunks.Length, 1);

            var remapArchetypesJob = new RemapArchetypesJob
            {
                remapArchetypes         = remapArchetypes,
                remapShared             = remapShared,
                dstEntityComponentStore = EntityComponentStore,
                chunkHeaderType         = TypeManager.GetTypeIndex <ChunkHeader>()
            }.Schedule(archetypeIndex, 1, remapAllChunksJob);

            ManagedComponentStore.Playback(ref EntityComponentStore->ManagedChangesTracker);

            remapArchetypesJob.Complete();
            remapShared.Dispose();
            remapChunks.Dispose();
        }
Beispiel #18
0
 public bool CastRay(RaycastInput input, ref NativeList <RaycastHit> allHits) => QueryWrappers.RayCast(ref this, input, ref allHits);
 public TestBinaryReader(TestBinaryWriter writer)
 {
     content        = writer.content;
     writer.content = new NativeList <byte>();
 }
Beispiel #20
0
 public bool CastCollider(ColliderCastInput input, ref NativeList <ColliderCastHit> allHits) => QueryWrappers.ColliderCast(ref this, input, ref allHits);
        void GenerateArgumentPermutations(StateData stateData, NativeList <ActionKey> argumentPermutations)
        {
            var agentObjects = new NativeList <int>(4, Allocator.Temp);

            stateData.GetTraitBasedObjectIndices(agentObjects, s_AgentFilter);
            var keyObjects = new NativeList <int>(4, Allocator.Temp);

            stateData.GetTraitBasedObjectIndices(keyObjects, s_KeyFilter);
            var roomObjects = new NativeList <int>(4, Allocator.Temp);

            stateData.GetTraitBasedObjectIndices(roomObjects, s_RoomFilter);

            if (roomObjects.Length <= 0)
            {
                return;
            }

            var traitBasedObjectIds = stateData.TraitBasedObjectIds;
            var carriableBuffer     = stateData.CarriableBuffer;
            var carrierBuffer       = stateData.CarrierBuffer;
            var localizedBuffer     = stateData.LocalizedBuffer;

            var firstRoom     = traitBasedObjectIds[roomObjects[0]].Id;
            var agentKeyIndex = -1;

            for (var i = 0; i < keyObjects.Length; i++)
            {
                var keyIndex  = keyObjects[i];
                var keyObject = stateData.TraitBasedObjects[keyIndex];

                if (carriableBuffer[keyObject.CarriableIndex].Carrier != ObjectId.None)
                {
                    continue;
                }

                for (var j = 0; j < agentObjects.Length; j++)
                {
                    var agentIndex  = agentObjects[j];
                    var agentObject = stateData.TraitBasedObjects[agentIndex];

                    if (carrierBuffer[agentObject.CarrierIndex].CarriedObject == traitBasedObjectIds[keyIndex].Id)
                    {
                        agentKeyIndex = keyIndex;
                        break;
                    }
                }

                if (keyIndex >= 0)
                {
                    break;
                }
            }

            // Get argument permutation and check preconditions
            for (var i = 0; i < keyObjects.Length; i++)
            {
                var keyIndex  = keyObjects[i];
                var keyObject = stateData.TraitBasedObjects[keyIndex];

                if (carriableBuffer[keyObject.CarriableIndex].Carrier != ObjectId.None)
                {
                    continue;
                }

                for (var j = 0; j < agentObjects.Length; j++)
                {
                    var agentIndex  = agentObjects[j];
                    var agentObject = stateData.TraitBasedObjects[agentIndex];

                    if (carrierBuffer[agentObject.CarrierIndex].CarriedObject == traitBasedObjectIds[keyIndex].Id)
                    {
                        continue;
                    }

                    if (localizedBuffer[agentObject.LocalizedIndex].Location != firstRoom)
                    {
                        continue;
                    }

                    argumentPermutations.Add(new ActionKey(k_MaxArguments)
                    {
                        ActionGuid        = ActionGuid,
                        [k_KeyIndex]      = keyIndex,
                        [k_AgentIndex]    = agentIndex,
                        [k_AgentKeyIndex] = agentKeyIndex
                    });
                }
            }

            agentObjects.Dispose();
            keyObjects.Dispose();
            roomObjects.Dispose();
        }
Beispiel #22
0
 public bool CalculateDistance(ColliderDistanceInput input, ref NativeList <DistanceHit> allHits) => QueryWrappers.CalculateDistance(ref this, input, ref allHits);
Beispiel #23
0
    public void BuildMesh(int2 dir)
    {
        Mesh mesh = new Mesh();
        NativeList <Vector3> verts = new NativeList <Vector3>(Allocator.Temp);
        NativeList <int>     tris  = new NativeList <int>(Allocator.Temp);
        List <Vector2>       uvs   = new List <Vector2>();

        float3 blockPos = new float3(0, 0, 0);

        int numFaces = 0;

        //front
        if (dir.y < 0)
        {
            verts.Add(blockPos + new float3(0, 0, 0));
            verts.Add(blockPos + new float3(0, 1, 0));
            verts.Add(blockPos + new float3(1, 1, 0));
            verts.Add(blockPos + new float3(1, 0, 0));
            numFaces++;

            uvs.AddRange(BlockTexture.Get(BlockType.BedRock, 0).sidePos.GetUVs());
        }

        //right
        if (dir.x > 0)
        {
            verts.Add(blockPos + new float3(1, 0, 0));
            verts.Add(blockPos + new float3(1, 1, 0));
            verts.Add(blockPos + new float3(1, 1, 1));
            verts.Add(blockPos + new float3(1, 0, 1));
            numFaces++;

            uvs.AddRange(BlockTexture.Get(BlockType.BedRock, 0).sidePos.GetUVs());
        }

        //back
        if (dir.y > 0)
        {
            verts.Add(blockPos + new float3(1, 0, 1));
            verts.Add(blockPos + new float3(1, 1, 1));
            verts.Add(blockPos + new float3(0, 1, 1));
            verts.Add(blockPos + new float3(0, 0, 1));
            numFaces++;

            uvs.AddRange(BlockTexture.Get(BlockType.BedRock, 0).sidePos.GetUVs());
        }

        //left
        if (dir.x < 0)
        {
            verts.Add(blockPos + new float3(0, 0, 1));
            verts.Add(blockPos + new float3(0, 1, 1));
            verts.Add(blockPos + new float3(0, 1, 0));
            verts.Add(blockPos + new float3(0, 0, 0));
            numFaces++;

            uvs.AddRange(BlockTexture.Get(BlockType.BedRock, 0).sidePos.GetUVs());
        }

        int tl = verts.Length - 4 * numFaces;

        for (int idx = 0; idx < numFaces; idx++)
        {
            NativeArray <int> range = new NativeArray <int>(6, Allocator.Temp);
            range[0] = tl + idx * 4;
            range[1] = tl + idx * 4 + 1;
            range[2] = tl + idx * 4 + 2;
            range[3] = tl + idx * 4;
            range[4] = tl + idx * 4 + 2;
            range[5] = tl + idx * 4 + 3;
            tris.AddRange(range);
            range.Dispose();
        }

        mesh.vertices  = verts.ToArray();
        mesh.triangles = tris.ToArray();
        mesh.uv        = uvs.ToArray();

        mesh.RecalculateNormals();

        GetComponent <MeshFilter>().mesh         = mesh;
        GetComponent <MeshCollider>().sharedMesh = mesh;
        verts.Dispose();
        tris.Dispose();
    }
Beispiel #24
0
        public void Update(ref EntityArray array)
        {
            m_Entities.Clear();
            EntitySpawnCount   = 0;
            EntityReplaceCount = 0;
            EntityRemovalCount = 0;

            var defaultEntity = new Entity();
            var length        = array.Length;

            if (NeedEntitiesList)
            {
                UnityEngine.Profiling.Profiler.BeginSample("ForLoop #1 - With entities");
                for (int i = 0; i != length; i++)
                {
                    Entity entity;
                    UnityEngine.Profiling.Profiler.BeginSample("Get entities and init var");
                    var checkedEntity = array[i];
                    UnityEngine.Profiling.Profiler.EndSample();
                    UnityEngine.Profiling.Profiler.BeginSample("TryGet()");
                    if (!m_CurrentEntities.FastTryGet(checkedEntity.Index, out entity))
                    {
                        if (NeedEntitiesList)
                        {
                            m_Entities.Add(new EntityChangeItem()
                            {
                                entity     = checkedEntity,
                                wasCreated = true
                            });
                        }
                        m_CurrentEntities[checkedEntity.Index] = checkedEntity;
                        EntitySpawnCount++;
                    }
                    else if (NeedToCheckReplacement)
                    {
                        UnityEngine.Profiling.Profiler.BeginSample("Check Version");
                        // The entity was replaced
                        if (entity.Version != checkedEntity.Version)
                        {
                            EntityReplaceCount++;
                            m_CurrentEntities[checkedEntity.Index] = checkedEntity;
                        }
                        UnityEngine.Profiling.Profiler.EndSample();
                    }
                    UnityEngine.Profiling.Profiler.EndSample();
                }
                UnityEngine.Profiling.Profiler.EndSample();
            }
            else
            {
                UnityEngine.Profiling.Profiler.BeginSample("ForLoop #1 - Without entities");
                EntitySpawnCount = length - m_LastLength;
                m_LastLength     = length;
                UnityEngine.Profiling.Profiler.EndSample();
            }

            UnityEngine.Profiling.Profiler.BeginSample("Check for removal");
            if (NeedToCheckRemoval && array.Length != m_CurrentEntities.Count)
            {
                var toRemove = new NativeList <int>(Allocator.Temp);
                foreach (var entity in m_CurrentEntities.Values)
                {
                    var exist = false;
                    for (int i = 0; i != array.Length; i++)
                    {
                        if (array[i].Index == entity.Index)
                        {
                            exist = true;
                            break;
                        }
                    }
                    if (exist)
                    {
                        continue;
                    }
                    EntityRemovalCount++;
                    m_Entities.Add(new EntityChangeItem()
                    {
                        entity     = entity,
                        wasCreated = false
                    });

                    toRemove.Add(entity.Index);
                }
                for (int i = 0; i != toRemove.Length; i++)
                {
                    m_CurrentEntities.Remove(toRemove[i]);
                }

                toRemove.Dispose();
            }
            UnityEngine.Profiling.Profiler.EndSample();
        }
Beispiel #25
0
    public static unsafe void CheckSupport(
        ref PhysicsWorld world, ref PhysicsCollider collider, CharacterControllerStepInput stepInput, RigidTransform transform,
        out CharacterSupportState characterState, out float3 surfaceNormal, out float3 surfaceVelocity,
        NativeList <StatefulCollisionEvent> collisionEvents = default)
    {
        surfaceNormal   = float3.zero;
        surfaceVelocity = float3.zero;

        // Up direction must be normalized
        Assert.IsTrue(Unity.Physics.Math.IsNormalized(stepInput.Up));

        // Query the world
        NativeList <ColliderCastHit> castHits = new NativeList <ColliderCastHit>(k_DefaultQueryHitsCapacity, Allocator.Temp);
        CharacterControllerAllHitsCollector <ColliderCastHit> castHitsCollector = new CharacterControllerAllHitsCollector <ColliderCastHit>(
            stepInput.RigidBodyIndex, 1.0f, ref castHits, world);
        var maxDisplacement = -stepInput.ContactTolerance * stepInput.Up;

        {
            ColliderCastInput input = new ColliderCastInput()
            {
                Collider    = collider.ColliderPtr,
                Orientation = transform.rot,
                Start       = transform.pos,
                End         = transform.pos + maxDisplacement
            };

            world.CastCollider(input, ref castHitsCollector);
        }

        // If no hits, proclaim unsupported state
        if (castHitsCollector.NumHits == 0)
        {
            characterState = CharacterSupportState.Unsupported;
            return;
        }

        float maxSlopeCos = math.cos(stepInput.MaxSlope);

        // Iterate over distance hits and create constraints from them
        NativeList <SurfaceConstraintInfo> constraints = new NativeList <SurfaceConstraintInfo>(k_DefaultConstraintsCapacity, Allocator.Temp);
        float maxDisplacementLength = math.length(maxDisplacement);

        for (int i = 0; i < castHitsCollector.NumHits; i++)
        {
            ColliderCastHit hit = castHitsCollector.AllHits[i];
            CreateConstraint(stepInput.World, stepInput.Up,
                             hit.RigidBodyIndex, hit.ColliderKey, hit.Position, hit.SurfaceNormal, hit.Fraction * maxDisplacementLength,
                             stepInput.SkinWidth, maxSlopeCos, ref constraints);
        }

        // Velocity for support checking
        float3 initialVelocity = maxDisplacement / stepInput.DeltaTime;

        // Solve downwards (don't use min delta time, try to solve full step)
        float3 outVelocity = initialVelocity;
        float3 outPosition = transform.pos;

        SimplexSolver.Solve(stepInput.DeltaTime, stepInput.DeltaTime, stepInput.Up, stepInput.MaxMovementSpeed,
                            constraints, ref outPosition, ref outVelocity, out float integratedTime, false);

        // Get info on surface
        int numSupportingPlanes = 0;
        {
            for (int j = 0; j < constraints.Length; j++)
            {
                var constraint = constraints[j];
                if (constraint.Touched && !constraint.IsTooSteep && !constraint.IsMaxSlope)
                {
                    numSupportingPlanes++;
                    surfaceNormal   += constraint.Plane.Normal;
                    surfaceVelocity += constraint.Velocity;

                    // Add supporting planes to collision events
                    if (collisionEvents.IsCreated)
                    {
                        var collisionEvent = new StatefulCollisionEvent(stepInput.World.Bodies[stepInput.RigidBodyIndex].Entity,
                                                                        stepInput.World.Bodies[constraint.RigidBodyIndex].Entity, stepInput.RigidBodyIndex, constraint.RigidBodyIndex,
                                                                        ColliderKey.Empty, constraint.ColliderKey, constraint.Plane.Normal);
                        collisionEvent.CollisionDetails = new StatefulCollisionEvent.Details(1, 0, constraint.HitPosition);
                        collisionEvents.Add(collisionEvent);
                    }
                }
            }

            if (numSupportingPlanes > 0)
            {
                float invNumSupportingPlanes = 1.0f / numSupportingPlanes;
                surfaceNormal   *= invNumSupportingPlanes;
                surfaceVelocity *= invNumSupportingPlanes;

                surfaceNormal = math.normalize(surfaceNormal);
            }
        }

        // Check support state
        {
            if (math.lengthsq(initialVelocity - outVelocity) < k_SimplexSolverEpsilonSq)
            {
                // If velocity hasn't changed significantly, declare unsupported state
                characterState = CharacterSupportState.Unsupported;
            }
            else if (math.lengthsq(outVelocity) < k_SimplexSolverEpsilonSq && numSupportingPlanes > 0)
            {
                // If velocity is very small, declare supported state
                characterState = CharacterSupportState.Supported;
            }
            else
            {
                // Check if sliding
                outVelocity = math.normalize(outVelocity);
                float slopeAngleSin   = math.max(0.0f, math.dot(outVelocity, -stepInput.Up));
                float slopeAngleCosSq = 1 - slopeAngleSin * slopeAngleSin;
                if (slopeAngleCosSq <= maxSlopeCos * maxSlopeCos)
                {
                    characterState = CharacterSupportState.Sliding;
                }
                else if (numSupportingPlanes > 0)
                {
                    characterState = CharacterSupportState.Supported;
                }
                else
                {
                    // If numSupportingPlanes is 0, surface normal is invalid, so state is unsupported
                    characterState = CharacterSupportState.Unsupported;
                }
            }
        }
    }
    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);
            }
        }
    }
Beispiel #27
0
    private static unsafe void CalculateAndStoreDeferredImpulsesAndCollisionEvents(
        CharacterControllerStepInput stepInput, bool affectBodies, float characterMass,
        float3 linearVelocity, NativeList <SurfaceConstraintInfo> constraints, ref NativeStream.Writer deferredImpulseWriter,
        NativeList <StatefulCollisionEvent> collisionEvents)
    {
        PhysicsWorld world = stepInput.World;

        for (int i = 0; i < constraints.Length; i++)
        {
            SurfaceConstraintInfo constraint = constraints[i];
            int rigidBodyIndex = constraint.RigidBodyIndex;

            float3 impulse = float3.zero;

            if (rigidBodyIndex < 0)
            {
                continue;
            }

            // Skip static bodies if needed to calculate impulse
            if (affectBodies && (rigidBodyIndex < world.NumDynamicBodies))
            {
                RigidBody body = world.Bodies[rigidBodyIndex];

                float3 pointRelVel = world.GetLinearVelocity(rigidBodyIndex, constraint.HitPosition);
                pointRelVel -= linearVelocity;

                float projectedVelocity = math.dot(pointRelVel, constraint.Plane.Normal);

                // Required velocity change
                float deltaVelocity = -projectedVelocity * stepInput.Damping;

                float distance = constraint.Plane.Distance;
                if (distance < 0.0f)
                {
                    deltaVelocity += (distance / stepInput.DeltaTime) * stepInput.Tau;
                }

                // Calculate impulse
                MotionVelocity mv = world.MotionVelocities[rigidBodyIndex];
                if (deltaVelocity < 0.0f)
                {
                    // Impulse magnitude
                    float impulseMagnitude = 0.0f;
                    {
                        float objectMassInv = GetInvMassAtPoint(constraint.HitPosition, constraint.Plane.Normal, body, mv);
                        impulseMagnitude = deltaVelocity / objectMassInv;
                    }

                    impulse = impulseMagnitude * constraint.Plane.Normal;
                }

                // Add gravity
                {
                    // Effect of gravity on character velocity in the normal direction
                    float3 charVelDown = stepInput.Gravity * stepInput.DeltaTime;
                    float  relVelN     = math.dot(charVelDown, constraint.Plane.Normal);

                    // Subtract separation velocity if separating contact
                    {
                        bool  isSeparatingContact = projectedVelocity < 0.0f;
                        float newRelVelN          = relVelN - projectedVelocity;
                        relVelN = math.select(relVelN, newRelVelN, isSeparatingContact);
                    }

                    // If resulting velocity is negative, an impulse is applied to stop the character
                    // from falling into the body
                    {
                        float3 newImpulse = impulse;
                        newImpulse += relVelN * characterMass * constraint.Plane.Normal;
                        impulse     = math.select(impulse, newImpulse, relVelN < 0.0f);
                    }
                }

                // Store impulse
                deferredImpulseWriter.Write(
                    new DeferredCharacterControllerImpulse()
                {
                    Entity  = body.Entity,
                    Impulse = impulse,
                    Point   = constraint.HitPosition
                });
            }

            if (collisionEvents.IsCreated && constraint.Touched && !constraint.IsMaxSlope)
            {
                var collisionEvent = new StatefulCollisionEvent(world.Bodies[stepInput.RigidBodyIndex].Entity,
                                                                world.Bodies[rigidBodyIndex].Entity, stepInput.RigidBodyIndex, rigidBodyIndex, ColliderKey.Empty,
                                                                constraint.ColliderKey, constraint.Plane.Normal);
                collisionEvent.CollisionDetails = new StatefulCollisionEvent.Details(
                    1, math.dot(impulse, collisionEvent.Normal), constraint.HitPosition);

                // check if collision event exists for the same bodyID and colliderKey
                // although this is a nested for, number of solved constraints shouldn't be high
                // if the same constraint (same entities, rigidbody indices and collider keys)
                // is solved in multiple solver iterations, pick the one from latest iteration
                bool newEvent = true;
                for (int j = 0; j < collisionEvents.Length; j++)
                {
                    if (collisionEvents[j].CompareTo(collisionEvent) == 0)
                    {
                        collisionEvents[j] = collisionEvent;
                        newEvent           = false;
                        break;
                    }
                }
                if (newEvent)
                {
                    collisionEvents.Add(collisionEvent);
                }
            }
        }
    }
Beispiel #28
0
 private void InitBoidBehaviourJob()
 {
     seenBoids = new NativeList <Boid_Blittable>(JOB_MAX_SEEN_BOIDS_ARRAYS_LENGTH, Allocator.Persistent);
     resultDir = new NativeArray <float3>(1, Allocator.Persistent);
 }
Beispiel #29
0
        public static void ConvertRectTransformsRecursive(UnityEngine.RectTransform parent, Entity parentEntity,
                                                          RectTransformToEntity rectTransformToEntity, EntityManager commandBuffer,
                                                          ref DotsUIArchetypes archetypes, ref NativeList <LinkedEntityGroup> linkedGroup, bool isPrefab)
        {
            rectTransformToEntity.Add(parent, parentEntity);
            linkedGroup.Add(parentEntity);
#if UNITY_EDITOR
            commandBuffer.SetName(parentEntity, parent.name);
#endif
            m_PooledRectTransformList.Add(parent);
            int childCount = parent.childCount;
            for (int i = 0; i < childCount; i++)
            {
                if (parent.GetChild(i) is UnityEngine.RectTransform childTransform)
                {
                    //if(!childTransform.gameObject.activeInHierarchy)
                    //    continue;
                    Entity child = commandBuffer.CreateEntity(archetypes.GenericChildArchetype);
                    SetRectTransform(commandBuffer, childTransform, child);
                    commandBuffer.SetComponentData(child, new UIParent()
                    {
                        Value = parentEntity
                    });
                    if (isPrefab)
                    {
                        commandBuffer.AddComponent(child, typeof(Prefab));
                    }
                    ConvertRectTransformsRecursive(childTransform, child, rectTransformToEntity, commandBuffer,
                                                   ref archetypes, ref linkedGroup, isPrefab);
                }
            }
        }
Beispiel #30
0
 internal FindAmmo(Guid guid, NativeList <StateEntityKey> statesToExpand, StateDataContext stateDataContext)
 {
     ActionGuid         = guid;
     m_StatesToExpand   = statesToExpand.AsDeferredJobArray();
     m_StateDataContext = stateDataContext;
 }