public unsafe void Execute() { DistanceHit dh; hit = world.CalculateDistance(input, out dh); result = dh; }
public void Execute(Entity ent, int index, [ReadOnly] ref Translation translation, ref Enemy enemy) { enemy.timer -= deltaTime; var input = new PointDistanceInput() { MaxDistance = enemy.rangeDie, Filter = new CollisionFilter() { CategoryBits = mask, MaskBits = mask, GroupIndex = 0 }, Position = translation.Value }; DistanceHit hit; if (world.CalculateDistance(input, out hit)) { cmd.DestroyEntity(index, ent); cmd.DestroyEntity(index, world.Bodies[hit.RigidBodyIndex].Entity); var e = cmd.Instantiate(index, explosionPrefab); cmd.SetComponent(index, e, new Translation() { Value = hit.Position }); } else if (enemy.timer < 0) { input.MaxDistance = enemy.rangeShoot; if (world.CalculateDistance(input, out hit)) { var dir = hit.Position - translation.Value; dir *= enemy.rangeShoot / math.length(dir) * 0.5f; cmd.DestroyEntity(index, world.Bodies[hit.RigidBodyIndex].Entity); var e = cmd.Instantiate(index, lazerPrefab); cmd.SetComponent(index, e, new Translation() { Value = translation.Value + dir }); cmd.SetComponent(index, e, new Rotation() { Value = quaternion.RotateZ(math.atan2(dir.y, dir.x)) }); enemy.timer = enemy.cooldown; } } }
public unsafe static void ColliderRange(CollisionWorld world, float radius, Collider coll, RigidTransform trans, ref NativeList <DistanceHit> hits) { ColliderDistanceInput input = new ColliderDistanceInput() { MaxDistance = radius, Collider = &coll, Transform = trans }; world.CalculateDistance(input, ref hits); }
public unsafe static void PointRange(CollisionWorld world, float radius, uint mask, float3 pos, ref NativeList <DistanceHit> hits) { PointDistanceInput input = new PointDistanceInput() { MaxDistance = radius, Filter = new CollisionFilter() { CategoryBits = mask, MaskBits = mask, GroupIndex = 0 }, Position = pos }; world.CalculateDistance(input, ref hits); }
public unsafe void Execute(int index) { DistanceHit hit; if (!world.CalculateDistance(inputs[index], out hit)) { hit = new DistanceHit() { RigidBodyIndex = -1 } } ; results[index] = hit; } }
/// <summary> /// Returns a list of all colliders within the specified distance of the provided collider, as a list of <see cref="DistanceHit"/>.<para/> /// /// Can be used in conjunction with <see cref="ColliderCastAll"/> to get the penetration depths of any colliders (using the distance of collisions).<para/> /// /// The caller must dispose of the returned list. /// </summary> /// <param name="collider"></param> /// <param name="maxDistance"></param> /// <param name="transform"></param> /// <param name="collisionWorld"></param> /// <returns></returns> public unsafe static NativeList <DistanceHit> ColliderDistanceAll(PhysicsCollider collider, float maxDistance, RigidTransform transform, ref CollisionWorld collisionWorld, Entity ignore, Allocator allocator = Allocator.TempJob) { ColliderDistanceInput input = new ColliderDistanceInput() { Collider = collider.ColliderPtr, MaxDistance = maxDistance, Transform = transform }; NativeList <DistanceHit> allDistances = new NativeList <DistanceHit>(allocator); if (collisionWorld.CalculateDistance(input, ref allDistances)) { TrimByEntity(ref allDistances, ignore); } return(allDistances); }
protected override unsafe void OnUpdate() { CollisionWorld collisionWorld = buildPhysicsWorld.PhysicsWorld.CollisionWorld; CollisionFilter collisionFilter = new CollisionFilter() { BelongsTo = 1u << 0, CollidesWith = 0u | (1u << 0) | (1u << 1), GroupIndex = 0 }; Dependency = Entities.WithAll <AnimalTag>().ForEach((ref Translation translation, ref AnimalMovementData mvmtData, in PhysicsCollider collider, in Rotation rotation) => { Unity.Collections.NativeList <DistanceHit> hits = new Unity.Collections.NativeList <DistanceHit>(Unity.Collections.Allocator.Temp); float maxDist = 1f; float3 fwd = translation.Value + (mvmtData.targetDirection * 0.25f); // Tested in Unity 2020.1.0b10 //ColliderDistanceInput cdi = new ColliderDistanceInput() //{ // Collider = collider.ColliderPtr, // MaxDistance = maxDist, // Transform = new RigidTransform(rotation.Value, translation.Value) //}; PointDistanceInput pdi = new PointDistanceInput() { Filter = collisionFilter, MaxDistance = maxDist, Position = fwd }; if (collisionWorld.CalculateDistance(pdi, ref hits)) { DistanceHit closest = GetClosestHit(hits, maxDist); if (closest.Distance > 0.00001) { float distance = closest.Distance; float distanceFrac = 1 - (distance / maxDist); distanceFrac = math.clamp(distanceFrac, 0.25f, 1f); byte colliderTags = collisionWorld.Bodies[closest.RigidBodyIndex].CustomTags; float dotProduct = 0f; float angle = 0f; bool avoid = false; if (colliderTags == 1) // Collision with another animal { quaternion r = collisionWorld.Bodies[closest.RigidBodyIndex].WorldFromBody.rot; float3 othersFwd = math.rotate(r, new float3(0f, 0f, 1f)); dotProduct = (float)(math.dot(mvmtData.targetDirection, math.normalize(othersFwd))); if (dotProduct < -0.7f) { avoid = true; angle = 5.846853f * distanceFrac; //- 25f degrees } else if (dotProduct >= -0.001f && dotProduct < 0.975f) { avoid = true; angle = (0.436332f - math.acos(dotProduct)) * distanceFrac; // 25 degrees } } else if (colliderTags == 2) // Collision with terrain { dotProduct = math.dot(mvmtData.targetDirection, math.normalize(closest.SurfaceNormal)); if (dotProduct < -0.1f) { avoid = true; angle = -(1.570796f - math.acos(dotProduct)) * distanceFrac; //90 degrees -> parallel to surface normal } } if (avoid) { quaternion newRotation = quaternion.RotateY(angle); float3 newDirection = math.rotate(newRotation, mvmtData.direction); newDirection = math.normalizesafe(newDirection); mvmtData.targetDirection = newDirection; } } } hits.Dispose(); }).Schedule(Dependency);
public void Execute( Entity entity, int index, ref VelocityComponent velocityComponent, ref Translation translation ) { velocityComponent.timerCalcVelocity -= DeltaTime; if (velocityComponent.timerCalcVelocity > 0) { return; } velocityComponent.timerCalcVelocity = tick; var input = new PointDistanceInput { Position = translation.Value, MaxDistance = cohesionRadius, Filter = CollisionFilter }; var closestHits = new NativeList <DistanceHit>(Allocator.Temp); if (!CollisionWorld.CalculateDistance(input, ref closestHits)) { closestHits.Dispose(); return; } if (closestHits.Length < 2) { closestHits.Dispose(); return; } velocityComponent.cohesion = float3.zero; velocityComponent.separation = float3.zero; velocityComponent.separationCount = 0; velocityComponent.alignment = float3.zero; for (int i = 0; i < closestHits.Length && i < maxBoids; i++) { var entityHit = CollisionWorld.Bodies[closestHits[i].RigidBodyIndex].Entity; velocityComponent.vector = translation.Value - TranslationMapData[entityHit].Value; velocityComponent.sqrMagnitude = Vector3.SqrMagnitude(velocityComponent.vector); velocityComponent.cohesion += TranslationMapData[entityHit].Value; velocityComponent.alignment += VelocityMapData[entityHit].velocity; if (velocityComponent.sqrMagnitude > 0 && velocityComponent.sqrMagnitude < separationDistance2) { velocityComponent.separation += velocityComponent.vector / velocityComponent.sqrMagnitude; velocityComponent.separationCount++; } } velocityComponent.cohesion /= closestHits.Length > maxBoids ? maxBoids : closestHits.Length; velocityComponent.cohesion = Vector3.ClampMagnitude(velocityComponent.cohesion - translation.Value, maxSpeed); velocityComponent.cohesion *= cohesionCoefficient; if (velocityComponent.separationCount > 0) { velocityComponent.separation /= velocityComponent.separationCount; velocityComponent.separation = Vector3.ClampMagnitude(velocityComponent.separation, maxSpeed); velocityComponent.separation *= separationCoefficient; } velocityComponent.alignment /= closestHits.Length > maxBoids ? maxBoids : closestHits.Length; velocityComponent.alignment = Vector3.ClampMagnitude(velocityComponent.alignment, maxSpeed); velocityComponent.alignment *= alignmentCoefficient; velocityComponent.velocity = Vector3.ClampMagnitude(velocityComponent.cohesion + velocityComponent.separation + velocityComponent.alignment, maxSpeed); closestHits.Dispose(); }
public unsafe void Execute() { world.CalculateDistance(input, ref result); }