public void Move(ref PhysicsVelocity rb, ref PhysicsMass mass, ref InputStruct input, ref PhysicsControllerStruct playerData, ref LocalToWorld toWorld, ref Rotation rot, ref Translation trans) { float3 targetVelocity = new float3(); float speed = 9; float gravity = 4; //Set target to input velocity targetVelocity.x = input.move.x; targetVelocity.z = input.move.y; //Calculate how fast we should be moving targetVelocity = TransformDirection(toWorld.Value, targetVelocity); //Change from local space to world space targetVelocity *= speed * deltaTime * 100; //Apply a force that attempts to reach our target velocity float3 velocityChange = (targetVelocity - rb.Linear); velocityChange.y = -gravity * deltaTime * 10; //Apply gravity to the player //Mouse movement rb.Angular.y = -input.mouseX * 2; //* deltaTime; mass.InverseInertia[0] = 0; mass.InverseInertia[2] = 0; if (playerData.isGrounded && input.jump && playerData.timeSinceLastJump > .1f) { velocityChange.y = 10; playerData.timeSinceLastJump = 0; } playerData.timeSinceLastJump += deltaTime; rb.ApplyLinearImpulse(mass, velocityChange); }
protected override void OnUpdate() { Entities .WithStructuralChanges() .WithAll <BulletData>() .ForEach((Entity srcEntity, ref PhysicsMass ms, ref PhysicsGravityFactor gravityFactor, in TargetReachedData targetReachedData, in Move2TargetData targetData) => { var r = PhysicsMass.CreateDynamic(MassProperties.UnitSphere, 1); ms.Transform = r.Transform; ms.InverseInertia = r.InverseInertia; ms.InverseMass = r.InverseMass; ms.AngularExpansionFactor = r.AngularExpansionFactor; gravityFactor.Value = 1; //EntityManager.AddComponentData(srcEntity, new PhysicsVelocity()); //EntityManager.AddComponentData(targetData.entity, new DeadData()); //cb.DestroyEntity(entityInQueryIndex, srcEntity); //cb.AddComponent(entityInQueryIndex, targetData.entity, new DeadData()); //cb.AddComponent(targetData.entity, new SEtNa); }).Run();
private void OnEnable() { // some random initial position var position = UnityEngine.Random.insideUnitCircle * 80f; transform.position = new Vector3(position.x, 0, position.y); entityManager = World.DefaultGameObjectInjectionWorld.EntityManager; EntityArchetype archetype = entityManager.CreateArchetype( typeof(Translation), typeof(Rotation), typeof(LocalToWorld), typeof(CopyInitialTransformToLocalToWorldTagCmp), typeof(CopyTransformToGameObject), typeof(CopyTransformFromGameObject), typeof(EntitiesAroundCountCmp), typeof(PhysicsCollider), typeof(PhysicsMass) ); entity = entityManager.CreateEntity(archetype); entityManager.SetName(entity, name); entityManager.SetComponentData(entity, new PhysicsCollider() { Value = PhysicsBootstrap.colliderUnitSmall }); entityManager.SetComponentData(entity, new EntitiesAroundCountCmp() { range = 10f }); entityManager.SetComponentData(entity, PhysicsMass.CreateKinematic(MassProperties.UnitSphere)); entityManager.AddComponentObject(entity, transform); }
public unsafe void Execute <TCtx>(TCtx ctx, InputTriggerPort port) where TCtx : IGraphInstance { var entity = ctx.ReadEntity(Entity); if (entity == Unity.Entities.Entity.Null) { return; } if (!ctx.EntityManager.HasComponent <PhysicsMass>(entity) || !ctx.EntityManager.HasComponent <PhysicsVelocity>(entity)) { return; } PhysicsMass physicsMass = ctx.EntityManager.GetComponentData <PhysicsMass>(entity); PhysicsVelocity physicsVelocity = ctx.EntityManager.GetComponentData <PhysicsVelocity>(entity); if (LinearOnly) { physicsVelocity.ApplyLinearImpulse(physicsMass, ctx.ReadFloat3(Value)); } else { Translation t = ctx.EntityManager.GetComponentData <Translation>(entity); Rotation r = ctx.EntityManager.GetComponentData <Rotation>(entity); ComponentExtensions.ApplyImpulse(ref physicsVelocity, physicsMass, t, r, ctx.ReadFloat3(Value), ctx.ReadFloat3(Point)); } ctx.EntityManager.SetComponentData(entity, physicsVelocity); }
protected override void OnUpdate() { Entities.ForEach( (PhysicsBody body) => { if (!body.enabled) { return; } var entity = GetPrimaryEntity(body.gameObject); if (body.MotionType == BodyMotionType.Static) { return; } // Build mass component var massProperties = DstEntityManager.GetComponentData <PhysicsCollider>(entity).MassProperties; if (body.OverrideDefaultMassDistribution) { massProperties.MassDistribution = body.CustomMassDistribution; // Increase the angular expansion factor to account for the shift in center of mass massProperties.AngularExpansionFactor += math.length(massProperties.MassDistribution.Transform.pos - body.CustomMassDistribution.Transform.pos); } DstEntityManager.AddOrSetComponent(entity, body.MotionType == BodyMotionType.Dynamic ? PhysicsMass.CreateDynamic(massProperties, body.Mass) : PhysicsMass.CreateKinematic(massProperties)); DstEntityManager.AddOrSetComponent(entity, new PhysicsVelocity { Linear = body.InitialLinearVelocity, Angular = body.InitialAngularVelocity }); if (body.MotionType == BodyMotionType.Dynamic) { // TODO make these optional in editor? DstEntityManager.AddOrSetComponent(entity, new PhysicsDamping { Linear = body.LinearDamping, Angular = body.AngularDamping }); if (body.GravityFactor != 1) { DstEntityManager.AddOrSetComponent(entity, new PhysicsGravityFactor { Value = body.GravityFactor }); } } else if (body.MotionType == BodyMotionType.Kinematic) { DstEntityManager.AddOrSetComponent(entity, new PhysicsGravityFactor { Value = 0 }); } } ); }
// // Object creation // private unsafe Entity CreateBody(float3 position, quaternion orientation, BlobAssetReference <Collider> collider, float3 linearVelocity, float3 angularVelocity, float mass, bool isDynamic) { EntityManager entityManager = EntityManager; Entity entity = entityManager.CreateEntity(new ComponentType[] { }); entityManager.AddComponentData(entity, new LocalToWorld { }); entityManager.AddComponentData(entity, new Translation { Value = position }); entityManager.AddComponentData(entity, new Rotation { Value = orientation }); entityManager.AddComponentData(entity, new PhysicsCollider { Value = collider }); List <Unity.Physics.Authoring.DisplayBodyColliders.DrawComponent.DisplayResult> meshes = Unity.Physics.Authoring.DisplayBodyColliders.DrawComponent.BuildDebugDisplayMesh((Collider *)collider.GetUnsafePtr()); CombineInstance[] instances = new CombineInstance[meshes.Count]; for (int i = 0; i < meshes.Count; i++) { instances[i] = new CombineInstance { mesh = meshes[i].Mesh, transform = Matrix4x4.TRS(meshes[i].Position, meshes[i].Orientation, meshes[i].Scale) }; } Mesh mesh = new Mesh(); mesh.CombineMeshes(instances); entityManager.AddSharedComponentData(entity, new RenderMesh { mesh = mesh, material = isDynamic ? dynamicMaterial : staticMaterial }); if (isDynamic) { Collider *colliderPtr = (Collider *)collider.GetUnsafePtr(); entityManager.AddComponentData(entity, PhysicsMass.CreateDynamic(colliderPtr->MassProperties, mass)); float3 angularVelocityLocal = math.mul(math.inverse(colliderPtr->MassProperties.MassDistribution.Transform.rot), angularVelocity); entityManager.AddComponentData(entity, new PhysicsVelocity() { Linear = linearVelocity, Angular = angularVelocityLocal }); entityManager.AddComponentData(entity, new PhysicsDamping() { Linear = 0.01f, Angular = 0.05f }); } return(entity); }
public void Execute() { int index = 0; int maxIndex = DeferredImpulseReader.ForEachCount; DeferredImpulseReader.BeginForEachIndex(index++); while (DeferredImpulseReader.RemainingItemCount == 0 && index < maxIndex) { DeferredImpulseReader.BeginForEachIndex(index++); } while (DeferredImpulseReader.RemainingItemCount > 0) { var impulse = DeferredImpulseReader.Read <DefferedCharacterControllerImpulse>(); while (DeferredImpulseReader.RemainingItemCount == 0 && index < maxIndex) { DeferredImpulseReader.BeginForEachIndex(index++); } PhysicsVelocity pv = PhysicsVelocityData[impulse.Entity]; PhysicsMass pm = PhysicsMassData[impulse.Entity]; Translation t = TranslationData[impulse.Entity]; Rotation r = RotationData[impulse.Entity]; if (pm.InverseMass > 0.0f) { pv.ApplyImpulse(pm, t, r, impulse.Impulse, impulse.Point); PhysicsVelocityData[impulse.Entity] = pv; } } }
protected override void OnUpdate() { Entities.ForEach( (LegacyRigidBody body) => { var entity = GetPrimaryEntity(body.gameObject); // prefer conversions from non-legacy data if they have already been performed if (DstEntityManager.HasComponent <PhysicsVelocity>(entity)) { return; } DstEntityManager.PostProcessTransformComponents( entity, body.transform, body.isKinematic ? BodyMotionType.Kinematic : BodyMotionType.Dynamic ); if (body.gameObject.isStatic) { return; } // Build mass component var massProperties = MassProperties.UnitSphere; if (DstEntityManager.HasComponent <PhysicsCollider>(entity)) { // Build mass component massProperties = DstEntityManager.GetComponentData <PhysicsCollider>(entity).MassProperties; } // n.b. no way to know if CoM was manually adjusted, so all legacy Rigidbody objects use auto CoM DstEntityManager.AddOrSetComponent(entity, !body.isKinematic ? PhysicsMass.CreateDynamic(massProperties, body.mass) : PhysicsMass.CreateKinematic(massProperties)); DstEntityManager.AddOrSetComponent(entity, new PhysicsVelocity()); if (!body.isKinematic) { DstEntityManager.AddOrSetComponent(entity, new PhysicsDamping { Linear = body.drag, Angular = body.angularDrag }); if (!body.useGravity) { DstEntityManager.AddOrSetComponent(entity, new PhysicsGravityFactor { Value = 0f }); } } else { DstEntityManager.AddOrSetComponent(entity, new PhysicsGravityFactor { Value = 0 }); } } ); }
protected override void OnUpdate() { var commandBuffer = commandBufferSystem.CreateCommandBuffer(); float deltaTime = Time.DeltaTime; float3 direction = new float3(1, 0, 1); Entities.WithStructuralChanges(). WithAll <ApplyImpulseTag>(). ForEach((Entity entity, ref PhysicsVelocity velocity, ref PhysicsGravityFactor gravityFactor, in Rotation rot, in PhysicsCollider physicsCollider, in DeadRobotData deadRobotData, in PhysicsMass mass) => { Translation bulletTrans = EntityManager.GetComponentData <Translation>(deadRobotData.bullet); Translation trans = EntityManager.GetComponentData <Translation>(entity); EntityManager.SetComponentData(entity, PhysicsMass.CreateDynamic(new MassProperties() { AngularExpansionFactor = mass.AngularExpansionFactor, MassDistribution = new MassDistribution() { Transform = mass.Transform, InertiaTensor = new float3(1, 1, 1) }, Volume = 1 }, 1)); PhysicsMass newMass = EntityManager.GetComponentData <PhysicsMass>(entity); float3 impulse = math.normalize(bulletTrans.Value - trans.Value) * 10; gravityFactor.Value = 1; PhysicsComponentExtensions.ApplyExplosionForce(ref velocity, newMass, physicsCollider, trans, rot, 100, bulletTrans.Value, 5, 1.0f / 30.0f, new float3(0, 1, 0), 3, ForceMode.Impulse); EntityManager.RemoveComponent <ApplyImpulseTag>(entity); })
public Entity CreateBody(RenderMesh displayMesh, float3 position, quaternion orientation, BlobAssetReference <Unity.Physics.Collider> collider, float3 linearVelocity, float3 angularVelocity, float mass, bool isDynamic) { ComponentType[] componentTypes = new ComponentType[isDynamic ? 9 : 6]; componentTypes[0] = typeof(RenderMesh); componentTypes[1] = typeof(TranslationProxy); componentTypes[2] = typeof(RotationProxy); componentTypes[3] = typeof(PhysicsCollider); componentTypes[4] = typeof(Translation); componentTypes[5] = typeof(Rotation); if (isDynamic) { componentTypes[6] = typeof(PhysicsVelocity); componentTypes[7] = typeof(PhysicsMass); componentTypes[8] = typeof(PhysicsDamping); } EntityManager entityManager = EntityManager; Entity entity = entityManager.CreateEntity(componentTypes); entityManager.SetName(entity, "randomSphere"); entityManager.SetSharedComponentData(entity, displayMesh); entityManager.AddComponentData(entity, new LocalToWorld { }); entityManager.SetComponentData(entity, new Translation { Value = position }); entityManager.SetComponentData(entity, new Rotation { Value = orientation }); entityManager.SetComponentData(entity, new PhysicsCollider { Value = collider }); if (isDynamic) { MassProperties massProperties = collider.Value.MassProperties; entityManager.SetComponentData(entity, PhysicsMass.CreateDynamic( massProperties, mass)); float3 angularVelocityLocal = math.mul( math.inverse(massProperties.MassDistribution.Transform.rot), angularVelocity); entityManager.SetComponentData(entity, new PhysicsVelocity() { Linear = linearVelocity, Angular = angularVelocityLocal }); entityManager.SetComponentData(entity, new PhysicsDamping() { Linear = 0.01f, Angular = 0.05f }); } return(entity); }
public unsafe void Execute <TCtx>(TCtx ctx, InputTriggerPort port) where TCtx : IGraphInstance { var entity = ctx.ReadEntity(Entity); if (entity == Unity.Entities.Entity.Null) { return; } if (!ctx.EntityManager.HasComponent <PhysicsCollider>(entity)) { return; } PhysicsCollider physicsCollider = ctx.EntityManager.GetComponentData <PhysicsCollider>(entity); Collider * colliderPtr = (Collider *)physicsCollider.Value.GetUnsafePtr(); if (!ctx.EntityManager.HasComponent <PhysicsGravityFactor>(entity)) { ctx.EntityManager.AddComponent <PhysicsGravityFactor>(entity); } float gravityFactor = ctx.ReadFloat(GravityFactor); ctx.EntityManager.SetComponentData(entity, new PhysicsGravityFactor() { Value = gravityFactor }); if (!ctx.EntityManager.HasComponent <PhysicsMass>(entity)) { ctx.EntityManager.AddComponent <PhysicsMass>(entity); } float mass = ctx.ReadFloat(Mass); ctx.EntityManager.SetComponentData(entity, PhysicsMass.CreateDynamic(colliderPtr->MassProperties, mass)); if (!ctx.EntityManager.HasComponent <PhysicsVelocity>(entity)) { ctx.EntityManager.AddComponent <PhysicsVelocity>(entity); } ctx.EntityManager.SetComponentData(entity, new PhysicsVelocity { Linear = float3.zero, Angular = float3.zero }); float drag = ctx.ReadFloat(Drag); float angularDrag = ctx.ReadFloat(AngularDrag); if (!ctx.EntityManager.HasComponent <PhysicsDamping>(entity)) { ctx.EntityManager.AddComponent <PhysicsDamping>(entity); } ctx.EntityManager.SetComponentData(entity, new PhysicsDamping { Linear = drag, Angular = angularDrag }); ctx.Trigger(Output); }
// Get the linear velocity of a rigid body at a given point (in world space) public static float3 GetLinearVelocity(this PhysicsVelocity velocityData, PhysicsMass massData, Translation posData, Rotation rotData, float3 point) { var worldFromEntity = new RigidTransform(rotData.Value, posData.Value); var worldFromMotion = math.mul(worldFromEntity, massData.Transform); float3 angularVelocity = math.rotate(worldFromMotion, velocityData.Angular); float3 linearVelocity = math.cross(angularVelocity, (point - worldFromMotion.pos)); return(velocityData.Linear + linearVelocity); }
private static void AddMass(Entity e, PhysicsCollider collider) { PhysicsMass physicsMass = PhysicsMass.CreateDynamic(collider.MassProperties, 1f); physicsMass.InverseInertia = new float3(0f, 0f, 0f); // Freeze rotation m.AddComponentData(e, physicsMass); m.AddComponentData(e, new PhysicsGravityFactor { Value = 0f }); // Disable built-in gravity on all dynamic entities }
public unsafe Unity.Entities.Entity CreateBody(float3 position, quaternion orientation, BlobAssetReference <Unity.Physics.Collider> collider, float3 linearVelocity, float3 angularVelocity, float mass, bool isDynamic) { ComponentType[] componentTypes = new ComponentType[isDynamic ? 7 : 3]; componentTypes[0] = typeof(TranslationProxy); componentTypes[1] = typeof(RotationProxy); componentTypes[2] = typeof(PhysicsCollider); if (isDynamic) { componentTypes[3] = typeof(PhysicsVelocity); componentTypes[4] = typeof(PhysicsMass); componentTypes[5] = typeof(PhysicsDamping); componentTypes[6] = typeof(PhysicsGravityFactor); } Unity.Entities.Entity entity = entityManager.CreateEntity(componentTypes); entityManager.AddComponentData(entity, new Translation { Value = position }); entityManager.AddComponentData(entity, new Rotation { Value = orientation }); entityManager.SetComponentData(entity, new PhysicsCollider { Value = collider }); if (isDynamic) { Unity.Physics.Collider *colliderPtr = (Unity.Physics.Collider *)collider.GetUnsafePtr(); entityManager.SetComponentData(entity, PhysicsMass.CreateDynamic(colliderPtr->MassProperties, mass)); float3 angularVelocityLocal = math.mul(math.inverse(colliderPtr->MassProperties.MassDistribution.Transform.rot), angularVelocity); entityManager.SetComponentData(entity, new PhysicsVelocity() { Linear = linearVelocity, Angular = angularVelocityLocal }); entityManager.SetComponentData(entity, new PhysicsDamping() { Linear = 1.5f, Angular = 1.5f }); entityManager.SetComponentData(entity, new PhysicsGravityFactor { Value = 0.0f }); } return(entity); }
private static void SetupPrefab( NativeArray <Entity> entities, IConfigurable cfg ) { EntityManager em = World.DefaultGameObjectInjectionWorld .EntityManager; ConfigurableComponent component = new ConfigurableComponent(cfg); foreach (Entity entity in entities) { PhysicsMass mass = em.GetComponentData <PhysicsMass>(entity); mass.InverseMass = component.mass; em.SetComponentData(entity, mass); } if (component.hasPropulsion) { em.AddComponent <PropulsionComponent>(entities); foreach (Entity entity in entities) { em.SetComponentData(entity, component.propulsion); } } if (component.hasDefense) { em.AddComponent <DefenseComponent>(entities); foreach (Entity entity in entities) { em.SetComponentData(entity, component.defense); } } if (component.hasEnergy) { em.AddComponent <EnergyComponent>(entities); foreach (Entity entity in entities) { em.SetComponentData(entity, component.energy); } } if (component.hasPower) { em.AddComponent <PowerComponent>(entities); foreach (Entity entity in entities) { em.SetComponentData(entity, component.power); } } }
public void ApplyChange(EntityManager entityManager, Entity entity, float mass = 0) { pm = entityManager.GetComponentData <PhysicsMass>(entity); pc = entityManager.GetComponentData <PhysicsCollider>(entity); if (IsKinematic) { PhysicsMass.CreateKinematic(pc.MassProperties); } else if (IsDynamic) { PhysicsMass.CreateDynamic(pc.MassProperties, mass > 0 ? mass : Mass); } }
// Create a native motion data private static MotionData CreateMotionData( Translation position, Rotation orientation, PhysicsMass massComponent, float linearDamping, float angularDamping, float gravityFactor = 1.0f) { return(new MotionData { WorldFromMotion = new RigidTransform( math.mul(orientation.Value, massComponent.InertiaOrientation), math.rotate(orientation.Value, massComponent.CenterOfMass) + position.Value ), BodyFromMotion = massComponent.Transform, LinearDamping = linearDamping, AngularDamping = angularDamping, GravityFactor = gravityFactor }); }
private static MotionData CreateMotionData( Translation position, Rotation orientation, PhysicsMass physicsMass, PhysicsDamping damping, float gravityFactor) { return(new MotionData { WorldFromMotion = new RigidTransform( math.mul(orientation.Value, physicsMass.InertiaOrientation), math.rotate(orientation.Value, physicsMass.CenterOfMass) + position.Value ), BodyFromMotion = physicsMass.Transform, LinearDamping = damping.Linear, AngularDamping = damping.Angular, GravityFactor = gravityFactor }); }
public Entity CreateBody(float3 position, quaternion orientation, BlobAssetReference <Collider> collider, float3 linearVelocity, float3 angularVelocity, float mass, bool isDynamic) { var entityManager = World.DefaultGameObjectInjectionWorld.EntityManager; Entity entity = entityManager.CreateEntity(new ComponentType[] {}); entityManager.AddComponentData(entity, new LocalToWorld { }); entityManager.AddComponentData(entity, new Translation { Value = position }); entityManager.AddComponentData(entity, new Rotation { Value = orientation }); var colliderComponent = new PhysicsCollider { Value = collider }; entityManager.AddComponentData(entity, colliderComponent); EntityManager.AddSharedComponentData(entity, new PhysicsWorldIndex()); CreateRenderMeshForCollider(entityManager, entity, collider, isDynamic ? DynamicMaterial : StaticMaterial); if (isDynamic) { entityManager.AddComponentData(entity, PhysicsMass.CreateDynamic(colliderComponent.MassProperties, mass)); float3 angularVelocityLocal = math.mul(math.inverse(colliderComponent.MassProperties.MassDistribution.Transform.rot), angularVelocity); entityManager.AddComponentData(entity, new PhysicsVelocity { Linear = linearVelocity, Angular = angularVelocityLocal }); entityManager.AddComponentData(entity, new PhysicsDamping { Linear = 0.01f, Angular = 0.05f }); } return(entity); }
public void Execute <TCtx>(TCtx ctx) where TCtx : IGraphInstance { var entity = ctx.ReadEntity(GameObject); if (entity != Entity.Null) { if (ctx.EntityManager.HasComponent <PhysicsMass>(entity)) { PhysicsMass physicsMass = ctx.EntityManager.GetComponentData <PhysicsMass>(entity); ctx.Write(Value, 1.0f / physicsMass.InverseMass); } else { ctx.Write(Value, 0); } } }
public unsafe void Execute <TCtx>(TCtx ctx, InputTriggerPort port) where TCtx : IGraphInstance { var entity = ctx.ReadEntity(Entity); if (entity == Unity.Entities.Entity.Null) { return; } if (!ctx.EntityManager.HasComponent <PhysicsVelocity>(entity) || !ctx.EntityManager.HasComponent <PhysicsVelocity>(entity)) { return; } PhysicsVelocity physicsVelocity = ctx.EntityManager.GetComponentData <PhysicsVelocity>(entity); PhysicsMass physicsMass = ctx.EntityManager.GetComponentData <PhysicsMass>(entity); physicsVelocity.ApplyLinearImpulse(physicsMass, ctx.ReadFloat3(Value)); ctx.EntityManager.SetComponentData(entity, physicsVelocity); }
protected override void OnUpdate() { float deltaTime = Time.DeltaTime; var pvs = GetComponentDataFromEntity <PhysicsVelocity>(); var pms = GetComponentDataFromEntity <PhysicsMass>(true); Entities .WithReadOnly(pms) .WithAll <Tag, AbilityCommon.Active>() .ForEach((in Owner owner, in AxisInput input, in Setting setting) => { float3 rawDirection = new float3(input.Value.x, 0, input.Value.y); if (rawDirection.Equals(0)) { return; } float3 direction = math.normalize(rawDirection); PhysicsVelocity velocity = pvs[owner.Entity]; PhysicsMass physicsMass = pms[owner.Entity]; velocity.ApplyLinearImpulse(physicsMass, setting.Strength * direction); pvs[owner.Entity] = velocity; }).Schedule();
protected override void OnUpdate() { //get entity array pokemonEntities = PokemonEntitySpawnQuery.ToEntityArray(Allocator.TempJob); for (int i = 0; i < pokemonEntities.Length; i++) { PhysicsCollider pc = EntityManager.GetComponentData <PhysicsCollider>(pokemonEntities[i]); PokemonEntityData ped = EntityManager.GetComponentData <PokemonEntityData>(pokemonEntities[i]); PhysicsMass pm = EntityManager.GetComponentData <PhysicsMass>(pokemonEntities[i]); float radius = calculateSphereRadius(pc.Value.Value.MassProperties.Volume); // Debug.Log("Mass = " + ped.Mass + "InverseMAss = " + (1 / ped.Mass) + " inverseInertia ="+ (1/(0.4f*ped.Mass*(radius*radius)))); EntityManager.SetComponentData <PhysicsMass>(pokemonEntities[i], new PhysicsMass { AngularExpansionFactor = pm.AngularExpansionFactor, Transform = pm.Transform, InverseMass = (1 / ped.Mass), InverseInertia = (1 / (0.4f * ped.Mass * (radius * radius))) }); EntityManager.RemoveComponent(pokemonEntities[i], typeof(PokemonEntitySpawnData)); } pokemonEntities.Dispose(); }
public unsafe void Execute <TCtx>(TCtx ctx, InputTriggerPort port) where TCtx : IGraphInstance { var entity = ctx.ReadEntity(Entity); if (entity == Unity.Entities.Entity.Null) { return; } if (!ctx.EntityManager.HasComponent <PhysicsMass>(entity) || !ctx.EntityManager.HasComponent <PhysicsCollider>(entity)) { return; } PhysicsCollider physicsCollider = ctx.EntityManager.GetComponentData <PhysicsCollider>(entity); float newMass = ctx.ReadFloat(Mass); Collider *colliderPtr = (Collider *)physicsCollider.Value.GetUnsafePtr(); ctx.EntityManager.SetComponentData(entity, PhysicsMass.CreateDynamic(colliderPtr->MassProperties, newMass)); }
public void Execute(ArchetypeChunk chunk, int chunkIndex, int firstEntityIndex) { //Get arrays of objects that we'll be operating on NativeArray <PhysicsVelocity> physVel = chunk.GetNativeArray(physVType); NativeArray <PhysicsMass> physMass = chunk.GetNativeArray(physMassType); NativeArray <InputStruct> inputStructs = chunk.GetNativeArray(inputType); NativeArray <PhysicsControllerStruct> controllers = chunk.GetNativeArray(pControlType); NativeArray <LocalToWorld> toWorlds = chunk.GetNativeArray(toWorldType); NativeArray <Rotation> rotations = chunk.GetNativeArray(rotType); NativeArray <Translation> translations = chunk.GetNativeArray(transType); //Essentially IJobForEach for (int i = 0; i < chunk.Count; i++) { //Get data from arrays PhysicsVelocity rb = physVel[i]; PhysicsMass pMass = physMass[i]; InputStruct inp = inputStructs[i]; PhysicsControllerStruct controllerStruct = controllers[i]; LocalToWorld toWorld = toWorlds[i]; Rotation rot = rotations[i]; Translation trans = translations[i]; //Do work on data Move(ref rb, ref pMass, ref inp, ref controllerStruct, ref toWorld, ref rot, ref trans); //Set data in array to data we changed physVel[i] = rb; physMass[i] = pMass; //inputStructs[i] = inp; controllers[i] = controllerStruct; //toWorlds[i] = toWorld; rotations[i] = rot; translations[i] = trans; } }
protected override JobHandle OnUpdate(JobHandle inputDeps) { if (m_MouseGroup.CalculateEntityCount() == 0) { return(inputDeps); } ComponentDataFromEntity <Translation> Positions = GetComponentDataFromEntity <Translation>(true); ComponentDataFromEntity <Rotation> Rotations = GetComponentDataFromEntity <Rotation>(true); ComponentDataFromEntity <PhysicsVelocity> Velocities = GetComponentDataFromEntity <PhysicsVelocity>(); ComponentDataFromEntity <PhysicsMass> Masses = GetComponentDataFromEntity <PhysicsMass>(true); // If there's a pick job, wait for it to finish if (m_PickSystem.PickJobHandle != null) { JobHandle.CombineDependencies(inputDeps, m_PickSystem.PickJobHandle.Value).Complete(); } // If there's a picked entity, drag it MousePickSystem.SpringData springData = m_PickSystem.SpringDatas[0]; if (springData.Dragging != 0) { Entity entity = m_PickSystem.SpringDatas[0].Entity; if (!EntityManager.HasComponent <PhysicsMass>(entity)) { return(inputDeps); } PhysicsMass massComponent = Masses[entity]; PhysicsVelocity velocityComponent = Velocities[entity]; if (massComponent.InverseMass == 0) { return(inputDeps); } var worldFromBody = new MTransform(Rotations[entity].Value, Positions[entity].Value); // Body to motion transform var bodyFromMotion = new MTransform(Masses[entity].InertiaOrientation, Masses[entity].CenterOfMass); MTransform worldFromMotion = Mul(worldFromBody, bodyFromMotion); // Damp the current velocity const float gain = 0.95f; velocityComponent.Linear *= gain; velocityComponent.Angular *= gain; // Get the body and mouse points in world space float3 pointBodyWs = Mul(worldFromBody, springData.PointOnBody); float3 pointSpringWs = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, springData.MouseDepth)); // Calculate the required change in velocity float3 pointBodyLs = Mul(Inverse(bodyFromMotion), springData.PointOnBody); float3 deltaVelocity; { float3 pointDiff = pointBodyWs - pointSpringWs; float3 relativeVelocityInWorld = velocityComponent.Linear + math.mul(worldFromMotion.Rotation, math.cross(velocityComponent.Angular, pointBodyLs)); const float elasticity = 0.1f; const float damping = 0.5f; deltaVelocity = -pointDiff * (elasticity / Time.fixedDeltaTime) - damping * relativeVelocityInWorld; } // Build effective mass matrix in world space // TODO how are bodies with inf inertia and finite mass represented // TODO the aggressive damping is hiding something wrong in this code if dragging non-uniform shapes float3x3 effectiveMassMatrix; { float3 arm = pointBodyWs - worldFromMotion.Translation; var skew = new float3x3( new float3(0.0f, arm.z, -arm.y), new float3(-arm.z, 0.0f, arm.x), new float3(arm.y, -arm.x, 0.0f) ); // world space inertia = worldFromMotion * inertiaInMotionSpace * motionFromWorld var invInertiaWs = new float3x3( massComponent.InverseInertia.x * worldFromMotion.Rotation.c0, massComponent.InverseInertia.y * worldFromMotion.Rotation.c1, massComponent.InverseInertia.z * worldFromMotion.Rotation.c2 ); invInertiaWs = math.mul(invInertiaWs, math.transpose(worldFromMotion.Rotation)); float3x3 invEffMassMatrix = math.mul(math.mul(skew, invInertiaWs), skew); invEffMassMatrix.c0 = new float3(massComponent.InverseMass, 0.0f, 0.0f) - invEffMassMatrix.c0; invEffMassMatrix.c1 = new float3(0.0f, massComponent.InverseMass, 0.0f) - invEffMassMatrix.c1; invEffMassMatrix.c2 = new float3(0.0f, 0.0f, massComponent.InverseMass) - invEffMassMatrix.c2; effectiveMassMatrix = math.inverse(invEffMassMatrix); } // Calculate impulse to cause the desired change in velocity float3 impulse = math.mul(effectiveMassMatrix, deltaVelocity); // Clip the impulse const float maxAcceleration = 250.0f; float maxImpulse = math.rcp(massComponent.InverseMass) * Time.fixedDeltaTime * maxAcceleration; impulse *= math.min(1.0f, math.sqrt((maxImpulse * maxImpulse) / math.lengthsq(impulse))); // Apply the impulse { velocityComponent.Linear += impulse * massComponent.InverseMass; float3 impulseLs = math.mul(math.transpose(worldFromMotion.Rotation), impulse); float3 angularImpulseLs = math.cross(pointBodyLs, impulseLs); velocityComponent.Angular += angularImpulseLs * massComponent.InverseInertia; } // Write back velocity Velocities[entity] = velocityComponent; } return(inputDeps); }
protected override void OnUpdate() { Entities .WithName("LinearDashpotUpdate") .WithBurst() .ForEach((in LinearDashpot dashpot) => { if (0 == dashpot.strength) { return; } var eA = dashpot.localEntity; var eB = dashpot.parentEntity; var eAIsNull = eA == Entity.Null; if (eAIsNull) { return; } var eBIsNull = eB == Entity.Null; var hasVelocityA = !eAIsNull && HasComponent <PhysicsVelocity>(eA); var hasVelocityB = !eBIsNull && HasComponent <PhysicsVelocity>(eB); if (!hasVelocityA) { return; } Translation positionA = default; Rotation rotationA = new Rotation { Value = quaternion.identity }; PhysicsVelocity velocityA = default; PhysicsMass massA = default; Translation positionB = positionA; Rotation rotationB = rotationA; PhysicsVelocity velocityB = velocityA; PhysicsMass massB = massA; if (HasComponent <Translation>(eA)) { positionA = GetComponent <Translation>(eA); } if (HasComponent <Rotation>(eA)) { rotationA = GetComponent <Rotation>(eA); } if (HasComponent <PhysicsVelocity>(eA)) { velocityA = GetComponent <PhysicsVelocity>(eA); } if (HasComponent <PhysicsMass>(eA)) { massA = GetComponent <PhysicsMass>(eA); } if (HasComponent <LocalToWorld>(eB)) { // parent could be static and not have a Translation or Rotation var worldFromBody = Math.DecomposeRigidBodyTransform(GetComponent <LocalToWorld>(eB).Value); positionB = new Translation { Value = worldFromBody.pos }; rotationB = new Rotation { Value = worldFromBody.rot }; } if (HasComponent <Translation>(eB)) { positionB = GetComponent <Translation>(eB); } if (HasComponent <Rotation>(eB)) { rotationB = GetComponent <Rotation>(eB); } if (HasComponent <PhysicsVelocity>(eB)) { velocityB = GetComponent <PhysicsVelocity>(eB); } if (HasComponent <PhysicsMass>(eB)) { massB = GetComponent <PhysicsMass>(eB); } var posA = math.transform(new RigidTransform(rotationA.Value, positionA.Value), dashpot.localOffset); var posB = math.transform(new RigidTransform(rotationB.Value, positionB.Value), dashpot.parentOffset); var lvA = velocityA.GetLinearVelocity(massA, positionA, rotationA, posA); var lvB = velocityB.GetLinearVelocity(massB, positionB, rotationB, posB); var impulse = dashpot.strength * (posB - posA) + dashpot.damping * (lvB - lvA); impulse = math.clamp(impulse, new float3(-100.0f), new float3(100.0f)); velocityA.ApplyImpulse(massA, positionA, rotationA, impulse, posA); SetComponent(eA, velocityA); if (0 == dashpot.dontApplyImpulseToParent && hasVelocityB) { velocityB.ApplyImpulse(massB, positionB, rotationB, -impulse, posB); SetComponent(eB, velocityB); } }).Schedule();
// 生成されたジョイントエンティティを返す。 public NativeArray <Entity> Convert (EntityManager em, Entity posturePrefab, NameAndEntity[] bonePrefabs) { //var motionClip = this.GetComponent<MotionAuthoring>().MotionClip;// var rbTop = this.GetComponentInChildren <Rigidbody>();// if (rbTop == null) { return(new NativeArray <Entity>()); // } var srcColliders = this.GetComponentsInChildren <UnityEngine.Collider>(); // 名前とボーンエンティティの組を配列化 //var qNameAndBone = motionClip.StreamPaths // .Select( x => System.IO.Path.GetFileName( x ) ) // .Select( ( name, i ) => (name, i: motionClip.IndexMapFbxToMotion[ i ]) ) // .Where( x => x.i != -1 ) // .Select( x => (Name:x.name, Entity:bonePrefabs[ x.i ].Entity) ) // .Append( (Name:rbTop.name, Entity:posturePrefab) ); //var namesAndBones = qNameAndBone.ToArray(); var namesAndBones = bonePrefabs .Append(new NameAndEntity(rbTop.name, posturePrefab)); // クエリ用コライダの生成 // ・マテリアルが "xxx overlap collider" という名前になっているものを抽出 // ・対応するボーンエンティティに専用のコンポーネントデータを付加 var qQueryableCollider = from x in srcColliders where x.sharedMaterial != null where x.sharedMaterial.name.StartsWith("overlap ") join bone in namesAndBones on x.name equals bone.Name select(bone.Entity, c : x) ; foreach (var(ent, c) in qQueryableCollider) { addQuearyableColliderBlobs_(ent, c, 0); } // コライダとそれが付くべき剛体の組を配列化(同じ剛体に複数のコライダもあり) // ・有効でないコライダは除外する var qColliderWithParent = from collider in srcColliders where collider.enabled let parent = collider.gameObject .AncestorsAndSelf() .Where(anc => anc.GetComponent <Rigidbody>() != null) .First() select(collider, parent) ; var collidersWithParent = qColliderWithParent.ToArray(); // 同じ剛体を親とするコライダをグループ化するクエリ var qColliderGroup = from x in collidersWithParent group x.collider by x.parent ; // 剛体を持たない子コライダを合成して、コライダコンポーネントデータを生成するクエリ var qCompounds = from g in qColliderGroup select new PhysicsCollider { Value = createBlobCollider_(srcColliders_: g, parent: g.Key, groupIndex: 0), }; // コライダがついているオブジェクトに相当するボーンのエンティティに、コライダコンポーネントデータを付加 // ・コライダ不要なら、質量プロパティだけ生成してコライダはつけないようにしたい(未実装) var qEntAndComponent = from c in (qColliderGroup, qCompounds).Zip() join b in namesAndBones on c.x.Key.name equals b.Name select(b.Entity, c : c.y) ; foreach (var(ent, c) in qEntAndComponent) { em.AddComponentData(ent, c); } // 剛体がついているオブジェクトに相当するボーンのエンティティに、各種コンポーネントデータを付加 // ・キネマティックは質量ゼロにするが、速度や質量プロパティは付加する。 // ・コライダがない場合は、球の質量プロパティになる。 var qRbAndBone = from x in this.GetComponentsInChildren <Rigidbody>() join b in namesAndBones on x.name equals b.Name select(rb : x, b.Entity) ; foreach (var(rb, ent) in qRbAndBone) { addDynamicComponentData_ByRigidbody_(ent, rb, posturePrefab); } //return new NativeArray<Entity>(0,Allocator.Temp); // ジョイントの生成。両端のオブジェクトに相当するエンティティを特定する。 // ・ジョイントはエンティティとして生成する。 // (コライダと同じエンティティに着けても動作したが、サンプルではこうしている) // (また、ラグドールジョイントはなぜか2つジョイントを返してくるので、同じエンティティには付けられない) var qJoint = from j in this.GetComponentsInChildren <UnityEngine.Joint>() //.Do( x=>Debug.Log(x.name)) join a in namesAndBones on j.name equals a.Name join b in namesAndBones on j.connectedBody.name equals b.Name let jointData = createJointBlob_(j) //select (a, b, j, jointData) select addJointComponentData_(a.Entity, jointData, a.Entity, b.Entity, j.enableCollision) ; return(qJoint.SelectMany().ToNativeArray(Allocator.Temp)); // 物理材質に着けられた名前から、特定のコライダを持つコンポーネントデータを生成する。 void addQuearyableColliderBlobs_ (Entity ent, UnityEngine.Collider srcCollider, int groupIndex) { switch (srcCollider.sharedMaterial.name) { //case "overlap cast":汎用だと1つしかもてない、用途ごとにコンポーネントデータを定義しないといけない //{ // var blob = createBlobCollider_( new[] { srcCollider }, srcCollider.gameObject, groupIndex ); // em.AddComponentData( ent, new GroundHitColliderData { Collider = blob } ); // break; //} case "overlap ground ray": { if (srcCollider is UnityEngine.SphereCollider srcSphere) { em.AddComponentData(ent, new GroundHitRayData { Start = srcSphere.center, Ray = new DirectionAndLength { value = new float4(math.up() * -1, srcSphere.radius) }, // 向きは暫定 Filter = LegacyColliderProducer.GetFilter(srcSphere, groupIndex), }); } break; } case "overlap ground sphere": { if (srcCollider is UnityEngine.SphereCollider srcSphere) { em.AddComponentData(ent, new GroundHitSphereData { Center = srcSphere.center, Distance = srcSphere.radius, Filter = LegacyColliderProducer.GetFilter(srcSphere, groupIndex), }); } break; } } } BlobAssetReference <Collider> compoundColliderBlobsFromEnumerable_ (IEnumerable <CompoundCollider.ColliderBlobInstance> src) { using (var arr = src.ToNativeArray(Allocator.Temp)) return(CompoundCollider.Create(arr)); } BlobAssetReference <Collider> createBlobCollider_ (IEnumerable <UnityEngine.Collider> srcColliders_, GameObject parent, int groupIndex) { return((srcColliders_.Count() > 1 || srcColliders_.First().gameObject != parent) ? queryBlobInstances_(srcColliders_, parent.transform, groupIndex) .To(compoundColliderBlobsFromEnumerable_) : createColliderBlob_(srcColliders_.First(), groupIndex) ); IEnumerable <CompoundCollider.ColliderBlobInstance> queryBlobInstances_ (IEnumerable <UnityEngine.Collider> srcColliders__, Transform tfParent, int groupIndex_) { return (from x in srcColliders__ let tfCollider = x.transform let rtf = new RigidTransform { pos = tfCollider.position - tfParent.position, rot = tfCollider.rotation * Quaternion.Inverse(tfParent.rotation), } select new CompoundCollider.ColliderBlobInstance { Collider = createColliderBlob_(x, groupIndex_), CompoundFromChild = rtf, }); } } BlobAssetReference <Collider> createColliderBlob_(UnityEngine.Collider srcCollider, int groupIndex) { switch (srcCollider) { case UnityEngine.SphereCollider srcSphere: return(srcSphere.ProduceColliderBlob(groupIndex)); case UnityEngine.CapsuleCollider srcCapsule: return(srcCapsule.ProduceColliderBlob(groupIndex)); case UnityEngine.BoxCollider srcBox: return(srcBox.ProduceColliderBlob(groupIndex)); } return(BlobAssetReference <Collider> .Null); } void addDynamicComponentData_ByRigidbody_(Entity ent, Rigidbody rb, Entity postureEnt) { var massProp = em.HasComponent <PhysicsCollider>(ent) ? em.GetComponentData <PhysicsCollider>(ent).MassProperties : MassProperties.UnitSphere; var physicsMass = rb.isKinematic ? PhysicsMass.CreateKinematic(massProp) : PhysicsMass.CreateDynamic(massProp, rb.mass); // XY回転拘束だけ特例で設定する var freez_xy = RigidbodyConstraints.FreezeRotationX | RigidbodyConstraints.FreezeRotationZ; if (rb.constraints == freez_xy) { physicsMass.InverseInertia = new float3(0, 1, 0); } //if( !rb.isKinematic ) em.AddComponentData(ent, physicsMass); // キネマティックの場合は、つけなくても大丈夫みたい(主にジョイントにとって) // が、いちおうつけておく //if( !rb.isKinematic ) em.AddComponentData(ent, new PhysicsVelocity()); // ジョイント付けると、質量ゼロにしても速度が必要みたい(ないと荒ぶる) // もしくは、コライダがあると安定したように見えた if (rb.isKinematic || !rb.useGravity) { em.AddComponentData(ent, new PhysicsGravityFactor { Value = 0.0f }); } // 質量ゼロにしても、なぜか重力の影響を受け続けるのでオフる //if( !rb.isKinematic ) { em.AddComponentData(ent, new Bone.InitializeData { PostureEntity = postureEnt }); em.SetComponentData(ent, new Translation { Value = rb.position }); em.SetComponentData(ent, new Rotation { Value = rb.rotation }); } } BlobAssetReference <JointData>[] createJointBlob_(UnityEngine.Joint srcJoint) { switch (srcJoint) { //case UnityEngine.CharacterJoint srcChJoint when srcChJoint.GetComponent<RagdollJointAuthoring>() != null: //{ // var srcRagdollJoint = srcChJoint.GetComponent<RagdollJointAuthoring>(); // JointData.CreateRagdoll // ( // srcRagdollJoint.positionAinA, // srcRagdollJoint.positionBinB, // srcRagdollJoint.twistAxisInA, // srcRagdollJoint.twistAxisInB, // srcRagdollJoint.perpendicularAxisInA, // srcRagdollJoint.perpendicularAxisInB, // math.radians( srcRagdollJoint.maxConeAngle ), // math.radians( srcRagdollJoint.minPerpendicularAngle ), // math.radians( srcRagdollJoint.maxPerpendicularAngle ), // math.radians( srcRagdollJoint.minTwistAngle ), // math.radians( srcRagdollJoint.maxTwistAngle ), // out var jointData0, // out var jointData1 // ); // return new[] { jointData0, jointData1 }; //} case UnityEngine.CharacterJoint srcChJoint2: { var blob = JointData.CreateBallAndSocket(srcChJoint2.anchor, srcChJoint2.connectedAnchor); return(new[] { blob }); } } return(new BlobAssetReference <JointData>[] {}); } //unsafe Entity createJoint_ unsafe Entity[] addJointComponentData_( Entity jointEntity, BlobAssetReference <JointData>[] jointDataArray, Entity entityA, Entity entityB, bool isEnableCollision = false ) { return((from x in jointDataArray select createJointEntity_(x)).ToArray()); Entity createJointEntity_(BlobAssetReference <JointData> jd) { var ent = em.CreateEntity(typeof(Prefab), typeof(PhysicsJoint)); em.SetComponentData(ent, new PhysicsJoint { //JointData = jd, //EntityA = entityA, //EntityB = entityB, //EnableCollision = ( isEnableCollision ? 1 : 0 ) } ); return(ent); } } } }
Entity CreateBody(float3 position, quaternion orientation, BlobAssetReference <Collider> collider, float3 linearVelocity, float3 angularVelocity, float mass, bool isDynamic) { var entityManager = DefaultWorld.EntityManager; Entity entity = entityManager.CreateEntity(new ComponentType[] { }); entityManager.AddComponentData(entity, new LocalToWorld { }); entityManager.AddComponentData(entity, new Translation { Value = position }); entityManager.AddComponentData(entity, new Rotation { Value = orientation }); var colliderComponent = new PhysicsCollider { Value = collider }; entityManager.AddComponentData(entity, colliderComponent); var mesh = new Mesh(); var instances = new List <CombineInstance>(8); var numVertices = 0; foreach (var displayResult in (IEnumerable)k_DrawComponent_BuildDebugDisplayMesh.Invoke(null, new object[] { collider })) { var instance = new CombineInstance { mesh = k_DisplayResultsMesh.GetValue(displayResult) as Mesh, transform = (float4x4)k_DisplayResultsTransform.GetValue(displayResult) }; instances.Add(instance); numVertices += mesh.vertexCount; } mesh.indexFormat = numVertices > UInt16.MaxValue ? UnityEngine.Rendering.IndexFormat.UInt32 : UnityEngine.Rendering.IndexFormat.UInt16; mesh.CombineMeshes(instances.ToArray()); entityManager.AddSharedComponentData(entity, new RenderMesh { mesh = mesh, material = isDynamic ? dynamicMaterial : staticMaterial }); if (isDynamic) { entityManager.AddComponentData(entity, PhysicsMass.CreateDynamic(colliderComponent.MassProperties, mass)); float3 angularVelocityLocal = math.mul(math.inverse(colliderComponent.MassProperties.MassDistribution.Transform.rot), angularVelocity); entityManager.AddComponentData(entity, new PhysicsVelocity() { Linear = linearVelocity, Angular = angularVelocityLocal }); entityManager.AddComponentData(entity, new PhysicsDamping() { Linear = 0.01f, Angular = 0.05f }); } return(entity); }
// Get the center of mass in world space public static float3 GetCenterOfMass(PhysicsMass massData, Translation posData, Rotation rotData) { return(math.rotate(rotData.Value, massData.CenterOfMass) + posData.Value); }